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

Re: tab inserts literal tab instead of completing at beginning of line



On May 20, 11:55pm, Mikael Magnusson wrote:
} Subject: Re: tab inserts literal tab instead of completing at beginning of
}
} > Ah, I was in my own little world there, I see more context is needed
} > :). What it does is what I described last in my first message: insert
} > a tab if the line is empty, or contains only tabs (presumably you want
} > to paste more than one sometimes), otherwise completion as usual.
} 
} tl;dr nm this whole thing

OK, but the patch did intend to require that the insert-tab zstyle be
set to the value "empty" in order to create the described effect?

} Hmmm, so I'm confused again. It turns out my patch didn't work as well
} as I hoped. When I press ctrl-n or alt-m, it just inserts those
} literally as well.

That's because the style name assumes tab is the completion character.
Presumably you have ctl-n and alt-m bound to do completion as well?

You're running into a strange combination of effects.  The completion
internals initialize compstate[insert]=tab only when an actual tab is
pressed, but the effect of explicitly assigning compstate[insert]=tab
inside a completion function is to change the final keystroke into a
self-insert.

If you look at the code after line 53 in _main_complete, you'll note
that except for the case of "pending" on lines 45-47, insert-tab has
no effect unless compstate[insert]=tab is already true, i.e., unless
you actually did type a TAB character.

} I tried comparing _complete_debug output for
} insert-tab=false and =true, but they were the same.

This is one of those cases where you can't get useful output from
_complete_debug unless you actually bind it to the TAB key.  There
are a few such.  Here's the important part of the diff (blank lines
added for clarity):

 53> [[ 'tab automenu-unambiguous' == tab* ]]

-54> [[ true == (|[[:blank:]]*)(yes|true|on|1)(|[[:blank:]]*) ]]
-55> [[ ::: != :* || -z '' ]]
-56> return 0

+54> [[ false == (|[[:blank:]]*)(yes|true|on|1)(|[[:blank:]]*) ]]
+58> compstate[insert]=automenu-unambiguous

} ( "$KEYS" = $'\t' && "$tmp" = empty && ${#${BUFFER##$'\t'#}} -eq 0 )

You could do it that way, but the real problem is that you're testing
too early.  You want your test on line 54 for the "return 0" on line 56,
not on line 47 for the assignment to compstate[insert].  See below.

Index: Completion/Base/Core/_main_complete
===================================================================
diff -c -r1.12 _main_complete
--- Completion/Base/Core/_main_complete	21 Dec 2010 16:41:14 -0000	1.12
+++ Completion/Base/Core/_main_complete	23 May 2011 02:24:10 -0000
@@ -51,7 +51,9 @@
 fi
 
 if [[ "$compstate[insert]" = tab* ]]; then
-  { [[ "$tmp" = (|[[:blank:]]*)(yes|true|on|1)(|[[:blank:]]*) ]] &&
+  { [[ "$tmp" = (|[[:blank:]]*)(yes|true|on|1)(|[[:blank:]]*) ||
+	( "$tmp" = (|[[:blank:]]*)empty(|[[:blank:]]*) &&
+	  ${#${BUFFER##$'\t'#}} -eq 0 ) ]] &&
     { [[ "$curcontext" != :* || -z "$compstate[vared]" ]] ||
         zstyle -t ":completion:vared${curcontext}:" insert-tab } } && return 0
 



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