diff options
-rw-r--r-- | Completion/Base/_brace_parameter | 42 | ||||
-rw-r--r-- | Completion/Base/_parameter | 15 | ||||
-rw-r--r-- | Completion/Core/_parameters | 144 | ||||
-rw-r--r-- | Doc/Zsh/compwid.yo | 8 | ||||
-rw-r--r-- | Src/Zle/comp.h | 7 | ||||
-rw-r--r-- | Src/Zle/compctl.c | 3 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 31 |
7 files changed, 151 insertions, 99 deletions
diff --git a/Completion/Base/_brace_parameter b/Completion/Base/_brace_parameter index 4a91dde73..2bf7b6a6d 100644 --- a/Completion/Base/_brace_parameter +++ b/Completion/Base/_brace_parameter @@ -1,25 +1,31 @@ #compdef -brace-parameter- -setopt localoptions extendedglob +_parameters -e -local lp ls n q -if [[ "$SUFFIX" = *\}* ]]; then - ISUFFIX="${SUFFIX#*\}}$ISUFFIX" - SUFFIX="${SUFFIX%%\}*}" - suf=() -elif [[ "$LBUFFER" = *\$\{[^}]#\$\{[^}]#$PREFIX || - "$compstate[insert]" = *menu* ]]; then - suf=(-b '') -else - suf=(-b ' ') -fi +# Without the `-e' option, we would use the following (see the file +# Core/_parameters for more enlightenment). -lp="$LBUFFER[1,-${#PREFIX}-1]" -ls="$RBUFFER[${#SUFFIX}+1,-1]" -n=${(M)#ls##\"#} -q=${(M)lp%%\"#} +# setopt localoptions extendedglob -[[ n -gt 0 ]] && suf='' +# local lp ls n q -_parameters "$suf[@]" -Qs "${q[1,-n-1]}" -r '-:?#%+=[/}' +# if [[ "$SUFFIX" = *\}* ]]; then +# ISUFFIX="${SUFFIX#*\}}$ISUFFIX" +# SUFFIX="${SUFFIX%%\}*}" +# suf=() +# elif [[ "$LBUFFER" = *\$\{[^}]#\$\{[^}]#$PREFIX || +# "$compstate[insert]" = *menu* ]]; then +# suf=(-b '') +# else +# suf=(-b ' ') +# fi + +# lp="$LBUFFER[1,-${#PREFIX}-1]" +# ls="$RBUFFER[${#SUFFIX}+1,-1]" +# n=${(M)#ls##\"#} +# q=${(M)lp%%\"#} + +# [[ n -gt 0 ]] && suf='' + +# _parameters "$suf[@]" -Qs "${q[1,-n-1]}" -r '-:?#%+=[/}' diff --git a/Completion/Base/_parameter b/Completion/Base/_parameter index aa9e3ce01..1ede49e27 100644 --- a/Completion/Base/_parameter +++ b/Completion/Base/_parameter @@ -1,7 +1,12 @@ #compdef -parameter- -if [[ "$compstate[insert]" = *menu* ]]; then - _parameters -s '' -else - _parameters -s ' ' -fi +_parameters -e + +# Without the `-e' option, we would use the following (see the file +# Core/_parameters for more enlightenment). + +# if [[ "$compstate[insert]" = *menu* ]]; then +# _parameters -s '' +# else +# _parameters -s ' ' +# fi diff --git a/Completion/Core/_parameters b/Completion/Core/_parameters index 0fd6585a2..34a8c3e9b 100644 --- a/Completion/Core/_parameters +++ b/Completion/Core/_parameters @@ -2,76 +2,94 @@ # This should be used to complete parameter names if you need some of the # extra options of compadd. It completes only non-local parameters. + +setopt localoptions extendedglob + +local pars expl + +_description expl parameter + +if zmodload -e parameter; then + pars=( ${(k)parameters[(R)^*local*]} ) +else + pars=( ${${${(f)"$(typeset +)"}:#*local *}##* } ) +fi + +compadd "$expl[@]" "$@" - $pars + + + +# The `-e' option does everything for parameter expansions of us. If +# we wouldn't have it, we would use something like: + # If the first argument is `-s' or `-b' auto_param_slash will be tested # and slashes will be added to parameters containing a directory. `-s' is # for parameter expansions without braces and `-b' is for expansions with # braces. A `-' as the first argument is ignored and in all cases all # other arguments will be given to `compadd'. +# setopt localoptions extendedglob -setopt localoptions extendedglob +# local pars expl slash suf -local pars expl slash suf - -if [[ "$1" = -s ]]; then - slash=normal - suf="$2" - shift 2 -elif [[ "$1" = -b ]]; then - slash=brace - suf="$2" - shift 2 -elif [[ "$1" = - ]]; then - shift -fi +# if [[ "$1" = -s ]]; then +# slash=normal +# suf="$2" +# shift 2 +# elif [[ "$1" = -b ]]; then +# slash=brace +# suf="$2" +# shift 2 +# elif [[ "$1" = - ]]; then +# shift +# fi -_description expl parameter +# _description expl parameter -if [[ -n "$slash" && -o autoparamslash ]]; then - local i dirs nodirs ret=1 - - dirs=() - nodirs=() - - if zmodload -e parameter; then - setopt localoptions extendedglob - nodirs=( ${(k)parameters[(R)undefined]} ) - pars=( ${(k)parameters[(R)^*(local|undefined)*]} ) - else - nodirs=( ${${(M)${(f)"$(typeset +)"}:#undefined *}##* } ) - pars=( ${${${(f)"$(typeset +)"}:#*(local|undefined) *}##* } ) - fi - - for i in $pars; do - if [[ -d "${(P)i}" ]]; then - dirs=( $dirs $i ) - else - nodirs=( $nodirs $i ) - fi - done - - if [[ "$slash" = normal ]]; then - compadd -S "/${suf%% #}" -r ' [/:' "$expl[@]" "$@" - $dirs && ret=0 - compadd -S "$suf" -r ' [:' "$expl[@]" "$@" - $nodirs && ret=0 - elif [[ "$slash" = brace ]]; then - compadd -S "}/${suf%% #}" -r '-:?#%+=[/}' "$expl[@]" "$@" - $dirs && ret=0 - compadd -S "}$suf" -r '-:?#%+=[/}' "$expl[@]" "$@" - $nodirs && ret=0 - fi - - return ret -else - if zmodload -e parameter; then - setopt localoptions extendedglob - pars=( ${(k)parameters[(R)^*local*]} ) - else - pars=( ${${${(f)"$(typeset +)"}:#*local *}##* } ) - fi - - if [[ "$slash" = normal ]]; then - compadd -S "$suf" -r ' [:' "$expl[@]" "$@" - $pars - elif [[ "$slash" = brace ]]; then - compadd -S "}$suf" -r '-:?#%+=[/}' "$expl[@]" "$@" - $pars - else - compadd "$expl[@]" "$@" - $pars - fi -fi +# if [[ -n "$slash" && -o autoparamslash ]]; then +# local i dirs nodirs ret=1 + +# dirs=() +# nodirs=() + +# if zmodload -e parameter; then +# setopt localoptions extendedglob +# nodirs=( ${(k)parameters[(R)undefined]} ) +# pars=( ${(k)parameters[(R)^*(local|undefined)*]} ) +# else +# nodirs=( ${${(M)${(f)"$(typeset +)"}:#undefined *}##* } ) +# pars=( ${${${(f)"$(typeset +)"}:#*(local|undefined) *}##* } ) +# fi + +# for i in $pars; do +# if [[ -d "${(P)i}" ]]; then +# dirs=( $dirs $i ) +# else +# nodirs=( $nodirs $i ) +# fi +# done + +# if [[ "$slash" = normal ]]; then +# compadd -S "/${suf%% #}" -r ' [/:' "$expl[@]" "$@" - $dirs && ret=0 +# compadd -S "$suf" -r ' [:' "$expl[@]" "$@" - $nodirs && ret=0 +# elif [[ "$slash" = brace ]]; then +# compadd -S "}/${suf%% #}" -r '-:?#%+=[/}' "$expl[@]" "$@" - $dirs && ret=0 +# compadd -S "}$suf" -r '-:?#%+=[/}' "$expl[@]" "$@" - $nodirs && ret=0 +# fi + +# return ret +# else +# if zmodload -e parameter; then +# pars=( ${(k)parameters[(R)^*local*]} ) +# else +# pars=( ${${${(f)"$(typeset +)"}:#*local *}##* } ) +# fi + +# if [[ "$slash" = normal ]]; then +# compadd -S "$suf" -r ' [:' "$expl[@]" "$@" - $pars +# elif [[ "$slash" = brace ]]; then +# compadd -S "}$suf" -r '-:?#%+=[/}' "$expl[@]" "$@" - $pars +# else +# compadd "$expl[@]" "$@" - $pars +# fi +# fi diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo index 2497eb768..6fbd3ca15 100644 --- a/Doc/Zsh/compwid.yo +++ b/Doc/Zsh/compwid.yo @@ -366,7 +366,7 @@ otherwise. ) findex(compadd) cindex(completion widgets, adding specified matches) -xitem(tt(compadd) [ tt(-qQfnUam) ] [ tt(-F) var(array) ]) +xitem(tt(compadd) [ tt(-qQfenUam) ] [ 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) ]) @@ -486,6 +486,12 @@ characters describing the types of the files in the completion lists will be shown. This also forces a slash to be added when the name of a directory is completed. ) +item(tt(-e))( +This flag can be used to tell the completion code that the matches +added are parameter names for a parameter expansion. This will make +the tt(AUTO_PARAM_SLASH) and tt(AUTO_PARAM_KEYS) options be used for +the matches. +) item(tt(-W) var(file-prefix))( This option has the same meaning as for the tt(compctl) and tt(compgen) builtin commands. Here, however, only one string may be diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index ab8d62c8a..034410f3a 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -226,9 +226,10 @@ struct cmatch { #define CMF_FILE 1 /* this is a file */ #define CMF_REMOVE 2 /* remove the suffix */ -#define CMF_PARBR 4 /* paramter expansion with a brace */ -#define CMF_PARNEST 8 /* nested paramter expansion */ -#define CMF_NOLIST 16 /* should not be listed */ +#define CMF_ISPAR 4 /* is paramter expansion */ +#define CMF_PARBR 8 /* paramter expansion with a brace */ +#define CMF_PARNEST 16 /* nested paramter expansion */ +#define CMF_NOLIST 32 /* should not be listed */ /* Stuff for completion matcher control. */ diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 92e0b4e25..942a289f6 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -1751,6 +1751,9 @@ bin_compadd(char *name, char **argv, char *ops, int func) case 'f': dat.flags |= CMF_FILE; break; + case 'e': + dat.flags |= CMF_ISPAR; + break; case 'F': sp = &(dat.ign); e = "string expected after -%c"; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index ae42c7b8e..374d9578a 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -197,6 +197,10 @@ static int noreal; static char *parpre; +/* Flags for parameter expansions for new style completion. */ + +static int parflags; + /* This is either zero or equal to the special character the word we are * * trying to complete starts with (e.g. Tilde or Equals). */ @@ -812,7 +816,8 @@ check_param(char *s, int set, int test) parq = eparq = 0; /* Save the prefix. */ - if (incompfunc) { + if (compfunc) { + parflags = (br >= 2 ? CMF_PARBR : 0); sav = *b; *b = '\0'; untokenize(parpre = ztrdup(s)); @@ -3801,6 +3806,8 @@ addmatches(Cadata dat, char **argv) Patprog cp = NULL; LinkList aparl = NULL, oparl = NULL, dparl = NULL; + if (dat->flags & CMF_ISPAR) + dat->flags |= parflags; if (compquote && (qc = *compquote)) { if (qc == '`') { instring = 0; @@ -4562,7 +4569,8 @@ docompletion(char *s, int lst, int incmd) cs = origcs; } /* Print the explanation strings if needed. */ - if (!showinglist && validlist && usemenu != 2 && nmatches != 1) { + if (!showinglist && validlist && usemenu != 2 && nmatches != 1 && + (!oldlist || !listshown)) { Cmgroup g = amatches; Cexpl *e; int up = 0, tr = 1, nn = 0; @@ -7751,6 +7759,7 @@ do_single(Cmatch m) { int l, sr = 0, scs; int havesuff = 0; + int partest = (m->ripre || ((m->flags & CMF_ISPAR) && parpre)); char *str = m->str, *ppre = m->ppre, *psuf = m->psuf, *prpre = m->prpre; if (!prpre) prpre = ""; @@ -7799,7 +7808,7 @@ do_single(Cmatch m) /* There is no user-specified suffix, * * so generate one automagically. */ cs = scs; - if (m->ripre && (m->flags & CMF_PARBR)) { + if (partest && (m->flags & CMF_PARBR)) { int pq; /*{{*/ @@ -7815,7 +7824,7 @@ do_single(Cmatch m) if (m->flags & CMF_PARNEST) havesuff = 1; } - if ((m->flags & CMF_FILE) || (m->ripre && isset(AUTOPARAMSLASH))) { + if ((m->flags & CMF_FILE) || (partest && isset(AUTOPARAMSLASH))) { /* If we have a filename or we completed a parameter name * * and AUTO_PARAM_SLASH is set, lets see if it is a directory. * * If it is, we append a slash. */ @@ -7827,11 +7836,14 @@ do_single(Cmatch m) t = 1; else { /* Build the path name. */ - if (m->ripre && !*psuf && !(m->flags & CMF_PARNEST)) { + if (partest && !*psuf && !(m->flags & CMF_PARNEST)) { int ne = noerrs; - p = (char *) zhalloc(strlen(m->ripre) + strlen(str) + 2); - sprintf(p, "%s%s%c", m->ripre, str, + p = (char *) zhalloc(strlen((m->flags & CMF_ISPAR) ? + parpre : m->ripre) + + strlen(str) + 2); + sprintf(p, "%s%s%c", + ((m->flags & CMF_ISPAR) ? parpre : m->ripre), str, ((m->flags & CMF_PARBR) ? Outbrace : '\0')); noerrs = 1; parsestr(p); @@ -7841,7 +7853,8 @@ do_single(Cmatch m) } else { p = (char *) zhalloc(strlen(prpre) + strlen(str) + strlen(psuf) + 3); - sprintf(p, "%s%s%s", (prpre && *prpre) ? prpre : "./", str, psuf); + sprintf(p, "%s%s%s", ((prpre && *prpre) ? + prpre : "./"), str, psuf); } /* And do the stat. */ t = (!(sr = ztat(p, &buf, 0)) && S_ISDIR(buf.st_mode)); @@ -7900,7 +7913,7 @@ do_single(Cmatch m) makesuffix(1); } } - if (minfo.we && m->ripre && isset(AUTOPARAMKEYS)) + if (minfo.we && partest && isset(AUTOPARAMKEYS)) makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq); if ((menucmp && !minfo.we) || !movetoend) { |