From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18224 invoked by alias); 23 May 2011 02:28:20 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 29337 Received: (qmail 17831 invoked from network); 23 May 2011 02:28:17 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received-SPF: none (ns1.primenet.com.au: domain at closedmail.com does not designate permitted sender hosts) From: Bart Schaefer Message-id: <110522192758.ZM718@torch.brasslantern.com> Date: Sun, 22 May 2011 19:27:58 -0700 In-reply-to: Comments: In reply to Mikael Magnusson "Re: tab inserts literal tab instead of completing at beginning of line" (May 20, 11:55pm) References: X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: Zsh hackers list Subject: Re: tab inserts literal tab instead of completing at beginning of line MIME-version: 1.0 Content-type: text/plain; charset=us-ascii 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