From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21333 invoked from network); 22 Jan 1999 13:22:42 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 22 Jan 1999 13:22:42 -0000 Received: (from list@localhost) by math.gatech.edu (8.9.1/8.9.1) id IAA20945; Fri, 22 Jan 1999 08:16:36 -0500 (EST) Resent-Date: Fri, 22 Jan 1999 08:16:36 -0500 (EST) Date: Fri, 22 Jan 1999 14:15:26 +0100 (MET) Message-Id: <199901221315.OAA27557@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@math.gatech.edu Subject: Re: experimental new style completion Resent-Message-ID: <"eTwj01.0.C75.qe7gs"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/4949 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu 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@informatik.hu-berlin.de