Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: experimental new style completion
- X-seq: zsh-workers 4949
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxxx
- Subject: Re: experimental new style completion
- Date: Fri, 22 Jan 1999 14:15:26 +0100 (MET)
The patch below fixes some small bugs in the new style completion
stuff:
- a memory problem due to not copying -P/-S strings
- a problem with the job table (the test for validity was too weak
if there are functions being executed, maybe we should add this
even without this new stuff).
- a problem with resetting compnmatches in the completion wrapper
function (OK, I admit that this was just wrong)
- cond_position() failed too often
This patch also modifies the example file. It now contains some more
useful example functions (while keeping the old example functions
which weren't that interesting). Most importantly it contains a
function showing the use of `compadd': with this function it is easy
to get partial-path completion for almost anything (including what was
previously `-g' patterns).
If you already have played with all this (has anyone?): I changed the
functions `defcomp' and `defpatcomp', they now get the name of the
function/variable as their first arguments and `defcomp' accepts more
than one command name.
Bye
Sven
*** Src/Zle/zle_tricky.c.old Fri Jan 22 12:57:16 1999
--- Src/Zle/zle_tricky.c Fri Jan 22 13:06:24 1999
***************
*** 2776,2783 ****
cm->str = (ms ? ms : s);
cm->ipre = (ipre && *ipre ? ipre : NULL);
cm->ripre = (ripre && *ripre ? ripre : NULL);
! cm->pre = curcc->prefix;
! cm->suf = curcc->suffix;
cm->flags = mflags | isf;
cm->brpl = bpl;
cm->brsl = bsl;
--- 2776,2788 ----
cm->str = (ms ? ms : s);
cm->ipre = (ipre && *ipre ? ipre : NULL);
cm->ripre = (ripre && *ripre ? ripre : NULL);
! if (incompfunc) {
! cm->pre = dupstring(curcc->prefix);
! cm->suf = dupstring(curcc->suffix);
! } else {
! cm->pre = curcc->prefix;
! cm->suf = curcc->suffix;
! }
cm->flags = mflags | isf;
cm->brpl = bpl;
cm->brsl = bsl;
***************
*** 4471,4477 ****
char *j, *jj;
for (i = 0; i < MAXJOB; i++)
! if (jobtab[i].stat & STAT_INUSE) {
int stopped = jobtab[i].stat & STAT_STOPPED;
j = jj = dupstring(jobtab[i].procs->text);
--- 4476,4483 ----
char *j, *jj;
for (i = 0; i < MAXJOB; i++)
! if ((jobtab[i].stat & STAT_INUSE) &&
! jobtab[i].procs && jobtab[i].procs->text) {
int stopped = jobtab[i].stat & STAT_STOPPED;
j = jj = dupstring(jobtab[i].procs->text);
*** Src/Zle/compctl.c.old Fri Jan 22 12:05:17 1999
--- Src/Zle/compctl.c Fri Jan 22 13:55:47 1999
***************
*** 1860,1869 ****
return 1;
else {
char *octxt, *ocmd, *opre, *osuf, *oipre;
! long ocur, onm;
ocur = compcurrent;
- onm = compnmatches;
octxt = dupstring(compcontext);
ocmd = dupstring(compcommand);
opre = dupstring(compprefix);
--- 1860,1868 ----
return 1;
else {
char *octxt, *ocmd, *opre, *osuf, *oipre;
! long ocur;
ocur = compcurrent;
octxt = dupstring(compcontext);
ocmd = dupstring(compcommand);
opre = dupstring(compprefix);
***************
*** 1873,1879 ****
runshfunc(list, w, name);
compcurrent = ocur;
- compnmatches = onm;
zsfree(compcontext);
compcontext = ztrdup(octxt);
zsfree(compcommand);
--- 1872,1877 ----
***************
*** 1976,1985 ****
b += l;
if (e < 0)
e += l;
! t = (b >= 0 && b < l && e >= 0 && e < l && i >= b && i <= e && b <= e);
! if (t && a[1])
restrict_range(b, e);
return t;
}
return 0;
--- 1974,1988 ----
b += l;
if (e < 0)
e += l;
! t = (b >= 0 && e >= 0 && i >= b && i <= e && b <= e);
! if (t && a[1]) {
! if (b > l)
! b = l;
! if (e > l)
! e = l;
restrict_range(b, e);
+ }
return t;
}
return 0;
*** Src/example.old Fri Jan 22 12:08:32 1999
--- Src/example Fri Jan 22 14:04:15 1999
***************
*** 13,33 ****
typeset -A comps
! # These may be used to define completion handlers.
defcomp() {
if [[ $# -eq 1 ]] then
comps[$1]="__$1"
else
! comps[$1]="$2"
fi
}
defpatcomp() {
if [[ ${+patcomps} == 1 ]] then
! patcomps=("$patcomps[@]" "$1 $2" )
else
! patcomps=( "$1 $2" )
fi
}
--- 13,42 ----
typeset -A comps
! # These may be used to define completion handlers. First argument is the
! # name of the function/variable containing the definition, the other
! # arguments are the command names for which this definition should be used.
! # With only one argument the function/variable-name __$1 is used.
defcomp() {
+ local v
+
if [[ $# -eq 1 ]] then
comps[$1]="__$1"
else
! v="$1"
! shift
! for i; do
! comps[$i]="$v"
! done
fi
}
defpatcomp() {
if [[ ${+patcomps} == 1 ]] then
! patcomps=("$patcomps[@]" "$2 $1" )
else
! patcomps=( "$2 $1" )
fi
}
***************
*** 157,168 ****
# Do sub-completion for pre-command modifiers.
! defcomp - __precmd
! defcomp noglob __precmd
! defcomp nocorrect __precmd
! defcomp exec __precmd
! defcomp command __precmd
! defcomp builtin __precmd
__precmd() {
COMMAND="$1"
shift
--- 166,172 ----
# Do sub-completion for pre-command modifiers.
! defcomp __precmd - noglob nocorrect exec command builtin
__precmd() {
COMMAND="$1"
shift
***************
*** 175,192 ****
compsub
}
# Simple default, command, and math completion defined with variables.
! defcomp --default-- __default
! __default=( -f )
! defcomp --command-- __command
__command=( -c )
! defcomp --math-- __math
__math=( -v )
! defcomp --subscr-- __subscr
__subscr() {
compalso --math-- "$@"
# ...probably other stuff
--- 179,295 ----
compsub
}
+ # Utility function for in-path completion.
+ # First argument should be an complist-option (e.g. -f, -/, -g). The other
+ # arguments should be glob patterns, one per argument.
+ # E.g.: files -g '*.tex' '*.texi'
+ # This is intended as a replacement for `complist -f', `complist -/', and
+ # `complist -g ...' (but don't use it with other options).
+ # This function behaves as if you have a matcher definition like:
+ # compctl -M 'r:|[-.,_/]=* r:|=* m:{a-z}={A-Z} m:-=_ m:.=,'
+ # so you may want to modify this.
+
+ pfiles() {
+ local nm str pa pre epre a b c s rest
+
+ setopt localoptions nullglob rcexpandparam globdots extendedglob
+ unsetopt markdirs globsubst shwordsplit nounset
+
+ nm=$NMATCHES
+ if [[ $# -eq 0 ]] then
+ complist -f
+ elif [[ "$1" = -g ]] then
+ complist -g "$argv[2,-1]"
+ shift
+ else
+ complist $1
+ shift
+ fi
+ [[ -nmatches nm ]] || return
+
+ str="$PREFIX*$SUFFIX"
+
+ [[ -z "$1" ]] && 1='*'
+ if [[ $str[1] = \~ ]] then
+ pre="${str%%/*}/"
+ eval epre\=$pre
+ str="${str#*/}"
+ pa=''
+ else
+ pre=''
+ epre=''
+ if [[ $str[1] = / ]] then
+ str="$str[2,-1]"
+ pa='/'
+ else
+ pa=''
+ fi
+ fi
+ str="$str:gs/,/*,/:gs/_/*_/:gs./.*/.:gs/-/*[-_]/:gs/./*[.,]/:gs-*[.,]*[.,]*/-../-:gs.**.*."
+ while [[ "$str" = */* ]] do
+ rest="${str#*/}"
+ a="${epre}${pa}(#l)${str%%/*}(-/)"
+ a=( $~a )
+ if [[ $#a -eq 0 ]] then
+ return
+ elif [[ $#a -gt 1 ]] then
+ c=()
+ s=( $rest$@ )
+ s=( "${(@)s:gs.**.*.}" )
+ for i in $a; do
+ b=( $~i/(#l)$~s )
+ [[ $#b -ne 0 ]] && c=( $c $i )
+ done
+ if [[ $#c -eq 0 ]] then
+ return
+ elif [[ $#c -ne 1 ]] then
+ a="$epre$pa"
+ c=( $~c/(#l)$~s )
+ c=( ${c#$a} )
+ for i in $c; do
+ compadd -p "$pre$pa" -W "$a" -s "/${i#*/}" -f "${i%%/*}"
+ done
+ return
+ fi
+ a=( "$c[1]" )
+ fi
+ a="$a[1]"
+ pa="$pa${a##*/}/"
+ str="$rest"
+ done
+ a="$epre$pa"
+ s=( $str$@ )
+ s=( "${(@)s:gs.**.*.}" )
+ b=( $~a(#l)$~s )
+ compadd -p "$pre$pa" -W "$epre$pa" -f ${b#$a}
+ }
+
+ # Utility function for completing files of a given type or any file.
+ # In many cases you will want to call this one instead of pfiles().
+
+ files() {
+ local nm
+
+ nm=$NMATCHES
+ pfiles "$@"
+
+ [[ $# -ne 0 && -nmatches nm ]] && pfiles
+ }
+
# Simple default, command, and math completion defined with variables.
! defcomp __default --default--
! __default() {
! files
! }
! defcomp __command --command--
__command=( -c )
! defcomp __math --math--
__math=( -v )
! defcomp __subscr --subscr--
__subscr() {
compalso --math-- "$@"
# ...probably other stuff
***************
*** 194,200 ****
# A simple pattern completion, just as an example.
! defpatcomp '*/X11/*' __x_options
__x_options() {
complist -J options -k '(-display -name -xrm)'
}
--- 297,303 ----
# A simple pattern completion, just as an example.
! defpatcomp __x_options '*/X11/*'
__x_options() {
complist -J options -k '(-display -name -xrm)'
}
***************
*** 214,227 ****
exec {f,}print{f,0,} ok prune ls'
compreset
elif [[ -position 1 ]] then
! complist -g '. ..' -/
elif [[ -mcurrent -1 -((a|c|)newer|fprint(|0|f)) ]] then
! complist -f
elif [[ -current -1 -fstype ]] then
complist -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)'
elif [[ -current -1 -group ]] then
! complist -g groups
elif [[ -current -1 -user ]] then
complist -u
fi
}
--- 317,450 ----
exec {f,}print{f,0,} ok prune ls'
compreset
elif [[ -position 1 ]] then
! complist -g '. ..'
! files -g '(-/)'
elif [[ -mcurrent -1 -((a|c|)newer|fprint(|0|f)) ]] then
! files
elif [[ -current -1 -fstype ]] then
complist -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)'
elif [[ -current -1 -group ]] then
! complist -k groups
elif [[ -current -1 -user ]] then
complist -u
+ fi
+ }
+
+ # Various completions...
+
+ defcomp __gunzip gunzip zcat
+ __gunzip() {
+ files -g '*.[gG][z]'
+ }
+
+ defcomp gzip
+ __gzip() {
+ files -g '*~*.[gG][zZ]'
+ }
+
+ defcomp xfig
+ __xfig() {
+ files -g '*.fig'
+ }
+
+ defcomp __make make gmake
+ __make() {
+ complist -s "\$(awk '/^[a-zA-Z0-9][^/ ]+:/ {print \$1}' FS=: [mM]akefile)"
+ }
+
+ defcomp __ps gs ghostview gview psnup psselect pswrap pstops pstruct lpr
+ __ps() {
+ files -g '*([pP][sS]|eps)'
+ }
+
+ defcomp __which which whence
+ __which=( -caF )
+
+ defcomp __rlogin rlogin rsh ssh
+ __rlogin() {
+ if [[ -position 1 ]] then
+ complist -k hosts
+ elif [[ -position 2 ]] then
+ complist -k '(-l)'
+ elif [[ -position 3 && -word 1 artus ]] then
+ complist -k '(puck root)'
+ fi
+ }
+
+ defcomp __dvi xdvi dvips dvibook dviconcat dvicopy dvidvi dviselect dvitodvi dvitype
+ __dvi() {
+ files -g '*.(dvi|DVI)'
+ }
+
+ defcomp __dirs rmdir df du dircmp cd
+ __dirs() {
+ files -/ '*(-/)'
+ }
+
+ defcomp __jobs fg bg jobs
+ __jobs=(-j -P '%?')
+
+ defcomp kill
+ __kill() {
+ if [[ -iprefix '-' ]] then
+ complist -k signals
+ else
+ complist -P '%?' -j
+ fi
+ }
+
+ defcomp __uncompress uncompress zmore
+ __uncompress() {
+ files -g '*.Z'
+ }
+
+ defcomp compress
+ __compress() {
+ files -g '*~*.Z'
+ }
+
+ defcomp __tex tex latex glatex slitex gslitex
+ __tex() {
+ files -g '*.(tex|TEX|texinfo|texi)'
+ }
+
+ defcomp __options setopt unsetopt
+ __options=(-M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o)
+
+ defcomp __funcs unfunction
+ __funcs=(-F)
+
+ defcomp __aliases unalias
+ __aliases=(-a)
+
+ defcomp __vars unset
+ __vars=(-v)
+
+ defcomp __enabled disable
+ __enabled=(-FBwa)
+
+ defcomp __disabled enable
+ __disabled=(-dFBwa)
+
+ defcomp __pdf acroread
+ __pdf() {
+ files -g '*.(pdf|PDF)'
+ }
+
+ defcomp tar
+ __tar() {
+ local nm tf
+ compsave
+
+ tf="$2"
+ nm=$NMATCHES
+ if [[ ( -mword 1 *t*f* || -mword 1 *x*f* ) && -position 3 100000 ]] then
+ complist -k "( $(tar tf $tf) )"
+ compreset
+ elif [[ -mword 1 *c*f* && -position 3 100000 ]] then
+ files
+ compreset
+ elif [[ -mcurrent -1 *f* && -position 2 ]] then
+ files -g '*.(tar|TAR)'
fi
}
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author