Клавиатурные привязки в zsh в стиле Vim
Программное обеспечение
Статья была опубликована 1 февраля 2010 года в 00:00, а последний раз правилась 1 февраля 2010 года в 10:46.
Постоянная ссылка: http://www.nixp.ru/articles/60.html
Данная статья посвящена исключительно настройке клавиатурных привязок в zsh в стиле vim. Во избежание повторений общих советов в статье нет.
Примечание: Статья была впервые опубликована в электронном издании «Open Source» (выпуск №019 от 10.08.2007). Ее размещение на nixp.ru производится в соответствии с разрешением со стороны редакции и автора материала.
Предупреждение
Данная статья посвящена исключительно настройке клавиатурных привязок в zsh в стиле vim. Во избежание повторений общих советов в статье нет.
Введение
В одном из обзоров редактора vim я встретил фразу, смысл которой сводится к следующему: очень многое в UNIX основано на подобии, поэтому изучение данного редактора для относительно опытного пользователя не должно представлять трудности. Многие разработчики отталкиваются от этого подобия и делают приложения чем-то похожими либо на vim, либо на emacs, либо на оба редактора. Именно так поступили создатели zsh, предоставив пользователю на выбор четыре схемы «привязок горячих клавиш» для редактора командной строки: emacs, viins, vicmd и .safe (две схемы для vim — для эмуляции разных его режимов).
Я люблю vim и постоянно использую его и только его, под какой бы операционной системой ни оказался — благо его порты есть под самую разнообразную экзотику. И в ходе очередного витка изысканий по настройке zsh было принято решение: для эффективности и унификации использовать схему привязок vim. Однако чувство незаконченности и неудобства не покидало меня. И выход был найден: создать свои схемы привязок на основе уже существующих, воспользовавшись поистине безграничными возможностями настройки zsh.
Создание схем в zsh
Итак, для достижения поставленной цели обработаем файл ~/.zshrc:
- Создадим две схемы на основе существующих (по одной на режим вставки и командный):
#vi insert mode like keybindings #defining something more usable than the defaults vi bindings #creating two keymaps bindkey -N myviins viins bindkey -N myvicmd vicmd
- Исправим досадное недоразумение: zsh никак не отображает текущий режим. Напишем свои переключения:
#defining widgets, to switch between them function my_viins_to_vicmd(){print -n "\033]0;zsh\a";bindkey -A myvicmd main} function my_vicmd_to_viinsi(){print -n "\033]0;zsh INSERT\a";bindkey -A myviins main} function my_vicmd_to_viinsa(){print -n "\033]0;zsh INSERT\a";zle vi-forward-char;bindkey -A myviins main} zle -N my_viins_to_vicmd zle -N my_vicmd_to_viinsi zle -N my_vicmd_to_viinsa bindkey -M myviins '^[' my_viins_to_vicmd bindkey -M myvicmd 'i' my_vicmd_to_viinsi bindkey -M myvicmd 'a' my_vicmd_to_viinsa
Теперь в заголовке эмулятора терминала будет отображаться режим вставки.
- Памятка с текущими привязками:
function list_mappings(){bindkey}; zle -N list_mappings bindkey -M myvicmd ':map' list_mappings
- Сделаем свой режим вставки режимом по умолчанию:
#setting my vi-like insert mode by default bindkey -A myviins main
- Исправим непривычное поведение некоторых клавиш (адаптация общего совета Алексея Федорчука):
#making work some special keys bindkey "\e[2~" yank bindkey "\e[3~" delete-char bindkey "\e[5~" up-line-or-history bindkey "\e[6~" down-line-or-history bindkey "\e[A" up-line-or-search ## up arrow for back-history-search bindkey "\e[B" down-line-or-search ## down arrow for fwd-history-search
#making work Home and End keys in both modes case $TERM in linux) bindkey -M myviins "\e[1~" beginning-of-line bindkey -M myviins "\e[4~" end-of-line bindkey -M myvicmd "^[[1~" beginning-of-line bindkey -M myvicmd "^[[4~" end-of-line ;; *xterm*|rxvt|(dt|k|E)term) bindkey -M myviins "\e[H" beginning-of-line bindkey -M myviins "\e[F" end-of-line bindkey -M myvicmd "\e[H" beginning-of-line bindkey -M myvicmd "\e[F" end-of-line ;; esac
Пример виджета в стиле vim
Ну, и напоследок небольшой пример, показывающий, как писать виджеты («задача виджета — выполнять некое малое действие») в стиле команд vim и привязывать их к клавиатурным сочетаниям.
Иногда возникает потребность быстро заменить один из аргументов в вызове программы:
kill -HUP foobar kill -9 foobar
Это и будет делать виджет в данном примере. Сначала объявляем функцию:
#simple widget, wich deletes N-th parameter (word) in line killparam() { zle beginning-of-line zle vi-forward-word -n ${NUMERIC:-1} zle delete-word -n 1 zle vi-delete-char -n 1 zle my_vicmd_to_viinsi }
Затем провозглашаем ее виджетом:
zle -N killparam
А после этого привязываем к горячей клавише:
bindkey -M myvicmd 'k' killparam
При написании виджета для простоты я использовал только уже готовые виджеты самой zsh, вызывая их с помощью команды zle. Обратите внимание на передачу параметра второму из них: если переменная $NUMERIC не определена, будет передана еденица. Всем остальным виджетам предписано выполняться строго один раз, даже если $NUMERIC задана (-n 1).
Теперь, чтобы удалить -HUP в указанном примере, достаточно в режиме редактирования набрать 1k или просто k (если набрать 2k, то будет удалено второе слово и так далее).
Результаты
Таким образом, я избавился от неинформативности оболочки, странного поведения привычных вещей и научил ее выполнять новые трюки. Как всегда, интересные идеи в этой области я буду рад видеть в своем почтовом ящике.
-
Популярные в этом разделе:
- «Обзор системы фильтрации спама rspamd: возможности, конфигурация, работа»,
- «Защищаем себя средствами GnuPG»,
- «Своё интернет-радио с Icecast».
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1