diff --git a/worktree/_worktree b/worktree/_worktree index 759494d..0d4e276 100644 --- a/worktree/_worktree +++ b/worktree/_worktree @@ -68,12 +68,12 @@ _worktree() { _arguments '1:: :__worktree_all_branches' ;; (find) - _arguments \ + _arguments -s -S \ '(-i --ignore-case)'{-i,--ignore-case}'[Match the glob case insensitively]' \ '1:: :_files' ;; (rm|remove) - _arguments \ + _arguments -s -S \ '(-f --force)'{-f,--force}'[Force removal even with modified or untracked files]' \ '(-d --delete-branch)'{-d,--delete-branch}'[Also delete the branch]' \ '*: :__worktree_active_branches' diff --git a/worktree/worktree.plugin.zsh b/worktree/worktree.plugin.zsh index d6dea46..8fe4801 100644 --- a/worktree/worktree.plugin.zsh +++ b/worktree/worktree.plugin.zsh @@ -54,6 +54,27 @@ __worktree_labels() { done } +# Sort arguments into the caller's flags and operands arrays. Combined single +# character flags are split, e.g. -fd into -f -d. Flags may appear anywhere +# before a --, after which every argument is an operand. +__worktree_parse_args() { + local arg i + while (( $# )); do + arg=$1 + shift + case "$arg" in + --) operands+=("$@"); return ;; + --?*) flags+=("$arg") ;; + -?*) + for (( i = 2; i <= ${#arg}; i++ )); do + flags+=("-${arg[i]}") + done + ;; + *) operands+=("$arg") ;; + esac + done +} + __worktree_find_in() { local dir=$1 pat=$2 icase=$3 if (( $+commands[fd] )); then @@ -66,9 +87,9 @@ __worktree_find_in() { fd_args+=(--case-sensitive) fi if [[ "$pat" == */* ]]; then - fd "${fd_args[@]}" --full-path "**/$pat" + fd "${fd_args[@]}" --full-path -- "**/$pat" else - fd "${fd_args[@]}" "$pat" + fd "${fd_args[@]}" -- "$pat" fi else local ic= @@ -177,14 +198,19 @@ which must be merged unless -f is given." find) local icase=0 - local -a globs - local arg - for arg in "${@:2}"; do - case "$arg" in + local -a flags operands + __worktree_parse_args "${@:2}" + local flag + for flag in "${flags[@]}"; do + case "$flag" in -i|--ignore-case) icase=1 ;; - *) globs+=("$arg") ;; + *) + print -P "%F{red}error:%f unknown option: $flag" + return 1 + ;; esac done + local -a globs=("${operands[@]}") if (( ${#globs} == 0 )); then print -P "%F{red}error:%f missing argument" return 1 @@ -291,15 +317,20 @@ which must be merged unless -f is given." rm|remove) local force=0 local delete_branch=0 - local branches=() - local arg - for arg in "${@:2}"; do - case "$arg" in + local -a flags operands + __worktree_parse_args "${@:2}" + local flag + for flag in "${flags[@]}"; do + case "$flag" in -f|--force) force=1 ;; -d|--delete-branch) delete_branch=1 ;; - *) branches+=("$arg") ;; + *) + print -P "%F{red}error:%f unknown option: $flag" + return 1 + ;; esac done + local branches=("${operands[@]}") if (( ${#branches[@]} == 0 )); then print -P "%F{red}error:%f missing argument" return 1