zsh-users
 help / color / mirror / code / Atom feed
* 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
       [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

* 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

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