diff --git a/bin/git-forgit b/bin/git-forgit index 1b252c4..856d8ea 100755 --- a/bin/git-forgit +++ b/bin/git-forgit @@ -31,6 +31,7 @@ $FORGIT_FZF_DEFAULT_OPTS _forgit_warn() { printf "%b[Warn]%b %s\n" '\e[0;33m' '\e[0m' "$@" >&2; } _forgit_info() { printf "%b[Info]%b %s\n" '\e[0;32m' '\e[0m' "$@" >&2; } +_forgit_print_dim() { printf "\e[90m%s\e[0m\n" "$*"; } _forgit_inside_work_tree() { git rev-parse --is-inside-work-tree >/dev/null 2>&1; } _forgit_inside_git_dir() { git rev-parse --is-inside-git-dir >/dev/null 2>&1; } _forgit_inside_git_repo() { _forgit_inside_work_tree || _forgit_inside_git_dir; } @@ -166,9 +167,9 @@ _forgit_branch_list() { local current current=$(git branch --show-current) if [[ -n "$current" ]]; then - printf '\e[90m%s\e[0m\n' "* $current" + _forgit_print_dim "* $current" else - printf '\e[90m%s\e[0m\n' "* (HEAD detached at $(git rev-parse --short HEAD))" + _forgit_print_dim "* (HEAD detached at $(git rev-parse --short HEAD))" fi git branch --color=always "$@" | grep -v '^\*' | grep -v ' -> ' } @@ -1381,18 +1382,26 @@ _forgit_worktree_delete() { local opts worktrees [[ $# -ne 0 ]] && { _forgit_git_worktree_delete "$@"; return $?; } + local candidates + candidates=$(_forgit_worktree_list_deletable) + if [[ -z "$candidates" ]]; then + echo "Nothing to delete." + return 1 + fi + opts=" $FORGIT_FZF_DEFAULT_OPTS +s --multi --tiebreak=index --preview=\"$FORGIT worktree_preview {}\" --bind=\"ctrl-y:execute-silent($FORGIT worktree_yank_path {})\" + --bind=\"alt-l:execute-silent($FORGIT worktree_toggle_lock {})+reload($FORGIT worktree_list_deletable)\" $FORGIT_WORKTREE_DELETE_FZF_OPTS " worktrees=() while IFS='' read -r line; do [[ -n "$line" ]] && worktrees+=("$(echo "$line" | _forgit_extract_worktree_path)") - done < <(_forgit_worktree_list_deletable | FZF_DEFAULT_OPTS="$opts" fzf) + done < <(echo "$candidates" | FZF_DEFAULT_OPTS="$opts" fzf) [[ ${#worktrees[@]} -eq 0 ]] && return 1 @@ -1511,6 +1520,7 @@ PRIVATE_COMMANDS=( "worktree_yank_path" "worktree_toggle_lock" "worktree_list" + "worktree_list_deletable" ) # Check if the script is being sourced. This is necessary for unit tests where diff --git a/completions/_git-forgit b/completions/_git-forgit index 9a1d9a7..65e44c6 100644 --- a/completions/_git-forgit +++ b/completions/_git-forgit @@ -19,7 +19,12 @@ _git-stash-show() { } _git-worktrees() { - _alternative "worktrees:worktree:($(git worktree list --porcelain 2>/dev/null | grep '^worktree ' | cut -d' ' -f2-))" + local -a wt_list + local field + while IFS= read -r -d '' field; do + [[ "$field" == worktree\ * ]] && wt_list+=("${field#worktree }") + done < <(git worktree list --porcelain -z 2>/dev/null) + _alternative "worktrees:worktree:(${(@q)wt_list})" } # The completions for git already define a _git-diff completion function, but @@ -108,7 +113,7 @@ _git-forgit() { squash) _git-log ;; stash_show) _git-stash-show ;; show) _git-show ;; - worktree) ;; + worktree) _git-worktree ;; worktree_delete) _git-worktrees ;; esac } @@ -139,6 +144,7 @@ compdef _git-log forgit::reword compdef _git-log forgit::squash compdef _git-stash-show forgit::stash::show compdef _git-show forgit::show +compdef _git-worktree forgit::worktree compdef _git-worktrees forgit::worktree::delete # this is the case of calling the command and pressing tab diff --git a/completions/git-forgit.bash b/completions/git-forgit.bash index 050783a..af9a5d8 100755 --- a/completions/git-forgit.bash +++ b/completions/git-forgit.bash @@ -37,7 +37,11 @@ _git_stash_show() _git_worktrees() { - __gitcomp_nl "$(__git worktree list --porcelain 2>/dev/null | grep '^worktree ' | cut -d' ' -f2-)" + local wt_list="" field + while IFS= read -r -d '' field; do + [[ "$field" == worktree\ * ]] && wt_list+="${field#worktree }"$'\n' + done < <(__git worktree list --porcelain -z 2>/dev/null) + __gitcomp_nl "$wt_list" } # Completion for git-forgit @@ -115,6 +119,7 @@ _git_forgit() show) _git_show ;; squash) _git_log ;; stash_show) _git_stash_show ;; + worktree) _git_worktree ;; worktree_delete) _git_worktrees ;; esac ;; @@ -154,6 +159,7 @@ then __git_complete forgit::show _git_show __git_complete forgit::squash _git_log __git_complete forgit::stash::show _git_stash_show + __git_complete forgit::worktree _git_worktree __git_complete forgit::worktree::delete _git_worktrees # Completion for forgit plugin shell aliases @@ -178,6 +184,7 @@ then __git_complete "${forgit_show}" _git_show __git_complete "${forgit_squash}" _git_log __git_complete "${forgit_stash_show}" _git_stash_show + __git_complete "${forgit_worktree}" _git_worktree __git_complete "${forgit_worktree_delete}" _git_worktrees fi fi diff --git a/tests/empty-state.test.sh b/tests/empty-state.test.sh index 9d626fa..d13fff8 100644 --- a/tests/empty-state.test.sh +++ b/tests/empty-state.test.sh @@ -31,3 +31,10 @@ function test_checkout_tag_shows_message_when_no_tags() { assert_same "Nothing to checkout: there are no tags." "$output" } + +function test_worktree_delete_shows_message_when_no_deletable_worktrees() { + output=$(_forgit_worktree_delete 2>&1) + assert_general_error + + assert_same "Nothing to delete." "$output" +}