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

Re: compinit causes completion to fail?



On Apr 30,  1:04am, TJ Luoma wrote:
}
} So it went like this:
} 
} * uncomment last file-to-source from within .zshenv
} * start a new shell
} * test to see if command and 'cd' completion worked
} * exit shell (deleting ~/.zcompdump)
} 
} * uncomment last-1 file-to-source from within .zshenv
} * start a new shell
} * test to see if command and 'cd' completion worked
} * exit shell (deleting ~/.zcompdump)
} 
} and so on.

Future hint:  Uncomment half the lines, then try.  If it works, leave
those uncommented and uncomment half the remaining lines.  If it fails,
re-comment half way back to the last place it succeeded.  Repeat.

(Binary search usually takes fewer comparisons than linear search.)

} Everything worked fine UNTIL I put the IFS line in at the top of the
} .zshenv. When I did that, completion broke. When I took it out,
} completion worked.

Did some quick comparison of the output of "setopt xtrace" with IFS=$'\n'
vs. the default.

I wrote:
> IFS shouldn't affect parsing of scripts etc., it should only affect
> "read" and parameter substitution.

Turns out compinit uses "read" to parse #compdef lines while walking
$fpath.  When IFS=$'\n' the entire line is in the first element of
the array, so compdef is run with the wrong arguments.  Then compdef
itself uses "read" to parse bindkey output, etc.

I'm not sure if it's worthwhile to fix this as having IFS=$'\n' during
a whole interactive shell session is likely to cause all sorts of havoc,
but here's a patch anyway.


Index: Completion/compinit
===================================================================
retrieving revision 1.19
diff -u -r1.19 compinit
--- Completion/compinit	20 Dec 2011 17:13:37 -0000	1.19
+++ Completion/compinit	30 Apr 2012 14:28:21 -0000
@@ -326,7 +326,7 @@
         [[ $2 = .menu-select ]] && zmodload -i zsh/complist
 	zle -C "$1" "$2" "$func"
 	if [[ -n $new ]]; then
-	  bindkey "$3" | read -A opt
+	  bindkey "$3" | IFS=$' \t' read -A opt
 	  [[ $opt[-1] = undefined-key ]] && bindkey "$3" "$1"
 	else
 	  bindkey "$3" "$1"
@@ -353,7 +353,7 @@
       # And bind the keys...
       for i; do
         if [[ -n $new ]]; then
-	   bindkey "$i" | read -A opt
+	   bindkey "$i" | IFS=$' \t' read -A opt
 	   [[ $opt[-1] = undefined-key ]] || continue
 	fi
         bindkey "$i" "$func"
@@ -469,7 +469,7 @@
 
 if [[ -f "$_comp_dumpfile" ]]; then
   if [[ -n "$_i_check" ]]; then
-    read -rA _i_line < "$_comp_dumpfile"
+    IFS=$' \t' read -rA _i_line < "$_comp_dumpfile"
     if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files &&
         $ZSH_VERSION = $_i_line[4] ]]
     then
@@ -491,7 +491,7 @@
       _i_name="${_i_file:t}"
       (( $+_i_test[$_i_name] + $_i_wfiles[(I)$_i_file] )) && continue
       _i_test[$_i_name]=yes
-      read -rA _i_line < $_i_file
+      IFS=$' \t' read -rA _i_line < $_i_file
       _i_tag=$_i_line[1]
       shift _i_line
       case $_i_tag in
@@ -527,7 +527,7 @@
 
 # If the default completer set includes _expand, and tab is bound
 # to expand-or-complete, rebind it to complete-word instead.
-bindkey '^i' | read -A _i_line
+bindkey '^i' | IFS=$' \t' read -A _i_line
 if [[ ${_i_line[2]} = expand-or-complete ]] &&
   zstyle -a ':completion:' completer _i_line &&
   (( ${_i_line[(i)_expand]} <= ${#_i_line} )); then

-- 
Barton E. Schaefer



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