Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: experimental new style completion



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