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 23 May 2011 04:27, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> 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?

Yeah, I sort of got frustrated by looking at the C code for too long :).

> } 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?

Yeah, I should have spent more time composing this mail. ctrl-n completes
files by mtime and alt-m goes into menu selection. The mail also appears
extra confused because I wrote half of it before finding it is even
handled in the C code.

> 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.

Yeah, all my confusion stems from not knowing where it was actually set.

> } 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.

A tangent, I was just staring at these tests, and the (|[[:blank:]]*)
thing that appears on both sides, shouldn't the asterisk be to the left
of the blank when the thing is to the left of the word? I don't see the
point of looking for a blank space, then random crap, then the word? Ie,
doesn't this
"$tmp" = (|[[:blank:]]*)(yes|true|on|1)(|[[:blank:]]*)
match the value " tralalayes bar" when the intention is to match "tralala
yes bar"? I tested now but I'm too lazy to rewrite, it does do that.

> 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

Yeah, this works, and feels less gross than my version, thanks.

Here's diffs for the wrong * placement,

--- a/Completion/Base/Core/_main_complete
+++ b/Completion/Base/Core/_main_complete
@@ -51,8 +51,8 @@
 fi

 if [[ "$compstate[insert]" = tab* ]]; then
-  { [[ "$tmp" = (|[[:blank:]]*)(yes|true|on|1)(|[[:blank:]]*) ||
-       ( "$tmp" = (|[[:blank:]]*)empty(|[[: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


and against current cvs

--- a/Completion/Base/Core/_main_complete
+++ b/Completion/Base/Core/_main_complete
@@ -51,7 +51,7 @@ if [[ ( "$tmp" = *pending(|[[:blank:]]*) && PENDING -gt 0 ) ||
 fi

 if [[ "$compstate[insert]" = tab* ]]; then
-  { [[ "$tmp" = (|[[:blank:]]*)(yes|true|on|1)(|[[:blank:]]*) ]] &&
+  { [[ "$tmp" = (|*[[:blank:]])(yes|true|on|1)(|[[:blank:]]*) ]] &&
     { [[ "$curcontext" != :* || -z "$compstate[vared]" ]] ||
         zstyle -t ":completion:vared${curcontext}:" insert-tab } } && return 0



-- 
Mikael Magnusson



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