Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: completion
- X-seq: zsh-workers 7467
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxx
- Subject: Re: PATCH: completion
- Date: Mon, 23 Aug 1999 15:46:54 +0200 (MET DST)
- In-reply-to: Tanaka Akira's message of 21 Aug 1999 08:22:55 +0900
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
Tanaka Akira wrote:
> Some options take arguments up to end of command line.
>
> If _arguments supports this style of options, it is also useful for
> _cvs, I suppose. Because first non-option argument for cvs command
> behaves like that.
This tries to implement this.
The syntax is:
'-opt:*:descr:action'
Of course there may be other argument descriptions before the
`:*:'. This can also handle multiple arguments ended by a word
matching a pattern: '-opt:*pattern:descr:action'. And one can select
if the `words' and `CURRENT' parameters should be restricted to those
words that are the arguments to the option or to those words covered
by the `:*:' description only. This is done by using two or three
colons as in:
'-opt:*::descr:action' # all args to the option
'-opt:first arg:...:*:::descr:action' # only the words covered by `:*:...'
Once this fully works, `_arguments' will be incredibly powerful... ;-)
There are also fixes for some typos in there...
Bye
Sven
P.S.: I /think/ it should be possible to implement `_find' using
`_arguments' now...
diff -u od/Zsh/compsys.yo Doc/Zsh/compsys.yo
--- od/Zsh/compsys.yo Mon Aug 23 11:42:16 1999
+++ Doc/Zsh/compsys.yo Mon Aug 23 15:37:18 1999
@@ -836,11 +836,13 @@
to automatically find out what should be completed as the argument.
The possible completions for option-arguments can be described with
the arguments to this function. Each argument contains one description
-of the form <pattern>:<message>:<action>. The message will be printed
+of the form `tt(<pattern>:<message>:<action>)'. The message will be printed
above the possible completion if the `description_format' configuration
key is set (see above). The actions specify what
should be done to complete arguments of those options that match
-the pattern. The action may be a list of words in brackets or in
+the pattern. In both the message and the action a colon can be
+included by preceding it with a backslash. The action may be a list of
+words in brackets or in
parentheses, separated by spaces. A list in brackets denotes
possible values for an optional argument, a list in parentheses
gives words to complete for mandatory arguments. If the action does
@@ -910,6 +912,18 @@
`tt(:)var(message)tt(:)var(action)' or
`tt(::)var(message)tt(:)var(action)', where the second form describes
an optional argument and the first one describes a mandatory argument.
+The last description may also be of the form
+`tt(:*:)var(message)tt(:)var(action)' or
+`tt(:*)var(pattern)tt(:)var(message)tt(:)var(action)'. These describe
+multiple arguments. In the first form all following words on the line
+are to be completed as described by the var(action), in the second
+form all words up to a word matching the given var(pattern) are to be
+completed using the var(action). The `tt(*)' or the var(pattern) may
+also be separated from the var(message) by two or three colons. With
+two colons the tt(words) special array and the tt(CURRENT) special
+parameter are modified to refer only to the words after the option
+(with two colons) or to the words covered by this description (with
+three colons) during the execution or evaluation of the var(action).
In the simplest form the var(opt-spec) is just the option name
beginning with a minus or a plus sign, such as `tt(-foo)'. In this
@@ -941,8 +955,11 @@
in the description will be shown above the matches. During the
evaluation or execution of the action the array `tt(line)' will be set
to the command name and normal arguments from the command line,
-i.e. to the words from the command line xcluding all options and their
+i.e. to the words from the command line excluding all options and their
arguments.
+
+To include a colon in the var(message) or the var(action), it has to
+be preceded by a backslash.
Normally the option names are taken as multi-character names and a
word from the line is considered to contain only one option (or
diff -u -r oc/Base/_arguments Completion/Base/_arguments
--- oc/Base/_arguments Mon Aug 23 11:42:44 1999
+++ Completion/Base/_arguments Mon Aug 23 15:39:03 1999
@@ -7,6 +7,7 @@
local long args rest ws cur nth def nm expl descr action opt arg tmp
local single uns ret=1 soptseq soptseq1 sopts prefix line
+local beg optbeg argbeg
# Associative arrays used to collect information about the options.
@@ -122,7 +123,10 @@
ws=( "${(@)words[2,-1]}" )
cur=$(( CURRENT-2 ))
nth=1
-liine=( "$words[1]" )
+line=( "$words[1]" )
+beg=2
+argbeg=2
+optbeg=2
# ...until the current word is reached.
@@ -138,15 +142,27 @@
fi
arg=''
+ # See if we are after an option getting n arguments ended by something
+ # that matches the current word.
+
+ if [[ "$def" = \**[^\\]:* && "$ws[1]" = ${~${(M)def#*[^\\]:}[2,-2]} ]]; then
+ def=''
+ shift 1 ws
+ (( cur-- ))
+ (( beg++ ))
+ continue
+ fi
+
# Remove one description/action pair from `def' if that isn't empty.
- if [[ -n "$def" ]]; then
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
+ if [[ -n "$def" && "$def" != \** ]]; then
+ if [[ "$def" = ?*[^\\]:*[^\\]:* ]]; then
+ def="${def#?*[^\\]:*[^\\]:}"
+ argbeg="$beg"
else
def=''
fi
- else
+ elif [[ -z "$def" ]]; then
# If it is empty, and the word starts with `--' and we should
# complete long options, just ignore this word, otherwise make sure
@@ -179,6 +195,8 @@
tmp="${ws[1][1]}${ws[1][-1]}"
if (( $+opts[$tmp] )); then
def="$opts[$tmp]"
+ optbeg="$beg"
+ argbeg="$beg"
uns="${ws[1][2,-1]}"
opt=''
fi
@@ -217,9 +235,11 @@
opt=''
def="$dopts[$tmp[1]]"
+ optbeg="$beg"
+ argbeg="$beg"
[[ -n "$oneshot[$tmp[1]]" ]] && unset "dopts[$tmp[1]]"
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
+ if [[ "$def" = [^*]*[^\\]:*[^\\]:* ]]; then
+ def="${def#?*[^\\]:*[^\\]:}"
else
def=''
fi
@@ -242,6 +262,8 @@
if (( $#tmp )); then
opt=''
def="$odopts[$tmp[1]]"
+ optbeg="$beg"
+ argbeg="$beg"
[[ -n "$oneshot[$tmp[1]]" ]] && unset "odopts[$tmp[1]]"
# For options whose first argument *may* come after the
@@ -251,8 +273,10 @@
if [[ ( -z "$sopts" && "$ws[1]" != "$tmp[1]" ) ||
( -n "$sopts" && ( ( $tmp[1] = [-+]? && "$ws[1]" != "${tmp[1][1]}"${~soptseq}"${tmp[1][2]}" ) ||
( $tmp[1] != [-+]? && "$ws[1]" != "$tmp[1]" ) ) ) ]]; then
- if [[ "$def" = ?*:*:* ]]; then
- def="${def#?*:*:}"
+ if [[ "$def" = [^*]*[^\\]:*[^\\]:* ]]; then
+ def="${def#?*[^\\]:*[^\\]:}"
+ optbeg="$beg"
+ argbeg="$beg"
else
def=''
fi
@@ -284,6 +308,7 @@
shift 1 ws
(( cur-- ))
+ (( beg++ ))
done
# Now generate the matches.
@@ -313,10 +338,16 @@
def="$args[nth]"
[[ -z "$def" ]] && def="$rest"
+
+ if [[ "$def" = \** ]]; then
+ def="${def#*[^\\]:}"
+ [[ "$def" = :* ]] && def="$def[2,-1]"
+ [[ "$def" = :* ]] && def="$def[2,-1]"
+ fi
fi
# In any case, we have to complete option names here, but we may
- # be in a string that starts with an option names and continues with
+ # be in a string that starts with an option name and continues with
# the first argument, test that (again, two loops).
opt=yes
@@ -407,14 +438,41 @@
if [[ -n "$def" ]]; then
- # Ignore the leading colon describing optional arguments.
+ # Ignore the leading colon or `*...' describing optional arguments.
+
+ if [[ "$def" = :* ]]; then
+ def="$def[2,-1]"
+ elif [[ "$def" = \** ]]; then
+ tmp="${${(M)def#*[^\\]:}[2,-2]}"
+ def="${def#*[^\\]:}"
+
+ if [[ "$def" = :* ]]; then
+ if [[ "$def" = ::* ]]; then
+ def="$def[3,-1]"
+ beg=$argbeg
+ else
+ def="$def[2,-1]"
+ beg=$optbeg
+ fi
- [[ "$def" = :* ]] && def="$def[2,-1]"
+ shift beg words
+ (( CURRENT -= beg ))
+
+ if [[ -n "$tmp" ]]; then
+ tmp="$words[(ib:CURRENT:)${~tmp}]"
+ [[ tmp -le $#words ]] && words=( "${(@)words[1,tmp-1]}" )
+ fi
+ fi
+ fi
# Get the description and the action.
- descr="${def%%:*}"
- action="${${def#*:}%%:*}"
+ descr="${${${(M)def#*[^\\]:}[1,-2]}//\\\\:/:}"
+ if [[ "$def" = *[^\\]:*[^\\]:* ]]; then
+ action="${${${(M)${def#*[^\\]:}#*[^\\]:}[1,-2]}//\\\\:/:}"
+ else
+ action="${${def#*[^\\]:}//\\\\:/:}"
+ fi
_description expl "$descr"
@@ -423,7 +481,7 @@
# An empty action means that we should just display a message.
_message "$descr"
return ret
- elif [[ "$action[1]" = \(*\) ]]; then
+ elif [[ "$action" = \(*\) ]]; then
# Anything inside `(...)' is added directly.
diff -u -r oc/Base/_long_options Completion/Base/_long_options
--- oc/Base/_long_options Mon Aug 23 11:42:44 1999
+++ Completion/Base/_long_options Mon Aug 23 12:01:58 1999
@@ -141,9 +141,9 @@
# First, we get the pattern and the action to use and take them
# from the positional parameters.
- pattern="${1%%:*}"
- descr="${${1#*:}%%:*}"
- action="${1#*:*:}"
+ pattern="${${${(M)1#*[^\\]:}[1,-2]}//\\\\:/:}"
+ descr="${${${(M)${1#*[^\\]:}#*[^\\]:}[1,-2]}//\\\\:/:}"
+ action="${${1#*[^\\]:*[^\\]:}//\\\\:/:}"
shift
# We get all options matching the pattern and take them from the
@@ -257,7 +257,7 @@
_description expl "$descr"
- if [[ "$action[1]" = (\[*\]|\(*\)) ]]; then
+ if [[ "$action" = (\[*\]|\(*\)) ]]; then
compadd "$expl[@]" - ${=action[2,-2]}
elif [[ "$action" = \{*\} ]]; then
eval "$action[2,-2]"
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author