Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
- **Most used zsh shortcuts**: `md`, `rd`, `mkcd`, `take`, `~` and `..` work exactly like zsh, while you can use `cd ...`, `cd ....` and `cd .....` for the other upwards navigation commands.
- **`all`**: selects all files and subdirectories at its location as targets for `rd`, `rm`, `cp` and `mv`.
- **Better autocompletion** with *Tab* key cycling through all options instead of just displaying them.
- **FZF shell bindings:** if *fzf* is installed, `sloth-bash` enables the standard Bash integration, including fuzzy history search on `Ctrl+R`.
- **Basic command colors:** enables colored output for `ls`, `dir`, `vdir` and `grep`, plus familiar aliases like `ll`, `la` and `l`.
- **Case-insensitive command parsing:**, `ls`, `Ls`, `lS` or `LS`, your command will always work.
- **Distrobox passthrough:** enter your distrobox shell with `distroboxname` and pass commands to your distroboxes running `distroboxname command` (and any additional arguments if needed after). As distroboxes follow the user's *`~/.bashrc`* file, sloth-bash also works from within them!

## Recommended usage
- Install *[Starship](https://starship.rs)* for the complete experience.
- Install *[fzf](https://github.com/junegunn/fzf)* if you want the full fuzzy shell bindings.
- Copy **sloth-bash** to **`~/.sloth-bash`**
- Copy **alias-list** to **`~/.alias-list`**
- Copy **starship.toml** to **`~/.config/starship.toml`** (not required if you don't wanna use *Starship*)
- Add **`source ~/.sloth-bash`** to the end of your `~/.bashrc` file
- Add **`source ~/.sloth-bash`** to the end of your `~/.bashrc` file
150 changes: 126 additions & 24 deletions sloth-bash
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
source ~/.alias-list
[[ -f ~/.alias-list ]] && source ~/.alias-list

# bash file manager
shopt -s autocd
function cd {
Expand Down Expand Up @@ -43,6 +44,15 @@ detach() {
fi
nohup $resolved "${@:2}" > /dev/null 2>&1 &
}

_sloth_run_quick_lookup() {
if command -v timeout >/dev/null 2>&1; then
timeout 0.5s "$@" 2>/dev/null
else
"$@" 2>/dev/null
fi
}

# python3 wrapper and flatpak matcher
command_not_found_handle() {
local cmd_lower="${1,,}"
Expand Down Expand Up @@ -74,26 +84,35 @@ command_not_found_handle() {
fi
shift
local args=("$@")
if [[ -n "${FLATPAK_ALIASES[$cmd]}" ]]; then
if command -v flatpak >/dev/null 2>&1 && [[ -n "${FLATPAK_ALIASES[$cmd]}" ]]; then
if flatpak info "${FLATPAK_ALIASES[$cmd]}" > /dev/null 2>&1; then
flatpak run "${FLATPAK_ALIASES[$cmd]}" "${args[@]}"
return $?
fi
fi
if [[ "${cmd,,}" != "kde" && "${cmd,,}" != "gnome" ]]; then
if command -v flatpak >/dev/null 2>&1 && [[ "${cmd,,}" != "kde" && "${cmd,,}" != "gnome" ]]; then
local match
match=$(flatpak list --app --columns=application 2>/dev/null \
match=$(_sloth_run_quick_lookup flatpak list --app --columns=application \
| grep -v -i "Platform" \
| grep -iF -m 1 "$cmd")
if [[ -n "$match" ]]; then
match=$(printf '%s\n' "$match" | head -n 1)
fi
if [[ -z "$match" ]]; then
match=$(_sloth_run_quick_lookup flatpak list --app --columns=application \
| grep -v -i "Platform" \
| grep -iE "(^|\.)${cmd}(\.|$)" \
| head -n 1)
fi
if [[ -n "$match" ]]; then
flatpak run "$match" "${args[@]}"
return $?
fi
fi
if command -v distrobox &>/dev/null; then
local distroBoxes=$(distrobox list 2>/dev/null | awk 'NR>1 {print $3}')
if echo "$distroBoxes" | grep -q "^${cmd}$"; then
local distroBoxes
distroBoxes=$(_sloth_run_quick_lookup distrobox list | awk 'NR>1 {print $3}')
if printf '%s\n' "$distroBoxes" | grep -Fxq "$cmd"; then
if [[ -n "${args[0]}" ]]; then
distrobox enter "$cmd" -- "${args[@]}"
else
Expand Down Expand Up @@ -161,6 +180,66 @@ _run_with_all() {
command "$cmd" "${expanded[@]}"
fi
}

_sloth_has_option_arg() {
local arg
for arg in "$@"; do
if [[ "$arg" == -- ]]; then
return 1
fi
if [[ "$arg" == -* ]]; then
return 0
fi
done
return 1
}

_sloth_total_size_bytes() {
local total
total=$(du -sb "$@" 2>/dev/null | awk 'END {print $1}')
if [[ "$total" =~ ^[0-9]+$ ]]; then
printf '%s\n' "$total"
return 0
fi

total=$(du -sk "$@" 2>/dev/null | awk '{sum += $1} END {print sum * 1024}')
if [[ "$total" =~ ^[0-9]+$ ]]; then
printf '%s\n' "$total"
return 0
fi

return 1
}

_sloth_fzf_history_search() {
command -v fzf >/dev/null 2>&1 || return 1

local selected
selected=$(fc -lnr 1 | awk 'NF && !seen[$0]++' | fzf --height 40% --layout=reverse --border --prompt='history> ' --query "$READLINE_LINE") || return 0

READLINE_LINE="$selected"
READLINE_POINT=${#READLINE_LINE}
}

_sloth_enable_basic_colors() {
if command -v dircolors >/dev/null 2>&1; then
if [[ -r ~/.dircolors ]]; then
eval "$(dircolors -b ~/.dircolors)"
else
eval "$(dircolors -b)"
fi
alias ls='ls --color=auto'
alias dir='dir --color=auto'
alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
LS_COLORS+=':ow=01;33'
fi

alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'
}

# cp and mv replacers
cp() {
for a in "$@"; do
Expand All @@ -172,13 +251,21 @@ cp() {
command cp "$@"
return $?
fi
if _sloth_has_option_arg "$@"; then
command cp "$@"
return $?
fi
local sources=("${@:1:$#-1}")
local total_size=$(du -cb "${sources[@]}" 2>/dev/null | tail -n 1 | awk '{print $1}')
local total_size
total_size=$(_sloth_total_size_bytes "${sources[@]}") || {
command cp "$@"
return $?
}
local threshold=$((100 * 1024 * 1024))
if [ "$total_size" -gt "$threshold" ]; then
command rsync -ah --info=progress2 "$@"
if (( total_size > threshold )); then
command rsync -ah --no-owner --no-group --info=progress2 "$@"
else
command rsync -ah "$@"
command rsync -ah --no-owner --no-group "$@"
fi
}
mv() {
Expand All @@ -191,6 +278,10 @@ mv() {
command mv "$@"
return $?
fi
if _sloth_has_option_arg "$@"; then
command mv "$@"
return $?
fi
local dest="${@: -1}"
local sources=("${@:1:$#-1}")
local source_dir=$(dirname "${sources[0]}")
Expand All @@ -199,12 +290,16 @@ mv() {
command mv "$@"
return $?
fi
local total_size=$(du -cb "${sources[@]}" 2>/dev/null | tail -n 1 | awk '{print $1}')
local total_size
total_size=$(_sloth_total_size_bytes "${sources[@]}") || {
command mv "$@"
return $?
}
local threshold=$((100 * 1024 * 1024))
if [ "$total_size" -gt "$threshold" ]; then
command rsync -ah --info=progress2 --remove-source-files "$@"
if (( total_size > threshold )); then
command rsync -ah --no-owner --no-group --info=progress2 --remove-source-files "$@"
else
command rsync -ah --remove-source-files "$@"
command rsync -ah --no-owner --no-group --remove-source-files "$@"
fi
}
rm() {
Expand Down Expand Up @@ -283,14 +378,21 @@ take() {
mkcd "$arg"
fi
}
# rolling tab
bind 'set show-all-if-ambiguous on'
bind 'TAB:menu-complete'
# starship
if which starship &> /dev/null; then
eval "$(starship init bash)"
fi
# zellij
if which zellij &> /dev/null; then
eval "$(zellij setup --generate-auto-start bash)"
# interactive shell extras
if [[ $- == *i* ]]; then
_sloth_enable_basic_colors
# rolling tab
bind 'set show-all-if-ambiguous on'
bind 'TAB:menu-complete'
if command -v fzf >/dev/null 2>&1; then
eval "$(fzf --bash)"
fi
# starship
if command -v starship >/dev/null 2>&1; then
eval "$(starship init bash)"
fi
# zellij
if command -v zellij >/dev/null 2>&1; then
eval "$(zellij setup --generate-auto-start bash)"
fi
fi
2 changes: 1 addition & 1 deletion starship.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
show_always = true

[sudo]
disabled = false
disabled = false
Loading