zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: Set index of first non-option argument in _arguments
@ 2006-09-27 16:29 Peter Stephenson
  2006-09-27 17:09 ` Peter Stephenson
  0 siblings, 1 reply; 2+ messages in thread
From: Peter Stephenson @ 2006-09-27 16:29 UTC (permalink / raw)
  To: Zsh hackers list

One thing that's annoyed me about _arguments (let's stick at that for now,
shall we?) is that although it, or rather the comparguments builtin,
knows perfectly well where the first argument after the options
started, it won't tell you.  This makes it unnecessarily difficult to
handle commands with subcommands with different arguments (such as cvs
or svn); you basically have to reparse the command line yourself to do
it properly.

This adds the option -n to _arguments to set NORMARG to the index of
first non-option argument, and uses it in _todo.sh to illustrate.

My first reaction to this was "OH MY *@!@! IT WORKS!", so I haven't
dared to peer too deeply into the code, where there could easily be
funnies.

_arguments still needs better documentation, in particular for the other
of its own options, whose documentation is hidden away.

There's a possible incompatibility if you don't use : to end _arguments'
option list, but that was always a difficulty and we'll have to pick up
the pieces as they fall.  The fact that : ends the list of options sucks
quite badly even by the standards of _arguments syntax.  OK, *now* I'm
rambling.

Index: Completion/Base/Utility/_arguments
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Base/Utility/_arguments,v
retrieving revision 1.16
diff -u -r1.16 _arguments
--- Completion/Base/Utility/_arguments	18 Jun 2004 09:49:00 -0000	1.16
+++ Completion/Base/Utility/_arguments	27 Sep 2006 16:26:31 -0000
@@ -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 @@
 
 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 @@
 	  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"
Index: Completion/Unix/Command/_todo.sh
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Unix/Command/_todo.sh,v
retrieving revision 1.2
diff -u -r1.2 _todo.sh
--- Completion/Unix/Command/_todo.sh	27 Sep 2006 14:50:35 -0000	1.2
+++ Completion/Unix/Command/_todo.sh	27 Sep 2006 16:26:31 -0000
@@ -11,8 +11,9 @@
 
 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 @@
   '-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 @@
   _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 @@
     (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 @@
     ;;
   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
Index: Doc/Zsh/compsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v
retrieving revision 1.192
diff -u -r1.192 compsys.yo
--- Doc/Zsh/compsys.yo	21 Sep 2006 19:54:31 -0000	1.192
+++ Doc/Zsh/compsys.yo	27 Sep 2006 16:26:32 -0000
@@ -3237,12 +3237,21 @@
 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))
Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.96
diff -u -r1.96 computil.c
--- Src/Zle/computil.c	23 Sep 2006 14:43:58 -0000	1.96
+++ Src/Zle/computil.c	27 Sep 2006 16:26:33 -0000
@@ -2371,6 +2371,7 @@
     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 @@
 	    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;
 }

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: PATCH: Set index of first non-option argument in _arguments
  2006-09-27 16:29 PATCH: Set index of first non-option argument in _arguments Peter Stephenson
@ 2006-09-27 17:09 ` Peter Stephenson
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Stephenson @ 2006-09-27 17:09 UTC (permalink / raw)
  To: Zsh hackers list

Peter Stephenson wrote:
> One thing that's annoyed me about _arguments (let's stick at that for now,
> shall we?) is that although it, or rather the comparguments builtin,
> knows perfectly well where the first argument after the options
> started, it won't tell you.  This makes it unnecessarily difficult to
> handle commands with subcommands with different arguments (such as cvs
> or svn); you basically have to reparse the command line yourself to do
> it properly.

To be scrupulous:  that's not entirely true.  There's an option
*::: to limit the words in the completion array to just the arguments.
However, that's not necessarily flexible enough.  What probably would
have been would be looking at the context which should be set to
include argument-N, and that N is just CURRENT - NORMARG + 1.

Still, I've done it now.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-09-27 17:09 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-27 16:29 PATCH: Set index of first non-option argument in _arguments Peter Stephenson
2006-09-27 17:09 ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).