From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29521 invoked by alias); 16 Mar 2014 14:23:59 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 18613 Received: (qmail 23497 invoked from network); 16 Mar 2014 14:23:53 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.3.2 Date: Sun, 16 Mar 2014 15:13:17 +0100 From: Eric Smith To: Zsh Users Subject: Re: implementing a control for completing filenames with a defined list of tokens Message-ID: References: <20131202142614.GA27697@trustfood.org> <131202075840.ZM3182@torch.brasslantern.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <131202075840.ZM3182@torch.brasslantern.com> User-Agent: Mutt/1.5.21 (2010-09-15) Thank you Bart. I want to use this completion facility at the start of file (a dir) names and also *in the middle* of the name. So the tags may appear anywhere in the filename. So I could type foobar__^K for example and the function will complete with my tokens which all begin with a double underscore. $ cat tokenfile __job__1403-whatever__ __article__ __finance__ __contract__ __published__ __project-foo__ __job__1402-visit__ How may I adapt your suggestions for this? Thanks a lot. Eric Bart Schaefer wrote on Mon-02-Dec 13 4:58PM > On Dec 2, 3:26pm, Eric Smith wrote: > } Subject: implementing a control for completing filenames with a defined li > } > } I would like to define a completion widget to complete filenames with > } a defined list of tokens. The widget would look up in a list the > } tokens and suggest these (ideally in order) to the user. > > This one is about as straightforward as it's possible to get. > > First you need a function that reads tokenfile and passes the lines > therein as arguments to the "compadd" builtin. > > _tokens() { compadd ${(f)"$( > Next you need a completion widget. There's a ready-made function for > creating completion widgets, called _generic. > > zle -C token-completion complete-word _generic > bindkey ^K token-completion > > (^K is normally kill-line so you might want to pick another binding.) > > Finally tell the completion system that when the token-completer is > invoked, it should use the _tokens function to supply the matches: > > zstyle ':completion:token-completion:*' completer _tokens > > And you're done. If you eventually want it to complete other things, you > can append more functions to the zstyle. > > Another way to do this is to create a file in your $fpath having a name > starting with underscore, and begin that file with a "#compdef -k ..." > line. That could be as simple as this: > > ---- 8< ---- snip ---- 8< ---- > #compdef -k complete-word ^K > > _tokens() { compadd ${(f)"$( _generic _tokens > ---- 8< ---- snip ---- 8< ---- > > However, that will redefine the _tokens function on each completion. A > slightly better formulation would be to have the file redefine the same > function as its file name. If the file is named "_token_completion": > > ---- 8< ---- snip ---- 8< ---- > #compdef -k complete-word ^K > > _tokens() { compadd ${(f)"$( _token_completion() { _generic _tokens } > _token_completion > ---- 8< ---- snip ---- 8< ---- > > It's probably not necessary to go this far when _tokens is so simple, > but if you eventually write something more involved it's a good pattern. > > Note that with the file you don't need the zstyle: passing _tokens as an > argument to _generic has the equivalent effect. You could omit _tokens > there and instead have the style, just replace "token-completion" in the > style pattern with the name of the file. -- Eric Smith