В системе завершения ZSH пользовательское сообщение при нажатии tab для определенного аргумента команды возможно через функцию _message
, как показано в этом скрипте завершения (_foo
) для определенной команды (foo
):
#compdef foo
local curcontext="$curcontext" state
_arguments -C -s \
'1: :->dofoo' \
&& return 0
case "$state" in
dofoo)
_message -r " -- warning: lp0 on fire"
_values "parameters" $(_call_program getparam echo aaa bbb)
;;
esac
Например.
% ls $fpath[*]/_foo 2>/dev/null
/Users/jdoe/.zsh/functions/_foo
% rm ~/.zcompdump && exec zsh
% function foo () { echo "$@" }
% foo █
-- warning: lp0 on fire
aaa bbb
(При изменении $fpath
для включения пользовательского каталога, всегда делайте это перед командами autoload -U compinit && compinit
. )
Однако, если командная строка имеет вид echo $(foo bar)"
, то завершение _foo
будет не задействовано при tab, поскольку это подстановка команды, и не автозавершение foo
.
При подстановке команды подставляемая команда не имеет указания, выполняется ли она напрямую или как подстановка команды (есть специальная переменная ZSH_EVAL_CONTEXT
, хотя экспорт этой переменной указывает только на toplevel
независимо от этого), и запись в терминал с последующим восстановлением позиции курсора будет затруднена:
% cat awkward
#!/bin/zsh
echo -ne "\e7\n -- warning: lp0 on fire\e[F\e8" >/dev/tty; echo blat
% ./awkward
blat
% echo $(./awkward)
... Хотя это вряд ли идеально, поскольку если подсказка находится внизу экрана, происходят ужасные глюки:
% echo -ne "\e[$LINES;0H"
...
% ./awkward
blatwarning: lp0 on fire
% echo $(./awkward )
-- warblat fire
Более сложная программа должна будет правильно работать с нахождением внизу терминала, или даже использовать ncurses
для переносимости, и должна будет как-то указать zsh
, что любая написанная пользовательская строка (строки) должна (могут) быть очищена, чтобы не испортить дисплей выводом последующей команды. Но это дополнительная работа.
Код zsh
в Src/exec.c
не выглядит так, будто он делает что-то особенное для задания cmdsubst
, и функция preexec
hook тоже не вызывается для замены команды. Так что я не вижу ничего простого для пользовательских сообщений терминала ниже экрана во время выполнения подстановки команды в zsh
.