diff --git a/ChangeLog b/ChangeLog index 15ba60489..4695a9a2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2006-09-27 Peter Stephenson + * 22780: Completion/Base/Utility/_arguments: + Completion/Unix/Command/_todo.sh, Doc/Zsh/compsys.yo, + Src/Zle/computil.c: _arguments -n sets NORMARG to index of first + non-option argument (via comparguments -n); use this in _todo.sh. + * unposted: Completion/Unix/Command/_todo.sh: replace buggy search message by completion of projects and contexts. diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments index 05a287a5f..a87486168 100644 --- a/Completion/Base/Utility/_arguments +++ b/Completion/Base/Utility/_arguments @@ -5,6 +5,7 @@ local long cmd="$words[1]" descr mesg subopts opt usecc autod local oldcontext="$curcontext" hasopts rawret optarg singopt alwopt +local setnormarg long=$argv[(I)--] if (( long )); then @@ -189,12 +190,13 @@ fi subopts=() singopt=() -while [[ "$1" = -(O*|[CRWsw]) ]]; do +while [[ "$1" = -(O*|[CRWnsw]) ]]; do case "$1" in -C) usecc=yes; shift ;; -O) subopts=( "${(@P)2}" ); shift 2 ;; -O*) subopts=( "${(@P)${1[3,-1]}}" ); shift ;; -R) rawret=yes; shift;; + -n) setnormarg=yes; NORMARG=-1; shift;; -w) optarg=yes; shift;; -s) singopt=(-s); shift;; -W) alwopt=arg; shift;; @@ -251,6 +253,10 @@ if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then descr="$descrs[anum]" subc="$subcs[anum++]" + if [[ $subc = argument* && -n $setnormarg ]]; then + comparguments -n NORMARG + fi + if [[ -n "$matched" ]] || _requested "$subc"; then curcontext="${oldcontext%:*}:$subc" diff --git a/Completion/Unix/Command/_todo.sh b/Completion/Unix/Command/_todo.sh index 5d60b9684..fc984f7d4 100644 --- a/Completion/Unix/Command/_todo.sh +++ b/Completion/Unix/Command/_todo.sh @@ -11,8 +11,9 @@ setopt localoptions braceccl local expl curcontext="$curcontext" state line pri nextstate local -a cmdlist itemlist +integer NORMARG -_arguments -s \ +_arguments -s -n : \ '-d[alternate config file]:config file:_files' \ '-f[force, no confirmation]' \ '-h[display help]' \ @@ -20,8 +21,7 @@ _arguments -s \ '-v[verbose mode, confirmation messages]' \ '-V[display version etc.]' \ '1:command:->commands' \ - '2:first argument:->firstarg' \ - '3:second argument:->secondarg' && return 0 + '*:arguments:->arguments' && return 0 local txtmsg="text, can include p: and @" @@ -45,11 +45,25 @@ case $state in _describe -t todo-commands 'todo.sh command' cmdlist ;; - (firstarg) - case $words[CURRENT-1] in + (arguments) + case $words[NORMARG] in (append|del|do|prepend|pri|replace) - itemlist=(${${(M)${(f)"$(todo.sh list)"}##<-> *}/(#b)(<->) (*)/${match[1]}:${match[2]}}) - _describe -t todo-items 'todo item' itemlist + if (( NORMARG == CURRENT - 1 )); then + itemlist=(${${(M)${(f)"$(todo.sh list)"}##<-> *}/(#b)(<->) (*)/${match[1]}:${match[2]}}) + _describe -t todo-items 'todo item' itemlist + else + case $words[NORMARG] in + (pri) + nextstate=pri + ;; + (append|prepend) + _message $txtmsg + ;; + (replace) + compadd -Q -- "${(qq)$(todo.sh list "^0*${words[CURRENT-1]} ")##<-> }" + ;; + esac + fi ;; (add) @@ -59,9 +73,6 @@ case $state in (list|listall) # This completes stuff beginning with p: (projects) or @ (contexts); # these are todo.sh conventions. - # We should do it for any argument after list or listall, but - # _arguments doesn't make that easy. We need it to tell us - # the position of the first non-option argument. _wanted search expl 'context or project' \ compadd ${${=${${(M)${(f)"$(todo.sh list)"}##<-> *}##<-> }}:#^(p:*|@*)} ;; @@ -75,23 +86,6 @@ case $state in ;; esac ;; - - (secondarg) - case $words[CURRENT-2] in - (append|prepend) - _message $txtmsg - ;; - (pri) - nextstate=pri - ;; - (replace) - compadd -Q -- "${(qq)$(todo.sh list "^0*${words[CURRENT-1]} ")##<-> }" - ;; - (*) - return 1 - ;; - esac - ;; esac case $nextstate in diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 1a81eea3f..f65f15223 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -3237,12 +3237,21 @@ Like tt(_tags) this function supports the tt(-C) option to give a different name for the argument context field. ) findex(_arguments) -item(tt(_arguments) [ tt(-swWACRS) ] [ tt(-O) var(name) ] [ tt(-M) var(matchspec) ] [ tt(:) ] var(spec) ...)( +item(tt(_arguments) [ tt(-nswWACRS) ] [ tt(-O) var(name) ] [ tt(-M) var(matchspec) ] [ tt(:) ] var(spec) ...)( This function can be used to give a complete specification for completion for a command whose arguments follow standard UNIX option and argument conventions. The following forms specify individual sets of options and arguments; to avoid ambiguity, these may be separated from the -options to tt(_arguments) itself by a single colon. +options to tt(_arguments) itself by a single colon. Options to +tt(_arguments) itself must be in separate words, i.e. tt(-s -w), not +tt(-sw). + +With the option tt(-n), tt(_arguments) sets the parameter tt(NORMARG) +to the position of the first normal argument in the tt($words) array, +i.e. the position after the end of the options. If that argument +has not been reached, tt(NORMARG) is set to tt(-1). The caller +should declare `tt(integer NORMARG)' if the tt(-n) option is passed; +otherwise the parameter is not used. startitem() xitem(var(n)tt(:)var(message)tt(:)var(action)) diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 17eb7a8df..bde1f79af 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -2371,6 +2371,7 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) case 'M': min = 1; max = 1; break; case 'a': min = 0; max = 0; break; case 'W': min = 2; max = 2; break; + case 'n': min = 1; max = 1; break; default: zwarnnam(nam, "invalid option: %s", args[0]); return 1; @@ -2665,6 +2666,20 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) sethparam(args[2], ret); } return 0; + case 'n': + /* + * This returns the array index of the word where normal + * arguments began. It uses optbeg rather than nargbeg + * (the value used when parsing) because nargbeg is assigned + * to optbeg in the returned value and nargbeg isn't + * used. + * + * -->PLEASE DON'T ASK<-- + * + * Thank you. + */ + setiparam(args[1], (zlong)ca_laststate.optbeg + !isset(KSHARRAYS)); + return 0; } return 1; }