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

PATCH: a new completer



The hunks in compcore.c fix some problems in the suffix-matching code.

The new completer is `_prefix'. It allows one to try completion with
ignoring the suffix of the word the cursor is on. I.e. if you have
`zsfrob' with the cursor after the `zs' and try completion with
_prefix in your completer list, it will try to complete `zs' and leave 
the suffix alone. What types of completion are to be tried can be set
with a locally used completer style. If that is not set it uses the
global list currently used -- see the manual for examples.

Bye
 Sven

diff -ru ../z.old/Completion/Core/_main_complete Completion/Core/_main_complete
--- ../z.old/Completion/Core/_main_complete	Fri Feb  4 13:32:30 2000
+++ Completion/Core/_main_complete	Fri Feb  4 15:35:42 2000
@@ -20,6 +20,7 @@
 unsetopt markdirs globsubst shwordsplit nounset ksharrays
 
 local comp post ret=1 _compskip _prio_num=1 format _comp_ignore \
+      _completers _completers_left \
       context state line opt_args val_args curcontext="$curcontext" \
       _last_nmatches=-1 _last_menu_style _def_menu_style _menu_style sel \
       _saved_exact="${compstate[exact]}" \
@@ -63,11 +64,15 @@
 
 # And now just call the completer functions defined.
 
+_completers=( "$@" )
+_completers_left=( "$@" )
+
 for comp; do
   if "$comp"; then
     ret=0
     break;
   fi
+  shift 1 _completers_left
 done
 
 if (( $compstate[nmatches] )); then
diff -ru ../z.old/Completion/Core/_prefix Completion/Core/_prefix
--- ../z.old/Completion/Core/_prefix	Fri Feb  4 15:35:08 2000
+++ Completion/Core/_prefix	Fri Feb  4 15:58:36 2000
@@ -0,0 +1,23 @@
+#autoload
+
+# Try to ignore the suffix. A bit like e-o-c-prefix.
+
+[[ -n "$SUFFIX" ]] || return 1
+
+local curcontext="${curcontext/:[^:]#:/:prefix:}" comp i
+
+zstyle -a ":completion:${curcontext}:" completer comp ||
+  comp=( "${(@)_completers[1,-${#_completers_left}-1][(R)_prefix,-1]}" )
+
+if zstyle -t ":completion:${curcontext}:" add-space; then
+  ISUFFIX=" $SUFFIX"
+else
+  ISUFFIX="$SUFFIX"
+fi
+SUFFIX=''
+
+for i in "$comp[@]"; do
+  [[ "$i" != _prefix ]] && "$i" && return 0
+done
+
+return 1
diff -ru ../z.old/Doc/Zsh/compsys.yo Doc/Zsh/compsys.yo
--- ../z.old/Doc/Zsh/compsys.yo	Fri Feb  4 13:32:10 2000
+++ Doc/Zsh/compsys.yo	Fri Feb  4 15:57:54 2000
@@ -681,6 +681,10 @@
 same as the string on the line, this match will immediately be
 accepted.
 )
+item(tt(add-space))(
+This style is used by the tt(_prefix) completer to decide if a space
+should be inserted before the suffix.
+)
 item(tt(arguments))(
 The value of this style is given to the tt(ps) command by functions
 that call it when generating process identifiers as matches.
@@ -1583,16 +1587,6 @@
 ifzman(the section `Completion System Configuration' above)\
 ifnzman(noderef(Completion System Configuration)).
 )
