I know that it is possible to display text "outside" of the zsh prompt where you are typing. Common example is completions:

myhost Wed 8 10:06 ~/sandlot 
$ e .py█

Press Tab, et voilá:

myhost Wed 8 10:06 ~/sandlot 
$ e .py█
 -- file --
lenum.py           lexample.py        otherticks.py

What interests me is the text from --file-- below. Is there some kind of "zsh_echo_below_zle" or something. I don't mind about about keyboard or shortcuts, since my intention is to run and use the output in zle. S.a.

myhost Wed 8 10:06 ~/sandlot 
$ some_command $(some_command_with_warning)█

Press Tab, and

myhost Wed 8 10:06 ~/sandlot 
$ some_command some_output█
 -- warning: some_output is about yadda yadda yadada --

1 Answer 1


Inside the ZSH completion system, a custom message upon mashing of tab for a particular argument of a command is possible via the _message function, as shown in this completion script (_foo) for a particular command (foo):

#compdef foo

local curcontext="$curcontext" state

_arguments -C -s \
  '1: :->dofoo' \
  && return 0

case "$state" in
    _message -r " -- warning: lp0 on fire"
    _values "parameters" $(_call_program getparam echo aaa bbb)


% ls $fpath[*]/_foo 2>/dev/null
% rm ~/.zcompdump && exec zsh
% function foo () { echo "$@" }
% foo █
 -- warning: lp0 on fire
aaa  bbb          

(When modifying $fpath to include a custom directory, always do that before the autoload -U compinit && compinit commands.)

However, given a command line of echo $(foo bar)█, the completion _foo is not involved when tab is mashed, as this is a command substitution, and not an autocompletion of foo.

During command substitution, the command being substituted has no indication whether it is being run directly or as a command substitution (there is a special ZSH_EVAL_CONTEXT variable though exporting that only indicates toplevel regardless), and writing to the terminal then restoring the cursor position will be complicated:

% cat awkward 
echo -ne "\e7\n -- warning: lp0 on fire\e[F\e8" >/dev/tty; echo blat
% ./awkward 
% echo $(./awkward)

... though that's hardly perfect, as if the prompt is down at the bottom of the screen, horrible buggy things happen:

% echo -ne "\e[$LINES;0H"
% ./awkward 

blatwarning: lp0 on fire
% echo $(./awkward )
 -- warblat         fire

A more complicated program would need to deal properly with being at the bottom of the terminal, or even use ncurses for portability, and will need to somehow indicate to zsh that any custom line(s) written (may) need to be cleared so the display does not risk being mucked up with the output of a subsequent command. But that's more work.

The zsh code in Src/exec.c does not look like it does anything special for a cmdsubst job, and the preexec hook function is not called for command substitution, either. So I'm really not seeing anything simple for custom below-the-prompt terminal messaging during the execution of a command substitution in zsh.

  • well, the final objective is to press <kbd>tab</kbd> for autocompletion. I used the command output replacemente because I'm familiar with it and I believe that writing auto completer has a steep learning curve. Commented Jun 8, 2016 at 15:33
  • "Outlook's not so good". Ok, then... will have to meddle with the autocompletion system. Thx Commented Jun 9, 2016 at 16:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .