Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: still confused about completion and matching
- X-seq: zsh-workers 13038
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxx
- Subject: Re: still confused about completion and matching
- Date: Thu, 19 Oct 2000 11:11:27 +0200 (MET DST)
- In-reply-to: "E. Jay Berkenbilt"'s message of Tue, 17 Oct 2000 15:30:55 -0400
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
E. Jay Berkenbilt wrote:
> ...
>
> zsh% ls u?/q/e?/ TAB
>
> finds no matches. The problem has to do with the code that is in the
> if (( tmp4 )) block in _path_files starting at line 463.
Yes, it couldn't match the paths with the way $PREFIX and $SUFFIX were
set up.
> ...
>
> The functionality I was able to get differs from what I originally
> described in two ways: if partial expansion is possible (i.e.,
> expansion of the first metacharacter but not the second), it is still
> not done. Expansion is done only when *all* metacharacters match
> unambiguously. This is fine -- in fact, it's probably better than
> what I originally specified.
The patch below should be a bit better (also fixing the `u1// ...'
thing you reported).
> The other thing is that the code doesn't
> complete as far as possible. For example, ls u?/ TAB should complete
> through u?/q since all the choices start with q. I can live without
> this too though I don't see exactly why it doesn't work.
It's because of the change in _match. That keeps the command line from
being changed if completion is ambiguous (btw., the patch below
slightly changes that test, too, giving a better behaviour, but it
can't be perfect, I'm sorry).
The problem really is that the completion can only: 1) leave the
command line unchanged, 2) insert a match (menu completion like or if
the match is unambiguous) or 3) insert the unambiguous part of a
match. That last one can't work if the matches were generated using
pattern matching -- how should it detect which wildcards should be
left unchanged and which have been used to match something
unambiguously. And note that the stuff I'm talking about is in the
C-code, at the very heart of the completion code.
We could change the strings generated as matches in _path_files to
contain the patterns in the ambiguous components, but that would break
menu completion (in the list this could be fixed using display
strings, but with menu completion: no way).
So, sorry, I don't see a way to implement what you want exactly,
without breaking one style of completion or the other.
Bye
Sven
diff -u -r ../oz/Completion/Builtins/_zstyle ./Completion/Builtins/_zstyle
--- ../oz/Completion/Builtins/_zstyle Wed Oct 18 20:54:45 2000
+++ ./Completion/Builtins/_zstyle Wed Oct 18 21:47:59 2000
@@ -44,7 +44,7 @@
ignored-patterns c:
insert-ids c:insert-ids
insert-tab c:bool
- insert-unambiguous c:bool
+ insert-unambiguous c:insunambig
keep-prefix c:keep-prefix
last-prompt c:bool
list c:listwhen
@@ -52,6 +52,7 @@
list-packed c:bool
list-prompt c:
list-rows-first c:bool
+ list-suffixes c:bool
local c:
match-original c:match-orig
matcher c:
@@ -290,6 +291,10 @@
oldmatches)
_wanted values expl 'use list of old matches' compadd true false only
+ ;;
+
+ insunambig)
+ _wanted values expl 'insert unambiguous string compadd true false pattern
;;
urgh)
diff -u -r ../oz/Completion/Core/_match ./Completion/Core/_match
--- ../oz/Completion/Core/_match Wed Oct 18 20:54:45 2000
+++ ./Completion/Core/_match Wed Oct 18 21:57:34 2000
@@ -11,41 +11,55 @@
### Shouldn't be needed any more: [[ _matcher_num -gt 1 ]] && return 1
-local tmp opm="$compstate[pattern_match]" ret=0 orig ins
+local tmp opm="$compstate[pattern_match]" ret=1 orig ins
+local oms="$_old_match_string" ocsi="$compstate[insert]"
# Do nothing if we don't have a pattern.
tmp="${${:-$PREFIX$SUFFIX}#[~=]}"
[[ "$tmp:q" = "$tmp" ]] && return 1
+_old_match_string="$PREFIX$SUFFIX$HISTNO"
+
zstyle -s ":completion:${curcontext}:" match-original orig
-zstyle -b ":completion:${curcontext}:" insert-unambiguous ins
+zstyle -s ":completion:${curcontext}:" insert-unambiguous ins
# Try completion without inserting a `*'?
if [[ -n "$orig" ]]; then
compstate[pattern_match]='-'
- _complete && ret=1
+ _complete && ret=0
compstate[pattern_match]="$opm"
- if (( ret )); then
- [[ "$ins" = yes &&
- $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] &&
- compstate[pattern_insert]=unambiguous
- return 0
- fi
+ # No completion with inserting `*'?
+
+ [[ ret -eq 1 && "$orig" = only ]] && return 1
+fi
+
+if (( ret )); then
+ compstate[pattern_match]='*'
+ _complete && ret=0
+ compstate[pattern_match]="$opm"
fi
-# No completion with inserting `*'?
+if (( ! ret )); then
+
+ if [[ "$ins" = pattern && $compstate[nmatches] -gt 1 ]]; then
-[[ "$orig" = only ]] && return 1
+ [[ "$oms" = "$PREFIX$SUFFIX$HISTNO" &&
+ "$compstate[insert]" = automenu-unambiguous ]] &&
+ compstate[insert]=automenu
+ [[ "$compstate[insert]" != *menu ]] &&
+ compstate[pattern_insert]= compstate[insert]=
-compstate[pattern_match]='*'
-_complete && ret=1
-compstate[pattern_match]="$opm"
+ [[ $compstate[unambiguous_cursor] -gt $#compstate[unambiguous] ]] &&
+ ins=yes compstate[insert]="$ocsi"
+ fi
-[[ ret -eq 1 && "$ins" = yes &&
- $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] &&
- compstate[pattern_insert]=unambiguous
+ [[ "$ins" = (true|yes|on|1) &&
+ $#compstate[unambiguous] -ge ${#:-${PREFIX}${SUFFIX}} ]] &&
+ compstate[pattern_insert]=unambiguous
+
+fi
-return 1-ret
+return ret
diff -u -r ../oz/Completion/Core/_path_files ./Completion/Core/_path_files
--- ../oz/Completion/Core/_path_files Wed Oct 18 20:54:45 2000
+++ ./Completion/Core/_path_files Wed Oct 18 21:48:57 2000
@@ -5,7 +5,7 @@
local linepath realpath donepath prepath testpath exppath skips skipped
local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre
-local pats haspats ignore pfxsfx sopt gopt opt sdirs ignpar cfopt
+local pats haspats ignore pfxsfx sopt gopt opt sdirs ignpar cfopt listsfx
local nm=$compstate[nmatches] menu matcher mopts sort match mid accex fake
typeset -U prepaths exppaths
@@ -137,6 +137,8 @@
fi
zstyle -s ":completion:${curcontext}:paths" special-dirs sdirs
+zstyle -t ":completion:${curcontext}:paths" list-suffixes &&
+ listsfx=yes
[[ "$pats" = ((|*[[:blank:]])\*(|[[:blank:]]*)|*\([^[:blank:]]#/[^[:blank:]]#\)*) ]] &&
sopt=$sopt/
@@ -460,9 +462,11 @@
SUFFIX="${tsuf}"
fi
- if (( tmp4 )) ||
- [[ -n "$compstate[pattern_match]" &&
- "$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
+ # This once tested `|| [[ -n "$compstate[pattern_match]" &&
+ # "$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]' but it should now be smart
+ # enough to handle multiple components with patterns.
+
+ if (( tmp4 )); then
# It is. For menucompletion we now add the possible completions
# for this component with the unambigous prefix we have built
# and the rest of the string from the line as the suffix.
@@ -480,15 +484,33 @@
compquote tmp1 tmp2
fi
+ if [[ -z "$_comp_correct" &&
+ "$compstate[pattern_match]" = \* && -n "$listsfx" &&
+ "$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
+ PREFIX="$opre"
+ SUFFIX="$osuf"
+ fi
+
if [[ -n $menu || -z "$compstate[insert]" ]] ||
- ! zstyle -t ":completion:${curcontext}:paths" expand suffix; then
+ ! zstyle -t ":completion:${curcontext}:paths" expand suffix ||
+ [[ -z "$listsfx" &&
+ ( -n "$_comp_correct" ||
+ -z "$compstate[pattern_match]" || "$SUFFIX" != */* ||
+ "${SUFFIX#*/}" = (|*[^\\])[][*?#~^\|\<\>]* ) ]]; then
(( tmp4 )) && zstyle -t ":completion:${curcontext}:paths" ambiguous &&
compstate[to_end]=
if [[ "$tmp3" = */* ]]; then
- compadd -Qf "$mopts[@]" -p "$linepath$tmp2" -s "/${tmp3#*/}" \
- -W "$prepath$realpath$testpath" \
- "$pfxsfx[@]" -M "r:|/=* r:|=*" \
- - "${(@)tmp1%%/*}"
+ if [[ -z "$listsfx" || "$tmp3" != */?* ]]; then
+ compadd -Qf "$mopts[@]" -p "$linepath$tmp2" -s "/${tmp3#*/}" \
+ -W "$prepath$realpath$testpath" \
+ "$pfxsfx[@]" -M "r:|/=* r:|=*" \
+ - "${(@)tmp1%%/*}"
+ else
+ compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
+ -W "$prepath$realpath$testpath" \
+ "$pfxsfx[@]" -M "r:|/=* r:|=*" \
+ - "${(@)^tmp1%%/*}/${tmp3#*/}"
+ fi
else
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
-W "$prepath$realpath$testpath" \
@@ -497,12 +519,20 @@
fi
else
if [[ "$tmp3" = */* ]]; then
- tmp3=( -Qf "$mopts[@]" -p "$linepath$tmp2"
+ tmp4=( -Qf "$mopts[@]" -p "$linepath$tmp2"
-W "$prepath$realpath$testpath"
"$pfxsfx[@]" -M "r:|/=* r:|=*" )
- for i in "$tmp1[@]"; do
- compadd "$tmp3[@]" -s "/${i#*/}" - "${i%%/*}"
- done
+ if [[ -z "$listsfx" ]]; then
+ for i in "$tmp1[@]"; do
+ compadd "$tmp4[@]" -s "/${i#*/}" - "${i%%/*}"
+ done
+ else
+ [[ -n "$compstate[pattern_match]" ]] && SUFFIX="${SUFFIX:s./.*/}*"
+
+ for i in "$tmp1[@]"; do
+ compadd "$tmp4[@]" - "$i"
+ done
+ fi
else
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
-W "$prepath$realpath$testpath" \
@@ -526,22 +556,33 @@
# take it from the filenames.
testpath="${testpath}${tmp1[1]%%/*}/"
- tmp1=( "${(@)tmp1#*/}" )
tmp3="${tmp3#*/}"
if [[ "$tpre" = */* ]]; then
- cpre="${cpre}${tpre%%/*}/"
+ if [[ -z "$_comp_correct" && -n "$compstate[pattern_match]" &&
+ "$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
+ cpre="${cpre}${tmp1[1]%%/*}/"
+ else
+ cpre="${cpre}${tpre%%/*}/"
+ fi
tpre="${tpre#*/}"
elif [[ "$tsuf" = */* ]]; then
[[ "$tsuf" != /* ]] && mid="$testpath"
- cpre="${cpre}${tpre}/"
+ if [[ -z "$_comp_correct" && -n "$compstate[pattern_match]" &&
+ "$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
+ cpre="${cpre}${tmp1[1]%%/*}/"
+ else
+ cpre="${cpre}${tpre}/"
+ fi
tpre="${tsuf#*/}"
tsuf=
else
tpre=
tsuf=
fi
+
+ tmp1=( "${(@)tmp1#*/}" )
done
if [[ -z "$tmp4" ]]; then
diff -u -r ../oz/Doc/Zsh/compsys.yo ./Doc/Zsh/compsys.yo
--- ../oz/Doc/Zsh/compsys.yo Wed Oct 18 20:54:38 2000
+++ ./Doc/Zsh/compsys.yo Wed Oct 18 21:48:15 2000
@@ -1367,6 +1367,10 @@
in the context name to one of tt(correct-)var(num) or
tt(approximate-)var(num), where var(num) is the number of errors that
were accepted.
+
+When used for the tt(_match) completer, the style may also be set to
+the string `tt(pattern)'. This makes the pattern on the line be left
+unchanged if it didn't match unambiguously.
)
kindex(keep-prefix, completion style)
item(tt(keep-prefix))(
@@ -1466,6 +1470,14 @@
determines if matches are to be listed in a rows-first fashion, as for the
tt(LIST_ROWS_FIRST) option.
)
+kindex(list-suffixes, completion style)
+item(tt(list-suffixes))(
+This style is used by the function used to complete filenames. If
+completion is attempted on a string containing multiple partially
+typed pathname components and this style is set to `true', all
+components starting with the first one for which more than one match
+could be generated will be shown.
+)
kindex(local, completion style)
item(tt(local))(
This style is used by completion functions which generate URLs as
@@ -2416,6 +2428,9 @@
tt(insert-unambiguous) style is set to `true'. In
this case menu completion will only be started if no unambiguous string
could be generated that is at least as long as the original string.
+The style may also be set to the string `tt(pattern)'. This will keep
+the pattern on the line intact as long as there isn't an unambiguous
+completion with which it could be replaced.
Note that the matcher specifications defined globally or used by the
completion functions will not be used.
@@ -3474,7 +3489,7 @@
`tt(-r)', and `tt(-R)' options from the tt(compadd) builtin.
Finally, the tt(_path_files) function uses the styles tt(expand),
-tt(ambiguous) and tt(special-dirs) and tt(file-sort).
+tt(ambiguous), tt(special-dirs), tt(list-suffixes) and tt(file-sort).
)
findex(_regex_arguments)
item(tt(_regex_arguments) var(name) var(specs) ...)(
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author