diff --git a/README.md b/README.md index 6db49409..d6c3bf69 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,20 @@ If you're having issues after updating, and commands such as `forgit::add` or al - **Interactive `git commit --fixup=reword && git rebase -i --autosquash` selector** (`grw`) +- **Interactive `git commit --squash && git rebase -i --autosquash` selector** (`gsq`) + +- **Interactive `git commit --fixup=reword && git rebase -i --autosquash` selector** (`grw`) + +- **Interactive `git worktree list` selector** (`gws`/`gwj`) + + + `gwj` jumps to the worktree using `cd` and can only be used via the alias, no equivalent behavior using forgit as a git subcommand + +- **Interactive `git worktree lock ` selector** (`gwl`) + +- **Interactive `git worktree remove ` selector** (`gwr`) + +- **Interactive `git worktree unlock ` selector** (`gwu`) + # ⌨ Keybindings | Key | Action | @@ -237,6 +251,10 @@ forgit_blame=gbl forgit_fixup=gfu forgit_squash=gsq forgit_reword=grw +forgit_worktree_select=gws/gwj +forgit_worktree_lock=gwl +forgit_worktree_remove=gwr +forgit_worktree_unlock=gwu ``` ## git integration @@ -275,29 +293,33 @@ git cf If you want to customize `git`'s behavior within forgit there is a dedicated variable for each forgit command. These are passed to the according `git` calls. -| Command | Option | -| -------- | --------------------------------------------------------------------------- | -| `ga` | `FORGIT_ADD_GIT_OPTS` | -| `glo` | `FORGIT_LOG_GIT_OPTS` | -| `grl` | `FORGIT_REFLOG_GIT_OPTS` | -| `gd` | `FORGIT_DIFF_GIT_OPTS` | -| `gso` | `FORGIT_SHOW_GIT_OPTS` | -| `grh` | `FORGIT_RESET_HEAD_GIT_OPTS` | -| `gcf` | `FORGIT_CHECKOUT_FILE_GIT_OPTS` | -| `gcb` | `FORGIT_CHECKOUT_BRANCH_GIT_OPTS`, `FORGIT_CHECKOUT_BRANCH_BRANCH_GIT_OPTS` | -| `gbd` | `FORGIT_BRANCH_DELETE_GIT_OPTS` | -| `gct` | `FORGIT_CHECKOUT_TAG_GIT_OPTS` | -| `gco` | `FORGIT_CHECKOUT_COMMIT_GIT_OPTS` | -| `grc` | `FORGIT_REVERT_COMMIT_GIT_OPTS` | -| `gss` | `FORGIT_STASH_SHOW_GIT_OPTS` | -| `gsp` | `FORGIT_STASH_PUSH_GIT_OPTS` | -| `gclean` | `FORGIT_CLEAN_GIT_OPTS` | -| `grb` | `FORGIT_REBASE_GIT_OPTS` | -| `gbl` | `FORGIT_BLAME_GIT_OPTS` | -| `gfu` | `FORGIT_FIXUP_GIT_OPTS` | -| `gsq` | `FORGIT_SQUASH_GIT_OPTS` | -| `grw` | `FORGIT_REWORD_GIT_OPTS` | -| `gcp` | `FORGIT_CHERRY_PICK_GIT_OPTS` | +| Command | Option | +| ----------- | --------------------------------------------------------------------------- | +| `ga` | `FORGIT_ADD_GIT_OPTS` | +| `glo` | `FORGIT_LOG_GIT_OPTS` | +| `grl` | `FORGIT_REFLOG_GIT_OPTS` | +| `gd` | `FORGIT_DIFF_GIT_OPTS` | +| `gso` | `FORGIT_SHOW_GIT_OPTS` | +| `grh` | `FORGIT_RESET_HEAD_GIT_OPTS` | +| `gcf` | `FORGIT_CHECKOUT_FILE_GIT_OPTS` | +| `gcb` | `FORGIT_CHECKOUT_BRANCH_GIT_OPTS`, `FORGIT_CHECKOUT_BRANCH_BRANCH_GIT_OPTS` | +| `gbd` | `FORGIT_BRANCH_DELETE_GIT_OPTS` | +| `gct` | `FORGIT_CHECKOUT_TAG_GIT_OPTS` | +| `gco` | `FORGIT_CHECKOUT_COMMIT_GIT_OPTS` | +| `grc` | `FORGIT_REVERT_COMMIT_GIT_OPTS` | +| `gss` | `FORGIT_STASH_SHOW_GIT_OPTS` | +| `gsp` | `FORGIT_STASH_PUSH_GIT_OPTS` | +| `gclean` | `FORGIT_CLEAN_GIT_OPTS` | +| `grb` | `FORGIT_REBASE_GIT_OPTS` | +| `gbl` | `FORGIT_BLAME_GIT_OPTS` | +| `gfu` | `FORGIT_FIXUP_GIT_OPTS` | +| `gsq` | `FORGIT_SQUASH_GIT_OPTS` | +| `grw` | `FORGIT_REWORD_GIT_OPTS` | +| `gcp` | `FORGIT_CHERRY_PICK_GIT_OPTS` | +| `gws`/`gwj` | `FORGIT_WORKTREE_PREVIEW_GIT_OPTS` | +| `gwl` | `FORGIT_WORKTREE_LOCK_GIT_OPTS`, `FORGIT_WORKTREE_PREVIEW_GIT_OPTS` | +| `gwr` | `FORGIT_WORKTREE_REMOVE_GIT_OPTS`, `FORGIT_WORKTREE_PREVIEW_GIT_OPTS` | +| `gwu` | `FORGIT_WORKTREE_PREVIEW_GIT_OPTS` | ## pagers @@ -332,31 +354,35 @@ export FORGIT_FZF_DEFAULT_OPTS=" Customizing fzf options for each command individually is also supported: -| Command | Option | -|----------|-----------------------------------| -| `ga` | `FORGIT_ADD_FZF_OPTS` | -| `glo` | `FORGIT_LOG_FZF_OPTS` | -| `grl` | `FORGIT_REFLOG_FZF_OPTS` | -| `gi` | `FORGIT_IGNORE_FZF_OPTS` | -| `gat` | `FORGIT_ATTRIBUTES_FZF_OPTS` | -| `gd` | `FORGIT_DIFF_FZF_OPTS` | -| `gso` | `FORGIT_SHOW_FZF_OPTS` | -| `grh` | `FORGIT_RESET_HEAD_FZF_OPTS` | -| `gcf` | `FORGIT_CHECKOUT_FILE_FZF_OPTS` | -| `gcb` | `FORGIT_CHECKOUT_BRANCH_FZF_OPTS` | -| `gbd` | `FORGIT_BRANCH_DELETE_FZF_OPTS` | -| `gct` | `FORGIT_CHECKOUT_TAG_FZF_OPTS` | -| `gco` | `FORGIT_CHECKOUT_COMMIT_FZF_OPTS` | -| `grc` | `FORGIT_REVERT_COMMIT_FZF_OPTS` | -| `gss` | `FORGIT_STASH_FZF_OPTS` | -| `gsp` | `FORGIT_STASH_PUSH_FZF_OPTS` | -| `gclean` | `FORGIT_CLEAN_FZF_OPTS` | -| `grb` | `FORGIT_REBASE_FZF_OPTS` | -| `gbl` | `FORGIT_BLAME_FZF_OPTS` | -| `gfu` | `FORGIT_FIXUP_FZF_OPTS` | -| `gsq` | `FORGIT_SQUASH_FZF_OPTS` | -| `grw` | `FORGIT_REWORD_FZF_OPTS` | -| `gcp` | `FORGIT_CHERRY_PICK_FZF_OPTS` | +| Command | Option | +|-------------|-----------------------------------| +| `ga` | `FORGIT_ADD_FZF_OPTS` | +| `glo` | `FORGIT_LOG_FZF_OPTS` | +| `grl` | `FORGIT_REFLOG_FZF_OPTS` | +| `gi` | `FORGIT_IGNORE_FZF_OPTS` | +| `gat` | `FORGIT_ATTRIBUTES_FZF_OPTS` | +| `gd` | `FORGIT_DIFF_FZF_OPTS` | +| `gso` | `FORGIT_SHOW_FZF_OPTS` | +| `grh` | `FORGIT_RESET_HEAD_FZF_OPTS` | +| `gcf` | `FORGIT_CHECKOUT_FILE_FZF_OPTS` | +| `gcb` | `FORGIT_CHECKOUT_BRANCH_FZF_OPTS` | +| `gbd` | `FORGIT_BRANCH_DELETE_FZF_OPTS` | +| `gct` | `FORGIT_CHECKOUT_TAG_FZF_OPTS` | +| `gco` | `FORGIT_CHECKOUT_COMMIT_FZF_OPTS` | +| `grc` | `FORGIT_REVERT_COMMIT_FZF_OPTS` | +| `gss` | `FORGIT_STASH_FZF_OPTS` | +| `gsp` | `FORGIT_STASH_PUSH_FZF_OPTS` | +| `gclean` | `FORGIT_CLEAN_FZF_OPTS` | +| `grb` | `FORGIT_REBASE_FZF_OPTS` | +| `gbl` | `FORGIT_BLAME_FZF_OPTS` | +| `gfu` | `FORGIT_FIXUP_FZF_OPTS` | +| `gsq` | `FORGIT_SQUASH_FZF_OPTS` | +| `grw` | `FORGIT_REWORD_FZF_OPTS` | +| `gcp` | `FORGIT_CHERRY_PICK_FZF_OPTS` | +| `gws`/`gwj` | `FORGIT_WORKTREE_SELECT_FZF_OPTS` | +| `gwl` | `FORGIT_WORKTREE_LOCK_FZF_OPTS` | +| `gwr` | `FORGIT_WORKTREE_REMOVE_FZF_OPTS` | +| `gwu` | `FORGIT_WORKTREE_UNLOCK_FZF_OPTS` | Complete loading order of fzf options is: diff --git a/bin/git-forgit b/bin/git-forgit index 4aac1fc0..bfe3950f 100755 --- a/bin/git-forgit +++ b/bin/git-forgit @@ -51,6 +51,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_inside_git_dir() { git rev-parse --is-inside-git-dir >/dev/null; } _forgit_inside_work_tree() { git rev-parse --is-inside-work-tree >/dev/null; } # tac is not available on OSX, tail -r is not available on Linux, so we use either of them _forgit_reverse_lines() { tac 2> /dev/null || tail -r; } @@ -64,6 +65,18 @@ _forgit_previous_commit() { fi } +_forgit_all_non_flags() { + while (("$#")); do + case "$1" in + -*) + return 1 + ;; + esac + shift + done + return 0 +} + _forgit_contains_non_flags() { while (("$#")); do case "$1" in @@ -1106,7 +1119,7 @@ _forgit_ignore() { args=() while IFS='' read -r arg; do args+=("$arg") - done < <(_forgit_paths_list "$FORGIT_GI_TEMPLATES" .gitignore | + done < <(_forgit_paths_list "$FORGIT_GI_TEMPLATES" .gitignore | nl -w4 -s' ' | FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $2}') fi @@ -1176,6 +1189,141 @@ _forgit_paths_list() { find "$path" -name "*$ext" -print |sed -e "s#$ext\$##" -e 's#.*/##' -e '/^$/d' | sort -fu } +_forgit_filter_existing_paths() { + while read -r path; do + [[ -d "$path" ]] && echo "$path" + done +} + +_forgit_worktree_preview() { + local sha + # trailing space in grep to avoid matching worktrees with a common path + sha=$(git worktree list | grep "$1 " | awk '{print $2}') + if [[ "$sha" == "(bare)" ]]; then + printf "%b(bare)%b %s\n" '\e[0;33m' '\e[0m' 'No history for git dir' + return + fi + # the trailing '--' ensures that this works for branches that have a name + # that is identical to a file + git log "$sha" "${_forgit_log_preview_options[@]}" -- +} + +_forgit_worktree_select() { + _forgit_inside_work_tree || _forgit_inside_git_dir || return 1 + local worktree_list count tree opts + worktree_list=$(git worktree list | grep -vE "prunable$" | awk '{print $1}' | _forgit_filter_existing_paths) + + count=$(echo "$worktree_list" | wc -l) + [[ $count -eq 1 ]] && return 1 + + opts=" + $FORGIT_FZF_DEFAULT_OPTS + +s +m --tiebreak=index + --preview=\"$FORGIT worktree_preview {1}\" + $FORGIT_WORKTREE_SELECT_FZF_OPTS + " + + tree=$(echo "$worktree_list" | FZF_DEFAULT_OPTS="$opts" fzf) + [[ -z "$tree" ]] && return 1 + echo "$tree" +} + +_forgit_worktree_lock_max_args() { + local usage + usage=$(git worktree lock --help 2>/dev/null | grep -E 'usage: git worktree lock' | head -n1) + usage=${usage#*:} + rest=$(echo "$usage" | awk '{for(i=4;i<=NF;++i)printf "%s ",$i; print ""}') + # shellcheck disable=SC2206 + local args=($rest) + echo "${#args[@]}" +} + +_forgit_git_worktree_lock() { + _forgit_worktree_lock_git_opts=() + _forgit_parse_array _forgit_worktree_lock_git_opts "$FORGIT_WORKTREE_LOCK_GIT_OPTS" + git worktree lock "${_forgit_worktree_lock_git_opts[@]}" "$@" +} + +_forgit_worktree_lock() { + _forgit_inside_work_tree || _forgit_inside_git_dir || return 1 + + local tree opts max_args + max_args=$(_forgit_worktree_lock_max_args) + + if [[ $# -ge "$max_args" ]] || { [[ $# -ne 0 ]] && _forgit_all_non_flags "$@"; }; then + git worktree lock "$@" + return $? + fi + + opts=" + $FORGIT_FZF_DEFAULT_OPTS + +s +m --tiebreak=index + --preview=\"$FORGIT worktree_preview {1}\" + $FORGIT_WORKTREE_LOCK_FZF_OPTS + " + + tree=$(git worktree list | grep -vE "\(bare\)|locked" | awk '{print $1}' | FZF_DEFAULT_OPTS="$opts" fzf) + [[ -z "$tree" ]] && return 1 + _forgit_git_worktree_lock "$tree" "$@" +} + +_forgit_git_worktree_remove() { + _forgit_worktree_remove_git_opts=() + _forgit_parse_array _forgit_worktree_remove_git_opts "$FORGIT_WORKTREE_REMOVE_GIT_OPTS" + git worktree remove "${_forgit_worktree_remove_git_opts[@]}" "$@" +} + +_forgit_worktree_remove() { + _forgit_inside_work_tree || _forgit_inside_git_dir || return 1 + local worktree_list tree opts + + if [[ $# -ne 0 ]] && _forgit_contains_non_flags "$@"; then + git worktree remove "$@" + return $? + fi + + worktree_list=$(git worktree list | grep -v "(bare)") + + count=$(echo "$worktree_list" | wc -l) + [[ $count -eq 1 ]] && return 1 + + opts=" + $FORGIT_FZF_DEFAULT_OPTS + +s +m --tiebreak=index + --preview=\"$FORGIT worktree_preview {1}\" + $FORGIT_WORKTREE_REMOVE_FZF_OPTS + " + + tree=$(echo "$worktree_list" | awk '{print $1}' | FZF_DEFAULT_OPTS="$opts" fzf) + [[ -z "$tree" ]] && return 1 + _forgit_git_worktree_remove "$tree" "$@" +} + +_forgit_worktree_unlock() { + _forgit_inside_work_tree || _forgit_inside_git_dir || return 1 + if [[ $# -ne 0 ]]; then + git worktree unlock "$@" + worktree_unlock_status=$? + return $worktree_unlock_status + fi + local worktree_list tree opts + + worktree_list=$(git worktree list | grep -v "(bare)" | grep -E "locked$") + count=$(echo "$worktree_list" | wc -l) + [[ $count -eq 0 ]] && return 1 + + opts=" + $FORGIT_FZF_DEFAULT_OPTS + +s +m --tiebreak=index + --preview=\"$FORGIT worktree_preview {1}\" + $FORGIT_WORKTREE_UNLOCK_FZF_OPTS + " + + tree=$(echo "$worktree_list" | awk '{print $1}' | FZF_DEFAULT_OPTS="$opts" fzf) + [[ -z "$tree" ]] && return 1 + git worktree unlock "$tree" +} + public_commands=( "add" "attributes" @@ -1201,12 +1349,17 @@ public_commands=( "show" "stash_show" "stash_push" + "worktree_select" + "worktree_lock" + "worktree_remove" + "worktree_unlock" ) private_commands=( "add_preview" "blame_preview" "branch_preview" + "worktree_preview" "checkout_commit_preview" "checkout_file_preview" "cherry_pick_from_branch_preview" diff --git a/completions/_git-forgit b/completions/_git-forgit index 434c1611..9a741181 100644 --- a/completions/_git-forgit +++ b/completions/_git-forgit @@ -18,6 +18,11 @@ _git-stash-show() { _alternative "files:filename:($(git stash list | sed -n -e 's/:.*//p'))" } +_git-worktrees() { + # --porcelain usually paired with -z but not needed since we use awk + _alternative "worktrees:worktree:($(git worktree list --porcelain | awk '/worktree/ {print $2}'))" +} + # The completions for git already define a _git-diff completion function, but # it provides the wrong results when called from _git-forgit because it heavily # depends on the context it's been called from (usage of $curcontext and @@ -79,6 +84,10 @@ _git-forgit() { 'squash:git squash' 'stash_show:git stash viewer' 'stash_push:git stash push selector' + 'worktree_select:git worktree selector' + 'worktree_lock:git worktree lock selector' + 'worktree_remove:git worktree remove selector' + 'worktree_unlock:git worktree unlock selector' ) _describe -t commands 'git forgit' subcommands ;; @@ -102,6 +111,10 @@ _git-forgit() { squash) __git_branch_names ;; stash_show) _git-stash-show ;; show) _git-show ;; + worktree_select) _git-worktrees ;; + worktree_lock) _git-worktrees ;; + worktree_remove) _git-worktrees ;; + worktree_unlock) _git-worktrees ;; esac } @@ -130,6 +143,10 @@ compdef __git_branch_names forgit::reword compdef __git_branch_names forgit::squash compdef _git-stash-show forgit::stash::show compdef _git-show forgit::show +compdef _git-worktrees forgit::worktree::select +compdef _git-worktrees forgit::worktree::lock +compdef _git-worktrees forgit::worktree::remove +compdef _git-worktrees forgit::worktree::unlock # this is the case of calling the command and pressing tab # the very first time of a shell session, we have to manually diff --git a/completions/git-forgit.bash b/completions/git-forgit.bash index 0d186006..fc4f0e55 100755 --- a/completions/git-forgit.bash +++ b/completions/git-forgit.bash @@ -35,6 +35,12 @@ _git_stash_show() __gitcomp_nl "$(__git stash list | sed -n -e 's/:.*//p')" } +_git_worktrees() +{ + # --porcelain usually paired with -z but not needed since we use awk + __gitcomp_nl "$(git worktree list --porcelain | awk '/worktree/ {print $2}')" +} + # Completion for git-forgit # This includes git aliases, e.g. "alias.cb=forgit checkout_branch" will # correctly complete available branches on "git cb". @@ -80,6 +86,10 @@ _git_forgit() squash stash_show stash_push + worktree_select + worktree_lock + worktree_remove + worktree_unlock " case ${cword} in @@ -108,6 +118,10 @@ _git_forgit() show) _git_show ;; squash) _git_branch ;; stash_show) _git_stash_show ;; + worktree_select) _git_worktrees ;; + worktree_lock) _git_worktrees ;; + worktree_remove) _git_worktrees ;; + worktree_unlock) _git_worktrees ;; esac ;; *) @@ -145,6 +159,10 @@ then __git_complete forgit::show _git_show __git_complete forgit::squash _git_branch __git_complete forgit::stash::show _git_stash_show + __git_complete forgit::worktree::select _git_worktrees + __git_complete forgit::worktree::lock _git_worktrees + __git_complete forgit::worktree::remove _git_worktrees + __git_complete forgit::worktree::unlock _git_worktrees # Completion for forgit plugin shell aliases if [[ -z "$FORGIT_NO_ALIASES" ]]; then @@ -167,5 +185,9 @@ then __git_complete "${forgit_show}" _git_show __git_complete "${forgit_squash}" _git_branch __git_complete "${forgit_stash_show}" _git_stash_show + __git_complete "${forgit_worktree_select}" _git_worktrees + __git_complete "${forgit_worktree_lock}" _git_worktrees + __git_complete "${forgit_worktree_remove}" _git_worktrees + __git_complete "${forgit_worktree_unlock}" _git_worktrees fi fi diff --git a/completions/git-forgit.fish b/completions/git-forgit.fish index 7876e888..87106ac1 100644 --- a/completions/git-forgit.fish +++ b/completions/git-forgit.fish @@ -8,7 +8,8 @@ function __fish_forgit_needs_subcommand for subcmd in add blame branch_delete checkout_branch checkout_commit checkout_file checkout_tag \ cherry_pick cherry_pick_from_branch clean diff fixup ignore log reflog rebase reset_head \ - revert_commit reword squash stash_show stash_push + revert_commit reword squash stash_show stash_push worktree_select worktree_lock \ + worktree_remove worktree_unlock if contains -- $subcmd (commandline -opc) return 1 end @@ -45,6 +46,10 @@ complete -c git-forgit -n __fish_forgit_needs_subcommand -a show -d 'git show vi complete -c git-forgit -n __fish_forgit_needs_subcommand -a squash -d 'git squash' complete -c git-forgit -n __fish_forgit_needs_subcommand -a stash_show -d 'git stash viewer' complete -c git-forgit -n __fish_forgit_needs_subcommand -a stash_push -d 'git stash push selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a worktree_select -d 'git worktree selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a worktree_lock -d 'git worktree lock selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a worktree_remove -d 'git worktree remove selector' +complete -c git-forgit -n __fish_forgit_needs_subcommand -a worktree_unlock -d 'git worktree unlock selector' complete -c git-forgit -n '__fish_seen_subcommand_from add' -a "(complete -C 'git add ')" complete -c git-forgit -n '__fish_seen_subcommand_from branch_delete' -a "(__fish_git_local_branches)" @@ -66,3 +71,7 @@ complete -c git-forgit -n '__fish_seen_subcommand_from show' -a "(complete -C 'g complete -c git-forgit -n '__fish_seen_subcommand_from squash' -a "(__fish_git_local_branches)" complete -c git-forgit -n '__fish_seen_subcommand_from stash_show' -a "(__fish_git_complete_stashes)" complete -c git-forgit -n '__fish_seen_subcommand_from stash_push' -a "(__fish_git_files modified deleted modified-staged-deleted)" +complete -c git-forgit -n '__fish_seen_subcommand_from worktree_select' -a "(__fish_git_complete_worktrees)" +complete -c git-forgit -n '__fish_seen_subcommand_from worktree_lock' -a "(complete -C 'git worktree lock ')" +complete -c git-forgit -n '__fish_seen_subcommand_from worktree_remove' -a "(complete -C 'git worktree remove ')" +complete -c git-forgit -n '__fish_seen_subcommand_from worktree_unlock' -a "(complete -C 'git worktree unlock ')" diff --git a/conf.d/forgit.plugin.fish b/conf.d/forgit.plugin.fish index 58bb18af..9fcde26d 100644 --- a/conf.d/forgit.plugin.fish +++ b/conf.d/forgit.plugin.fish @@ -55,4 +55,9 @@ if test -z "$FORGIT_NO_ALIASES" abbr -a -- (string collect $forgit_revert_commit; or string collect "grc") git-forgit revert_commit abbr -a -- (string collect $forgit_blame; or string collect "gbl") git-forgit blame abbr -a -- (string collect $forgit_checkout_tag; or string collect "gct") git-forgit checkout_tag + abbr -a -- (string collect $forgit_worktree_select; or string collect "gwj") git-forgit worktree_select + abbr -a -- (string collect $forgit_worktree_jump; or string collect "gwj") 'set tree (git-forgit worktree_select); test -n "$tree"; and cd "$tree"' + abbr -a -- (string collect $forgit_worktree_lock; or string collect "gwl") git-forgit worktree_lock + abbr -a -- (string collect $forgit_worktree_remove; or string collect "gwr") git-forgit worktree_remove + abbr -a -- (string collect $forgit_worktree_unlock; or string collect "gwu") git-forgit worktree_unlock end diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 54a8f8bd..03473f47 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -156,6 +156,26 @@ forgit::attributes() { "$FORGIT" attributes "$@" } +forgit::worktree::select() { + "$FORGIT" worktree_select "$@" +} + +forgit::worktree::jump() { + cd "$(forgit::worktree::select "$@")" || exit +} + +forgit::worktree::lock() { + "$FORGIT" worktree_lock "$@" +} + +forgit::worktree::remove() { + "$FORGIT" worktree_remove "$@" +} + +forgit::worktree::unlock() { + "$FORGIT" worktree_unlock "$@" +} + # register aliases # shellcheck disable=SC2139 if [[ -z "$FORGIT_NO_ALIASES" ]]; then @@ -183,6 +203,11 @@ if [[ -z "$FORGIT_NO_ALIASES" ]]; then builtin export forgit_squash="${forgit_squash:-gsq}" builtin export forgit_reword="${forgit_reword:-grw}" builtin export forgit_blame="${forgit_blame:-gbl}" + builtin export forgit_worktree_select="${forgit_worktree_select:-gws}" + builtin export forgit_worktree_jump="${forgit_worktree_jump:-gwj}" + builtin export forgit_worktree_lock="${forgit_worktree_lock:-gwl}" + builtin export forgit_worktree_remove="${forgit_worktree_remove:-gwr}" + builtin export forgit_worktree_unlock="${forgit_worktree_unlock:-gwu}" builtin alias "${forgit_add}"='forgit::add' builtin alias "${forgit_reset_head}"='forgit::reset::head' @@ -207,5 +232,10 @@ if [[ -z "$FORGIT_NO_ALIASES" ]]; then builtin alias "${forgit_squash}"='forgit::squash' builtin alias "${forgit_reword}"='forgit::reword' builtin alias "${forgit_blame}"='forgit::blame' + builtin alias "${forgit_worktree_select}"='forgit::worktree::select' + builtin alias "${forgit_worktree_jump}"='forgit::worktree::jump' + builtin alias "${forgit_worktree_lock}"='forgit::worktree::lock' + builtin alias "${forgit_worktree_remove}"='forgit::worktree::remove' + builtin alias "${forgit_worktree_unlock}"='forgit::worktree::unlock' fi