-findex(_menu)
-item(tt(_menu))(
-This completer is a simple example function implemented to show how
-menucompletion can be done in shell code. It should be used as the
-first completer and has the effect of making the code perform
-menucompletion. Note that this is independent of the setting of the
-tt(MENU_COMPLETE) option and does not work with the other
-menucompletion widgets such as tt(reverse-menu-complete), or
-tt(accept-and-menu-complete).
-)
 findex(_oldlist)
 item(tt(_oldlist))(
 This completer controls how the standard completion widgets behave
@@ -1603,6 +1597,46 @@
 tt(menu), see
 ifzman(the section `Completion System Configuration' above)\
 ifnzman(noderef(Completion System Configuration)).
+)
+findex(_prefix)
+item(tt(_prefix))(
+This completer can be used to try completion with the suffix after the 
+cursor ignored. I.e. the suffix will not be considered to be part of
+the word to complete and hence does not need to be matched. It uses
+the tt(completer) style to decide which other completers to call to
+try to generate matches. If this style is unset, the completers
+currently used by the whole completion are used -- except, of course,
+the tt(_prefix) completer itself. Also, if this completer appears more
+than once in the list of completers to use only those completers not
+already tried by the last invocation of tt(_prefix) will be called.
+
+For example, consider this global tt(completer) style:
+
+example(zstyle ':completion:::::' completer _complete _prefix _correct _prefix)
+
+This makes the tt(_prefix) completer try normal completion with the
+suffix ignored. If that doesn't generate any matches and neither does
+the call to the tt(_correct) completer after it, then tt(_prefix) will 
+be called a second time and will now only try correction with the
+suffix ignored. If you want to use tt(_prefix) as the last resort and
+want it to try only normal completion, you need to do:
+
+example(zstyle ':completion:::::' completer _complete ... _prefix
+zstyle ':completion::prefix:::' completer _complete)
+
+The tt(add-space) style is used, too. If it is set to `true' then
+tt(_prefix) will insert a space between the matches generated (if any) 
+and the suffix.
+)
+findex(_menu)
+item(tt(_menu))(
+This completer is a simple example function implemented to show how
+menucompletion can be done in shell code. It should be used as the
+first completer and has the effect of making the code perform
+menucompletion. Note that this is independent of the setting of the
+tt(MENU_COMPLETE) option and does not work with the other
+menucompletion widgets such as tt(reverse-menu-complete), or
+tt(accept-and-menu-complete).
 )
 enditem()
 
diff -ru ../z.old/Src/Zle/compcore.c Src/Zle/compcore.c
--- ../z.old/Src/Zle/compcore.c	Fri Feb  4 13:32:01 2000
+++ Src/Zle/compcore.c	Fri Feb  4 15:25:40 2000
@@ -1974,21 +1974,12 @@
 	salen += (qisl = strlen(qisuf));
 
     if (salen) {
-	char *asuf = (char *) zhalloc(salen);
 	Cline pp, p, s, sl = NULL;
-	
-
-	if (psl)
-	    memcpy(asuf, psuf, psl);
-	if (isl)
-	    memcpy(asuf + psl, isuf, isl);
-	if (qisl)
-	    memcpy(asuf + psl + isl, qisuf, qisl);
 
 	for (pp = NULL, p = line; p->next; pp = p, p = p->next);
 
-	if (salen > qisl) {
-	    s = bld_parts(asuf, salen - qisl, salen - qisl, &sl);
+	if (psl) {
+	    s = bld_parts(psuf, psl, psl, &sl);
 
 	    if (sline) {
 		Cline sp;
@@ -1998,6 +1989,7 @@
 		for (sp = sline; sp->next; sp = sp->next);
 		sp->next = s;
 		s = sline;
+		sline = NULL;
 	    }
 	    if (!(p->flags & (CLF_SUF | CLF_MID)) &&
 		!p->llen && !p->wlen && !p->olen) {
@@ -2009,7 +2001,7 @@
 		    s->prefix = p->prefix;
 		    p->prefix = NULL;
 		}
-		s->flags |= (p->flags & CLF_MATCHED);
+		s->flags |= (p->flags & CLF_MATCHED) | CLF_MID;
 		free_cline(p);
 		if (pp)
 		    pp->next = s;
@@ -2018,8 +2010,29 @@
 	    } else
 		p->next = s;
 	}
+	if (isl) {
+	    Cline tsl;
+
+	    s = bld_parts(isuf, isl, isl, &tsl);
+
+	    if (sl)
+		sl->next = s;
+	    else if (sline) {
+		Cline sp;
+
+		sline = cp_cline(sline, 1);
+
+		for (sp = sline; sp->next; sp = sp->next);
+		sp->next = s;
+		p->next = sline;
+		sline = NULL;
+	    } else
+		p->next = s;
+
+	    sl = tsl;
+	}
 	if (qisl) {
-	    Cline qsl = bld_parts(asuf + psl + isl, qisl, qisl, NULL);
+	    Cline qsl = bld_parts(qisuf, qisl, qisl, NULL);
 
 	    qsl->flags |= CLF_SUF;
 	    qsl->suffix = qsl->prefix;
@@ -2129,7 +2142,7 @@
 	} else
 	    for (p = lp = cp_cline(pline, 1); lp->next; lp = lp->next);
 
-	if (lp->prefix && !(line->flags & (CLF_SUF | CLF_MID)) &&
+	if (lp->prefix && !(line->flags & CLF_SUF) &&
 	    !lp->llen && !lp->wlen && !lp->olen) {
 	    Cline lpp;
 

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author