* Menu completion on empty line @ 2016-11-03 7:17 ml 2016-11-06 2:01 ` Bart Schaefer [not found] ` <161105190150.ZM1605__20581.2434120618$1478397817$gmane$org@torch.brasslantern.com> 0 siblings, 2 replies; 5+ messages in thread From: ml @ 2016-11-03 7:17 UTC (permalink / raw) To: Zsh Users Hi gyus, I was thinking having a kind of an action menu for a build directory of a c++ project. If I press the tab key on an empty line and I am in a build directory, which can be detected by a presence of, let's say the makefile file, it would be useful to get a menu with items: clean build rebuild. I could use the tab key to move around these items. If I choose one, it would expand to a particular command, like 'make clean'. Setting anything like that is beyond my current knowledge of zsh. Any help / pointers as to how to do that are appreciated. Thanks, kybu ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Menu completion on empty line 2016-11-03 7:17 Menu completion on empty line ml @ 2016-11-06 2:01 ` Bart Schaefer 2016-11-07 6:22 ` ml [not found] ` <161105190150.ZM1605__20581.2434120618$1478397817$gmane$org@torch.brasslantern.com> 1 sibling, 1 reply; 5+ messages in thread From: Bart Schaefer @ 2016-11-06 2:01 UTC (permalink / raw) To: ml, Zsh Users On Nov 3, 7:17am, ml@kybu.org wrote: } } If I press the tab key on an empty line and I am in a build directory, } which can be detected by a presence of, let's say the makefile file, } it would be useful to get a menu with items: clean build rebuild. I } could use the tab key to move around these items. If I choose one, it } would expand to a particular command, like 'make clean'. As a prelude, there are two problems with this. (1) Completion is VERY single-word-oriented. Anything that completes to something with spaces in it is going to be quoted by default, so you have to jump through even more hoops than usual to make it work. I would recommend avoiding this by creating three aliases alias clean='make clean' alias build='make all' alias rebuild='clean;build' and then use the menu to select those aliases. (2) By default TAB doesn't do anything on an empty command line except insert itself. To fix that, you need: zstyle ':completion::*' insert-tab 'pending=1' With that out of the way ... There are two approaches here: Change the widget invoked by the TAB key, or change the handling for the context of an empty line. The former would let you do the hoop-jumping to insert multiple words as the completion, but the latter is probably what you want to do. To get started, note that with compinit loaded you can always type control-x h to get a description of the current context. If you do that on a blank line, you get: tags in context :completion::complete:-command-:: commands builtins functions aliases suffix-aliases reserved-words jobs parameters (_command_names _autocd) commands (_path_commands _command_names _autocd) jobs (_jobs _command_names _autocd) parameters (_parameters _command_names _autocd) This is telling you that: * the start of an empty line is the special "-command-" context; * there are eight tags recognized in this context; * there are five completion functions that may supply candidate completions for these tags, and which functions use which tags. The important thing in this case is that you would want to change the handling of the -command- context. Here again you have two choices: Replace the default completion function for -command-, or augment one of the existing tags. I'll note at this point that your three aliases show up in the "aliases" tag automatically, and if that were good enough we just stop here. But you want special handling if there's a makefile, so on we go. There is an example in the documentation of supplementing a context. It's found under the fake-always style and discusses the context of the "cd" command. We need to change it to the context we care about. # Create a preferred aliases-make tag for build commands zstyle ':completion::*:-command-::' \ tag-order 'aliases:-make:"build\ commands"' '*' The "*" there in place of "complete" makes this work for other completers, though that's not strictly necessary. The additional '*' in the style definition means that if there is something on the line and it does not match one of those three aliases, you'll get normal completion. Next: # Ignore everything but our three aliases for make zstyle ':completion::*:-command-:*:aliases-make' \ ignored-patterns '*~(clean|build|rebuild)' Now if you press TAB on an empty line, you'll see only your three aliases. To limit it so this happens only when there is a makefile present, we need to use "zstyle -e": # Create a preferred aliases-make tag for build commands # but do so only when there is a makefile in this directory zstyle -e ':completion::*:-command-::' \ tag-order '[[ -f makefile || -f Makefile ]] && reply=("aliases:-make:build\ commands" "*")' And there you have it. -- Barton E. Schaefer ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Menu completion on empty line 2016-11-06 2:01 ` Bart Schaefer @ 2016-11-07 6:22 ` ml 0 siblings, 0 replies; 5+ messages in thread From: ml @ 2016-11-07 6:22 UTC (permalink / raw) To: zsh-users Amazing, thank you. I will try it out. On Sat, Nov 05, 2016 at 07:01:50PM -0700, Bart Schaefer wrote: > On Nov 3, 7:17am, ml@kybu.org wrote: > } > } If I press the tab key on an empty line and I am in a build directory, > } which can be detected by a presence of, let's say the makefile file, > } it would be useful to get a menu with items: clean build rebuild. I > } could use the tab key to move around these items. If I choose one, it > } would expand to a particular command, like 'make clean'. > > As a prelude, there are two problems with this. > > (1) Completion is VERY single-word-oriented. Anything that completes to > something with spaces in it is going to be quoted by default, so you have > to jump through even more hoops than usual to make it work. > > I would recommend avoiding this by creating three aliases > alias clean='make clean' > alias build='make all' > alias rebuild='clean;build' > and then use the menu to select those aliases. > > (2) By default TAB doesn't do anything on an empty command line except > insert itself. To fix that, you need: > > zstyle ':completion::*' insert-tab 'pending=1' > > With that out of the way ... > > There are two approaches here: Change the widget invoked by the TAB > key, or change the handling for the context of an empty line. The > former would let you do the hoop-jumping to insert multiple words as > the completion, but the latter is probably what you want to do. > > To get started, note that with compinit loaded you can always type > control-x h to get a description of the current context. If you do > that on a blank line, you get: > > tags in context :completion::complete:-command-:: > commands builtins functions aliases suffix-aliases reserved-words jobs parameters (_command_names _autocd) > commands > (_path_commands _command_names _autocd) > jobs > (_jobs _command_names _autocd) > parameters > (_parameters _command_names _autocd) > > This is telling you that: > * the start of an empty line is the special "-command-" context; > * there are eight tags recognized in this context; > * there are five completion functions that may supply candidate > completions for these tags, and which functions use which tags. > > The important thing in this case is that you would want to change the > handling of the -command- context. Here again you have two choices: > Replace the default completion function for -command-, or augment > one of the existing tags. > > I'll note at this point that your three aliases show up in the "aliases" > tag automatically, and if that were good enough we just stop here. But > you want special handling if there's a makefile, so on we go. > > There is an example in the documentation of supplementing a context. > It's found under the fake-always style and discusses the context of the > "cd" command. We need to change it to the context we care about. > > # Create a preferred aliases-make tag for build commands > zstyle ':completion::*:-command-::' \ > tag-order 'aliases:-make:"build\ commands"' '*' > > The "*" there in place of "complete" makes this work for other completers, > though that's not strictly necessary. The additional '*' in the style > definition means that if there is something on the line and it does not > match one of those three aliases, you'll get normal completion. Next: > > # Ignore everything but our three aliases for make > zstyle ':completion::*:-command-:*:aliases-make' \ > ignored-patterns '*~(clean|build|rebuild)' > > Now if you press TAB on an empty line, you'll see only your three > aliases. > > To limit it so this happens only when there is a makefile present, we > need to use "zstyle -e": > > # Create a preferred aliases-make tag for build commands > # but do so only when there is a makefile in this directory > zstyle -e ':completion::*:-command-::' \ > tag-order '[[ -f makefile || -f Makefile ]] && > reply=("aliases:-make:build\ commands" "*")' > > And there you have it. > > > > -- > Barton E. Schaefer ^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <161105190150.ZM1605__20581.2434120618$1478397817$gmane$org@torch.brasslantern.com>]
* Re: Menu completion on empty line [not found] ` <161105190150.ZM1605__20581.2434120618$1478397817$gmane$org@torch.brasslantern.com> @ 2016-11-06 3:15 ` Daniel Shahaf 2016-11-06 3:41 ` Bart Schaefer 0 siblings, 1 reply; 5+ messages in thread From: Daniel Shahaf @ 2016-11-06 3:15 UTC (permalink / raw) To: Zsh Users; +Cc: ml Bart Schaefer wrote on Sat, Nov 05, 2016 at 19:01:50 -0700: > alias rebuild='clean;build' Tangent: it would be better to have braces here: alias rebuild='{ clean; build }' This is in order for the alias to behave correctly inside control structures: % alias x='echo foo; echo bar' % repeat 2 x foo foo bar % alias x='{ echo foo; echo bar }' % repeat 2 x foo bar foo bar % ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Menu completion on empty line 2016-11-06 3:15 ` Daniel Shahaf @ 2016-11-06 3:41 ` Bart Schaefer 0 siblings, 0 replies; 5+ messages in thread From: Bart Schaefer @ 2016-11-06 3:41 UTC (permalink / raw) To: Zsh Users; +Cc: ml On Nov 6, 3:15am, Daniel Shahaf wrote: } } Tangent: it would be better to have braces here: } } alias rebuild='{ clean; build }' Sure. It would probably also be better to use "clean && build" ... but kybu never said what "build" or "rebuild" meant to him. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-11-07 6:22 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-11-03 7:17 Menu completion on empty line ml 2016-11-06 2:01 ` Bart Schaefer 2016-11-07 6:22 ` ml [not found] ` <161105190150.ZM1605__20581.2434120618$1478397817$gmane$org@torch.brasslantern.com> 2016-11-06 3:15 ` Daniel Shahaf 2016-11-06 3:41 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).