mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-11-01 18:30:55 +01:00
22328, modified: add -o option to compadd
add _list_files helper to handle new file-list style for _path_files
This commit is contained in:
parent
1c06bba931
commit
e17fc50793
8 changed files with 149 additions and 10 deletions
|
|
@ -1,5 +1,13 @@
|
|||
2006-03-07 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 22328, modified: Completion/Unix/Type/_list_files,
|
||||
Completion/Unix/Type/_path_files, Doc/Zsh/compsys.yo,
|
||||
Doc/Zsh/compwid.yo, Src/Zle/comp.h, Src/Zle/compcore.c,
|
||||
Src/Zle/complete.c: Option -o to compadd uses match
|
||||
strings rather than display strings from -d for sorting;
|
||||
_path_files uses _list_files to handle file-list style
|
||||
which allows long format file lists.
|
||||
|
||||
* unposted: Config/version.mk: belatedly update version
|
||||
to 4.3.2-dev-1 to avoid clash with released version.
|
||||
|
||||
|
|
|
|||
66
Completion/Unix/Type/_list_files
Normal file
66
Completion/Unix/Type/_list_files
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#autoload
|
||||
|
||||
# Helper function for _path_files to handle the file-list style.
|
||||
|
||||
# arguments:
|
||||
# name of parameter containing file matches
|
||||
# directory prefix
|
||||
# Sets array listfiles to the display strings and the array
|
||||
# listopts appropriately to be added to the compadd command line.
|
||||
|
||||
local stat f elt what
|
||||
local -a stylevals
|
||||
integer ok
|
||||
|
||||
listfiles=()
|
||||
listopts=()
|
||||
|
||||
zmodload -i zsh/stat 2>/dev/null || return 1
|
||||
|
||||
zstyle -a ":completion:${curcontext}:" file-list stylevals || return 1
|
||||
|
||||
# TODO: more flexible way of handling the following? e.g. use $compstate?
|
||||
case $WIDGETSTYLE in
|
||||
(*complete*)
|
||||
what=insert
|
||||
;;
|
||||
|
||||
(*)
|
||||
what=list
|
||||
;;
|
||||
esac
|
||||
|
||||
for elt in $stylevals; do
|
||||
case $elt in
|
||||
(*($what|all|true|1|yes)*=<->)
|
||||
# use long format if no more than the given number of matches
|
||||
(( ${(P)#1} <= ${elt##*=} )) && (( ok = 1 ))
|
||||
break
|
||||
;;
|
||||
|
||||
(*($what|all|true|1|yes)[^=]#)
|
||||
# always use long format
|
||||
(( ok = 1 ))
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
(( ok )) || return 1
|
||||
|
||||
for f in ${(P)1}; do
|
||||
if [[ ! -e "${2:+$2/}$f" ]]; then
|
||||
listfiles+=("${2:+$2/}$f")
|
||||
continue
|
||||
fi
|
||||
|
||||
# Borrowed from Functions/Example/zls
|
||||
stat -s -H stat -F "%b %e %H:%M" - "${2:+$2/}$f" >/dev/null 2>&1
|
||||
|
||||
listfiles+=("$stat[mode] ${(l:3:)stat[nlink]} ${(r:8:)stat[uid]} \
|
||||
${(r:8:)stat[gid]} ${(l:8:)stat[size]} $stat[mtime] $f")
|
||||
done
|
||||
|
||||
(( ${#listfiles} )) && listopts=(-d listfiles -l -o)
|
||||
|
||||
return 0
|
||||
|
|
@ -7,6 +7,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 pfx pfxsfx sopt gopt opt sdirs ignpar cfopt listsfx
|
||||
local nm=$compstate[nmatches] menu matcher mopts sort match mid accex fake
|
||||
local listfiles listopts tmpdisp
|
||||
|
||||
typeset -U prepaths exppaths
|
||||
|
||||
|
|
@ -539,46 +540,65 @@ for prepath in "$prepaths[@]"; do
|
|||
( -n "$_comp_correct" ||
|
||||
-z "$compstate[pattern_match]" || "$SUFFIX" != */* ||
|
||||
"${SUFFIX#*/}" = (|*[^\\])[][*?#~^\|\<\>]* ) ]] }; then
|
||||
# We have not been told to insert the match, so we are
|
||||
# listing, or something.
|
||||
(( tmp4 )) && zstyle -t ":completion:${curcontext}:paths" ambiguous &&
|
||||
compstate[to_end]=
|
||||
if [[ "$tmp3" = */* ]]; then
|
||||
if [[ -z "$listsfx" || "$tmp3" != */?* ]]; then
|
||||
# I think this means we are expanding some directory
|
||||
# back up the path.
|
||||
tmp1=("${(@)tmp1%%/*}")
|
||||
_list_files tmp1 "$prepath$realpath$testpath"
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" -s "/${tmp3#*/}" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
- "${(@)tmp1%%/*}"
|
||||
$listopts \
|
||||
-a tmp1
|
||||
else
|
||||
# Same with a non-empty suffix
|
||||
tmp1=("${(@)^tmp1%%/*}/${tmp3#*/}")
|
||||
_list_files tmp1 "$prepath$realpath$testpath"
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
- "${(@)^tmp1%%/*}/${tmp3#*/}"
|
||||
$listopts \
|
||||
-a tmp1
|
||||
fi
|
||||
else
|
||||
_list_files tmp1 "$prepath$realpath$testpath"
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
$listopts \
|
||||
-a tmp1
|
||||
fi
|
||||
else
|
||||
# We are inserting the match into the command line.
|
||||
if [[ "$tmp3" = */* ]]; then
|
||||
tmp4=( -Qf "$mopts[@]" -p "$linepath$tmp2"
|
||||
-W "$prepath$realpath$testpath"
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" )
|
||||
if [[ -z "$listsfx" ]]; then
|
||||
for i in "$tmp1[@]"; do
|
||||
compadd "$tmp4[@]" -s "/${i#*/}" - "${i%%/*}"
|
||||
tmpdisp=("${i%%/*}")
|
||||
_list_files tmpdisp "$prepath$realpath$testpath"
|
||||
compadd "$tmp4[@]" -s "/${i#*/}" $listopts - "$tmpdisp"
|
||||
done
|
||||
else
|
||||
[[ -n "$compstate[pattern_match]" ]] && SUFFIX="${SUFFIX:s./.*/}*"
|
||||
|
||||
for i in "$tmp1[@]"; do
|
||||
compadd "$tmp4[@]" - "$i"
|
||||
_list_files i "$prepath$realpath$testpath"
|
||||
compadd "$tmp4[@]" $listopts - "$i"
|
||||
done
|
||||
fi
|
||||
else
|
||||
_list_files tmp1 "$prepath$realpath$testpath"
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
$listopts \
|
||||
-a tmp1
|
||||
fi
|
||||
fi
|
||||
|
|
@ -642,9 +662,10 @@ for prepath in "$prepaths[@]"; do
|
|||
fi
|
||||
compquote tmp4 tmp2 tmp1
|
||||
for i in "$tmp1[@]"; do
|
||||
_list_files tmp2 "$prepath$realpath${mid%/*/}"
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp3/" -s "/$tmp4$i" \
|
||||
-W "$prepath$realpath${mid%/*/}/" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" - "$tmp2"
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" $listopts - "$tmp2"
|
||||
done
|
||||
else
|
||||
if [[ "$osuf" = */* ]]; then
|
||||
|
|
@ -665,11 +686,15 @@ for prepath in "$prepaths[@]"; do
|
|||
fi
|
||||
if [[ -z "$_comp_correct" && -n "$compstate[pattern_match]" &&
|
||||
"${PREFIX#\~}$SUFFIX" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
|
||||
tmp1=("$linepath$tmp4${(@)^tmp1}")
|
||||
_list_files tmp1 "$prepath$realpath"
|
||||
compadd -Qf -W "$prepath$realpath" "$pfxsfx[@]" "$mopts[@]" \
|
||||
-M "r:|/=* r:|=*" - "$linepath$tmp4${(@)^tmp1}"
|
||||
-M "r:|/=* r:|=*" $listopts -a tmp1
|
||||
else
|
||||
# Not a pattern match
|
||||
_list_files tmp1 "$prepath$realpath$testpath"
|
||||
compadd -Qf -p "$linepath$tmp4" -W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" "$mopts[@]" -M "r:|/=* r:|=*" -a tmp1
|
||||
"$pfxsfx[@]" "$mopts[@]" -M "r:|/=* r:|=*" $listopts -a tmp1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1263,6 +1263,36 @@ given, the name will only be completed if parameters of that type are
|
|||
required in the particular context. Names for which no type is
|
||||
specified will always be completed.
|
||||
)
|
||||
kindex(file-list, completion style)
|
||||
item(tt(file-list))(
|
||||
This style controls whether files completed using the standard builtin
|
||||
mechanism are to be listed with a long list similar to tt(ls -l)
|
||||
(although note that this feature actually uses the shell module
|
||||
tt(zsh/stat) for file information).
|
||||
|
||||
The style may either be set to a true value (or `tt(all)'), or
|
||||
one of the values `tt(insert)' or `tt(list)', indicating that files
|
||||
are to be listed in long format in all circumstances, or when
|
||||
attempting to insert a file name, or when listing file names
|
||||
without attempting to insert one.
|
||||
|
||||
More generally, the value may be an array of any of the above values,
|
||||
optionally followed by tt(=)var(num). If var(num) is present it
|
||||
gives the maximum number of matches for which long listing style
|
||||
will be used. For example,
|
||||
|
||||
example(zstyle ':completion:*' file-list list=20 insert=10)
|
||||
|
||||
specifies that long format will be used when listing up to 20 files
|
||||
or inserting a file with up to 10 matches (assuming a listing
|
||||
is to be shown at all, for example on an ambiguous completion), else short
|
||||
format will be used.
|
||||
|
||||
example(zstyle -e ':completion:*' file-list '(( ${+NUMERIC} )) && reply=(true)')
|
||||
|
||||
specifies that long format will be used any time a numeric argument is
|
||||
supplied, else short format.
|
||||
)
|
||||
kindex(file-patterns, completion style)
|
||||
item(tt(file-patterns))(
|
||||
This is used by the standard function for completing filenames,
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ sect(Builtin Commands)
|
|||
startitem()
|
||||
findex(compadd)
|
||||
cindex(completion widgets, adding specified matches)
|
||||
xitem(tt(compadd) [ tt(-akqQfenUl12C) ] [ tt(-F) var(array) ])
|
||||
xitem(tt(compadd) [ tt(-akqQfenUld12C) ] [ tt(-F) var(array) ])
|
||||
xitem([ tt(-P) var(prefix) ] [ tt(-S) var(suffix) ])
|
||||
xitem([ tt(-p) var(hidden-prefix) ] [ tt(-s) var(hidden-suffix) ])
|
||||
xitem([ tt(-i) var(ignored-prefix) ] [ tt(-I) var(ignored-suffix) ])
|
||||
|
|
@ -530,6 +530,12 @@ This option only has an effect if used together with the tt(-d)
|
|||
option. If it is given, the display strings are listed one per line,
|
||||
not arrayed in columns.
|
||||
)
|
||||
item(tt(-o))(
|
||||
This option only has an effect if used together with the tt(-d)
|
||||
option. If it is given, the order of the output is determined by the
|
||||
match strings; otherwise it is determined by the display strings
|
||||
(i.e. the strings given by the tt(-d) option).
|
||||
)
|
||||
item(tt(-J) var(name))(
|
||||
Gives the name of the group of matches the words should be stored in.
|
||||
)
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ struct cmatch {
|
|||
#define CMF_FMULT (1<<12) /* first of multiple equal strings */
|
||||
#define CMF_ALL (1<<13) /* a match representing all other matches */
|
||||
#define CMF_DUMMY (1<<14) /* unselectable dummy match */
|
||||
#define CMF_MORDER (1<<15) /* order by matches, not display strings */
|
||||
|
||||
/* Stuff for completion matcher control. */
|
||||
|
||||
|
|
|
|||
|
|
@ -2735,7 +2735,7 @@ addexpl(int always)
|
|||
static int
|
||||
matchcmp(Cmatch *a, Cmatch *b)
|
||||
{
|
||||
if ((*a)->disp) {
|
||||
if ((*a)->disp && !((*a)->flags & CMF_MORDER)) {
|
||||
if ((*b)->disp) {
|
||||
if ((*a)->flags & CMF_DISPLINE) {
|
||||
if ((*b)->flags & CMF_DISPLINE)
|
||||
|
|
@ -2751,7 +2751,7 @@ matchcmp(Cmatch *a, Cmatch *b)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
if ((*b)->disp)
|
||||
if ((*b)->disp && !((*b)->flags & CMF_MORDER))
|
||||
return 1;
|
||||
|
||||
return strbpcmp(&((*a)->str), &((*b)->str));
|
||||
|
|
|
|||
|
|
@ -569,6 +569,9 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
|
|||
case 'l':
|
||||
dat.flags |= CMF_DISPLINE;
|
||||
break;
|
||||
case 'o':
|
||||
dat.flags |= CMF_MORDER;
|
||||
break;
|
||||
case 'E':
|
||||
if (p[1]) {
|
||||
dat.dummies = atoi(p + 1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue