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

PATCH: moving the cursor in before_complete()



The following patch removes the functionality associated with the
FC_INWORD flag from the completion code. The behaviour it causes has been
annoying me for a while. When you have partial completion that results
in the cursor being moved back, the next time you invoke completion,
the actual visible position of the cursor is ignored and it treats it
as having been at the end.

You can reproduce it as follows:

_users_hosts () {
  local ret=1
  if [[ -prefix *@* ]]; then 
    compadd -M 'r:|@=* r:|=*' -p "user@" host && ret=0 
    compadd -M 'r:|@=* r:|=*' -p "root@" host && ret=0 
  else
    compadd -M 'r:|@=* r:|=*' -s "@host" user root && ret=0
  fi
  return ret
} 
compdef _users_hosts foo
foo @h<tab><tab>

After the first tab, the line is unchanged and the cursor is moved back
before the @ to indicate that there is an ambiguity at that point. The
second time you press tab, the -prefix test fails because the cursor
got moved forward during before_complete. You can examine $CURSOR in
the function and it has been affected.

I've tried to fathom what purpose this originally served. Various things like
repeating partial completions, _prefix, menu completion have crossed my mind
but none seem to fit.

As it is, this does fix an issue so unless someone else has some ideas, I'd
prefer to apply it and wait to see if it breaks something.

Oliver

diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index 3e9834560..de70ce843 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -350,7 +350,6 @@ typedef void (*CLPrintFunc)(Cmgroup, Cmatch *, int, int, int, int);
 /* Flags for fromcomp. */
 
 #define FC_LINE   1
-#define FC_INWORD 2
 
 /* Flags for special parameters. */
 
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index fd415da89..f19e29ac9 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -260,12 +260,9 @@ mod_export LinkList allccs;
 
 /* This says what of the state the line is in when completion is started *
  * came from a previous completion. If the FC_LINE bit is set, the       *
- * string was inserted. If FC_INWORD is set, the last completion moved   *
- * the cursor into the word although it was at the end of it when the    *
- * last completion was invoked.                                          *
+ * string was inserted.                                                  *
  * This is used to detect if the string should be taken as an exact      *
- * match (see do_ambiguous()) and if the cursor has to be moved to the   *
- * end of the word before generating the completions.                    */
+ * match (see do_ambiguous()).                                           */
 
 /**/
 int fromcomp;
@@ -460,6 +457,12 @@ static int oldmenucmp;
 int
 before_complete(UNUSED(Hookdef dummy), int *lst)
 {
+    /*
+     * Currently this hook runs before metafication.
+     * This is the only hook of the three defined here of
+     * which that is true.
+     */
+
     oldmenucmp = menucmp;
 
     if (showagain && validlist)
@@ -478,17 +481,6 @@ before_complete(UNUSED(Hookdef dummy), int *lst)
 	return 1;
     }
 
-    /* We may have to reset the cursor to its position after the   *
-     * string inserted by the last completion. */
-
-    /*
-     * Currently this hook runs before metafication.
-     * This is the only hook of the three defined here of
-     * which that is true.
-     */
-    if ((fromcomp & FC_INWORD) && (zlecs = lastend) > zlell)
-	zlecs = zlell;
-
     /* Check if we have to start a menu-completion (via automenu). */
 
     if (startauto && lastambig &&
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index 05799399d..8ad6bddf0 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -814,10 +814,8 @@ do_ambiguous(void)
 	/* If REC_EXACT and AUTO_MENU are set and what we inserted is an  *
 	 * exact match, we want menu completion the next time round       *
 	 * so we set fromcomp, to ensure that the word on the line is not *
-	 * taken as an exact match. Also we remember if we just moved the *
-	 * cursor into the word.                                          */
-	fromcomp = ((isset(AUTOMENU) ? FC_LINE : 0) |
-		    ((atend && zlemetacs != lastend) ? FC_INWORD : 0));
+	 * taken as an exact match.                                       */
+	fromcomp = (isset(AUTOMENU) ? FC_LINE : 0;
 
 	/* Probably move the cursor to the end. */
 	if (movetoend == 3)



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