Вопрос или проблема
Я хотел бы запустить некоторый код, когда zle становится активным.
Единственный способ, который я знаю, как это сделать:
zle-init-line() {
echo hi
}
zle -N zle-init-line
Но, насколько я знаю, это заменит любые потенциальные существующие хуки zle-init-line
.
Как я могу либо добавить к существующим хукам (как в случае с precmd
, который имеет массив precmd_functions
), либо восстановить предыдущее состояние zle-init-line
после выполнения моей функции?
Вы можете добавить код к существующей функции. Это работает только в простых случаях: например, любое использование return
в существующей функции приведет к тому, что ваш код будет пропущен.
functions[zle-line-init]+='
echo hi
'
Если вам нужно запустить код после кода, который определяет zle-line-init
, не полагаясь на его простоту, вы можете переименовать существующую функцию и вызвать её.
functions[zle-line-init-before-me]=$functions[zle-line-init]
function zle-line-init {
zle-line-init-before-me
echo hi
}
Чтобы сделать это более надежным, структурируйте это как список хуков. Пусть любой существующий код будет одним из элементов списка.
zle_line_init_functions=()
if [[ -v functions[zle-line-init] ]]; then
functions[zle-line-init-before-me]=$functions[zle-line-init]
zle_line_init_functions+=zle-line-init-before-me
fi
function zle-line-init {
local f
for f in $zle_line_init_functions[@]; do
$f $@[@] || return $?
done
}
Ответ или решение
Добавление хуков в Zsh может быть вызвано необходимостью выполнить пользовательский код каждый раз, когда активируется функция zle (Zsh Line Editor). Однако, проблема в том, что использование:
zle-init-line() {
echo hi
}
zle -N zle-init-line
заменяет любые существующие хуки zle-init-line
, что может быть нежелательным. В этой статье мы рассмотрим несколько решений, которые помогут вам добавить новый функционал без замены существующих хуков, сохраняя их в целостности.
Использование простого добавления к существующему хуку
Если вы уверены, что zle-init-line
не использует команду return
, вы можете просто добавить свою команду непосредственно в уже существующий хук:
functions[zle-line-init]+='
echo hi
'
Этот метод прост и эффективен, однако он ограничен: использование return
в существующей функции zle-line-init
приведет к тому, что ваша команда будет пропущена.
Переименование существующей функции и создание новой
Если вам нужно гарантировать, что ваш код будет выполнен после выполнения существующих команд, без зависимости от их структуры, лучше переименовать существующий хук и вызвать его внутри нового хука:
functions[zle-line-init-before-me]=$functions[zle-line-init]
function zle-line-init {
zle-line-init-before-me
echo hi
}
Этот подход позволяет сохранить оригинальный функционал и добавляет ваш собственный код.
Более устойчивый вариант: структура в виде списка хуков
Для более комплексных сценариев хорошим вариантом будет создание списка хуков, который позволяет управлять порядком выполнения функций:
zle_line_init_functions=()
if [[ -v functions[zle-line-init] ]]; then
functions[zle-line-init-before-me]=$functions[zle-line-init]
zle_line_init_functions+=zle-line-init-before-me
fi
function zle-line-init {
local f
for f in "${zle_line_init_functions[@]}"; do
$f "$@" || return $?
done
echo hi # Ваш код
}
В данном примере мы проверяем, существует ли функция zle-line-init
. Если да, мы сохраняем её в новом именованном хуке zle-line-init-before-me
, после чего добавляем его в массив zle_line_init_functions
. Затем, при выполнении нового хука zle-line-init
, мы проходимся по всем функциям в массиве и вызываем их. Ваш собственный код выполняется в конце, обеспечивая выполнение всех предшествующих инструкций.
Заключение
Используя описанные выше методы, вы можете добавить новый код при активации zle
, не заменяя существующие хуки. В зависимости от ваших потребностей, вы можете выбрать наиболее подходящий подход: от простого добавления к более сложной и безопасной структуре с использованием массивов хуков. Применяя эти методы, вы можете гибко управлять функциями вашего окружения Zsh, минимизируя риски нарушения существующего функционала вашей оболочки.