3

If I am at a zsh prompt and I have the current "context" (partially completed command-line command)

% man gr_
        ^ here I have used _ to  represent the cursor 

If I then invoke the _complete_help function CtrlXh

It tells me the context is

% man gr_
tags in context :completion::complete:man::
    manuals  (_man)

If I am reading this output correctly - I can see there is a completer function _man that is capable of listing all the known man pages - which would be invoked if I hit the Tab key at this point.
My question is, can I call the _man completer function manually? rather than having _man being invoked by compsys (which itself is invoked by Tab)?

I have tried using the zle minibuffer <Esc>x , then type _man<Enter> but I think the mini-buffer is only capable of understanding zle commands, not executing general functions.

2

I found that yes its possible and usable for simple completion functions, but because, this particular function _man does some parsing and validation work, it generates an error when invoked outside of its expected context.

Here's what I did to bind the _man completion function to a key combination so it could be invoked manually.

Define a wrapper function that sets the required options.

_man_autonomous () {
  eval $_comp_setup
  _man "$@"
}

Register a new widget with the line editor:

zle -C complete-man expand-or-complete _man_autonomous

bind the widget to Ctrl+T

bindkey '^T' complete-man

There is an example of this technique using _files in the zsh FAQ.

  • The problem was nonexistent manpath entries. Completion functions expect a set of options including null_glob and calling individual functions directly does not set those options. See my edit. – Gilles 'SO- stop being evil' Aug 15 '16 at 20:58
  • @Gilles thanks for that. After running the code you provided, I get no response (no errors either). i.e. after running your code in a zsh terminal, I then type: % man gr<CTRL-T> - gives no response. I also tried running in a zsh shell without sourcing my ~/.zshrc and also using an ordinary widget instead of a completion widget i.e. I used zle -N complete-man _man_autonomous. this produced multiple errors e.g. _man:3: bad math expression: operand expected at == (( - 1...' – the_velour_fog Aug 15 '16 at 21:38
  • Did you press Ctrl+T twice? By default expand-or-complete requires this on an ambiguous prefix. You might have Tab bound to a different widget if you don't usually do that (I have it bound to complete-word). – Gilles 'SO- stop being evil' Aug 15 '16 at 21:43
  • @Gilles pressing CTRL-T twice still causes no response. It would be nice if I could just bind to a normal widget, but from your code it seems that _man_autonomous runs in its own context (own process or subshell) for purposes of constraining its scope (not polluting the main parent shell) - it needs to do the setup produced by eval $_comp_setup AND then _man_autonomous needs to be called with arguments which _man "$@" uses. obviously those arguments are normally provided by the completion system upon invocation. – the_velour_fog Aug 15 '16 at 21:54
  • You can't call a completion function outside of a completion context. I have no idea why this doesn't work for you, it works for me on zsh 5.0.7 both with my own configuration and with a .zshrc that contains only autoload -U compinit; compinit and the code in this answer. Try calling set -x and invoking the widget, and reading through the trace (but the trace may be very long, it can be difficult to locate the problem). – Gilles 'SO- stop being evil' Aug 15 '16 at 22:00
0

I'm not sure why zsh doesn't provide this functionality... Luckily someone made a hack: https://github.com/Valodim/zsh-capture-completion

$ capture.zsh 'man gr'
grep
<snip>
groff
<snip>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.