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

Re: file completion(?) erases word typed



I think the comment included in the diff is fairly explanatory.  This
change means menu completion sometimes starts earlier than expected
(i.e., on the first or second tab instead of on the second or third)
but that seems preferable to throwing away the set of matches and
starting over at what is probably the wrong place.

It's likely that there are still situations -- probably including
_multi_parts with separators other than "/" -- where this heuristic
fails, but this should catch a lot of common cases (I hope).

If I'm wrong about any of the assertions in that comment, please
point out how the tests could be tweaked.


diff --git a/Completion/Base/Core/_main_complete b/Completion/Base/Core/_main_complete
index c292ce7..01e6eaa 100644
--- a/Completion/Base/Core/_main_complete
+++ b/Completion/Base/Core/_main_complete
@@ -284,6 +284,29 @@ if [[ $compstate[old_list] = keep || nm -gt 1 ]]; then
     fi
   fi
 
+  if [[ "$compstate[insert]" = *unambiguous &&
+	"$compstate[old_list]" != keep &&
+	"$compstate[nmatches]" -gt 1 &&
+	( "$compstate[insert_positions]" != *:* ||
+	  "$compstate[unambiguous_positions]" == 0* ) &&
+	( "$compstate[unambiguous]" == /## ||
+	  "$compstate[unambiguous_cursor]" -lt ${#PREFIX} ) ]]; then
+    #
+    # We have multiple matches but no useful common prefix to show.
+    # This would result in either erasing an existing prefix on the
+    # line, or adding a prefix that breaks subsequent completions.
+    # Instead, forcibly enter menu completion to cycle the matches.
+    #
+    # The above test is heuristic; what we really need to know
+    # is whether compadd -U or -M is going to cause the current
+    # string on the line to be shortened or removed, but that
+    # information isn't present in the user-visible state.  The
+    # test for unambiguous == /## ideally would apply only for
+    # file completion, but there's no way to detect that either.
+    #
+    compstate[insert]=menu
+  fi
+
   if [[ "$compstate[insert]" = *menu* ]]; then
     [[ "$MENUSELECT" = 00 ]] && MENUSELECT=0
     if [[ -n "$_menu_style[(r)no-select*]" ]]; then



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