about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Base/Utility/_arguments8
-rw-r--r--Completion/Unix/Command/_todo.sh48
-rw-r--r--Doc/Zsh/compsys.yo13
-rw-r--r--Src/Zle/computil.c15
5 files changed, 59 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 15ba60489..4695a9a2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2006-09-27  Peter Stephenson  <pws@csr.com>
 
+	* 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:<project> and @<where>"
 
@@ -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;
 }