Мой .zshrc с использованием zinit
Zshell - очень крутая оболочка. Возможности её line-editor практически безграничны: тут тебе и поддержка биндов и виджеты. Жаль, что “из коробки” ничего, кроме автокомплита, не увидишь. Приходится настраивать всё самому, дёргая сниппеты из статей добрых людей из интернета. Настало время мне и самому написать небольшой гайд по конфигурации zsh.
Почему не Oh-my-zsh или Pretzo?
Если у тебя стоит сборка oh-my-zsh или pretzo, сноси её. Это помойки из скриптов, среди которых приблизительно 99% - это алиасы и темы. Zsh способна предложить гораздо больше, а ради кучки алиасов не вижу причин замедлять свой конфиг, тем более что все пакетные менеджеры умеют ставить необходимые вам куски OMZ и Pretzo, если вам что-то особенно понравилось. Лично я не перенес в итоге ни одного скрипта, кроме автокомплита для Docker.
Плагины в zshell
Вообще, строго говоря, в zshell нет такого понятия, как плагин. Это просто .zsh
файлы, которые вы включаете в свой .zshrc
файл командой source
. При желании
можно в пару строк сделать подобие пакетного менеджера, который просто будет
скачивать .zsh файлы по url делать source. Пример такого аскетичного конфига
есть на канале Chris@Machine, если тебе интересно разобраться в zsh ещё глубже.
Я же использую готовый пакетный менджер.
Конфигурация с пакетным менеджером zinit
Первый шаг к нормальному конфигу zshell - установка пакетного менеджера. Как я
указал выше, накидать базовый пакетный менеджер достаточно просто. Поэтому
готовых решений довольно много, сравнение самых известных из них можно
посмотреть здесь. Мой выбор пал на zinit, как достаточно популярный, гибкий и
быстрый. После того как выполнили шаги из introduction, наш .zshrc
файл должен
начинаться с 3 строчек, которые сурсят .zsh файл менеджера, загружают функцию
zinit
, с помощью которой мы будем подключать плагины и добавляет файлы
автокомплита для неё в zsh.
source "$HOME/.local/share/zinit/zinit.git/zinit.zsh" autoload -Uz _zinit (( ${+_comps} )) && _comps[zinit]=_zinit
Простейший пример - prompt
Как известно, все любители командной строки обожают перегруженные промпты с
кучей ненужной информации, чтобы почувствовать себя L33T H4CK3rS
. Пример
установки самого выпендрёжного из них - powerlevel10k - есть в документации
zinit. Я предпочитаю чуть более умеренную geometry. На её примере заодно и
разберу основы синтаксиса zinit. Zinit в простом случае принимает в качестве
координат плагина путь к репозиторию на github в формате <username>/<repo>
.
Другие источники, конечно же, тоже поддерживаются. Zinit сам скачивает
репозиторий и следит за его обновлением.
zinit geometry-zsh/geometry
Теперь промпт должен смениться на минималистичный треугольник:
Модификаторы
Кроме имени репозитория ещё принимается список модификаторов, которые так или
иначе влияют на процесс загрузки плагина. Для того чтобы применить модификаторы
есть два вида синтаксиса на выбор: легаси ice и новенький for. Два модификатора
придётся лепить почти на все плагины - это lucid
, который убирает спам
отладочными сообщениями и light-mode
, который выключает некоторые фичи zinit
типа статистики использования плагина, чтобы грузиться как можно быстрее.
Применю их, используя for синтаксис.
zinit lucid light-mode for \
geometry-zsh/geometry
Fzf - лучший друг zsh
В терминале часто приходится выбирать какие-то опции. Варианты автокомплита,
элементы истории, файлы в директории. Справляться со всем этим помогает fzf -
библиотека для fuzzy search. К примеру, так можно интерактивно выбрать файл по
сочетанию клавиш ctrl+t
.
Установка
Fzf имеет небольшие тонкости в установке, поэтому в zinit есть специальная
конструкция pack
, которая позволяет переиспользовать скрипты установки
популярных плагинов.
zinit pack"default+keys" for fzf
Как включить fzf везде
Для того, чтобы заработали сочетания клавиш ctrl+t
для выбора файла из текущей
директории и ctrl+r
для интерактивного поиска по истории, нужно засурсить
файл, находящийся по пути shell/key-bindings.zsh
в репозитории fzf. В zinit
отдельные файлы можны выбирать модификатором pick'<путь до zsh файла от
корня>'
.
zinit wait lucid for pick'shell/key-bindings.zsh' junegunn/fzf
Во многих туториалах, в том числе и в документации fzf, можно встретить ещё и
предложение включить shell/completions.zsh
чтобы использовать fzf для
автокомплита. Однако для меня лучше подошёл плагин fzf-tab, который лучше
интегрируется со стандартным автокомплитом из zshell.
zinit wait lucid has'fzf' for Aloxaf/fzf-tab
Избранные директории
У меня много проектов, между которыми приходится часто переключаться. Поэтому я
себе поставил плагин для избранных директорий zfm. По сочетанию ctrl+p
открывается fzf с выбором моих избранных директорий.
zinit wait'0a' lucid light-mode for \ pabloariasal/zfm
Интерактивный справочник
Иногда хочется иметь что-то вроде Cmd+Shift+A
в Intellij или Command Palette в
VS Code, чтобы забить “get first line of a file” и не вспоминать что там за
команда head и какие у неё команды. Для этого существует navi - интерактивный
cheatsheet. Ставится он чуть более сложно - нужно выполнить eval после
загрузки скрипта. Это делается модификатором atload
.
zinit wait lucid from"gh-r" as"null" for \ atload'eval "$(navi widget zsh)"' \ denisidoro/navi
Теперь, нажав ctrl+g
вы получите интерактивное окошко куда можно будет вбивать
ваши хотелки и получать готовые сниппеты.
Интерактивный jq
Наконец, для любителей погонять json-ы jq является незаменимой. Однако иногда
хочется интерактивно пощупать json, попробовать разные запросы. Некто reegnz
совместил fzf и jq и получилась очень приятная утилита, которая пайпит результат
только что введённой команды в jq и позволяет фильтровать результат, да ещё и с
автокомплитом полей.
Чтобы заполучить эту красоту, достаточно пары строчек. Обрати внимание на
trackbinds
в сочетании с bindmap"\ej -> ^j"
. Эти модификаторы дают
возможность переопределить биндинги, которые приносит плагин. Например, тут мне
захотелось вызывать jq на ctrl+j
.
zinit wait lucid light-mode trackbinds for \ bindmap"\ej -> ^j" reegnz/jq-zsh-plugin
Автокомплит
Важно: автокомплит нужно загружать до fzf. Не знаю точно, почему
Одно из самых частых изменений в моём конфиге - добавление и удаление completions. При этом каждый публикует сompletions по разному.
Github
Самое простое - если completion лежит на гитхабе. Тогда всё что требуется -
добавить модификатор as'completion'
.
zinit wait lucid for \ as"completion" gradle/gradle-completion
Oh My Zsh
Хотя я и ругал OMZ за его раздутость, всё таки для некоторых программ там есть неплохие комплишены. Благо, zinit имеет специальный синтаксис для загрузки плагинов из репозитория OMZ.
zinit wait lucid for \ as"completion" OMZP::docker/_docker
Локальный сниппет
Иногда комплишен предлагают устанавливать из локального файла. Для этого в zinit
есть специальный модификатор is-snippet
.
zinit wait lucid for \ as"completion" blockf is-snippet "$HOME/.dotfiles/zshell/func/_arc"
zsh-completions
У zsh есть и свой джентельменский набор комплишенов, которым можно воспользоваться при помощи следующей команды.
zinit wait lucid for \ atload"zicompinit; zicdreplay" blockf @zsh-users/zsh-completions
Здесь atload
делает некоторую zsh магию, которую я не берусь обьяснять в этом
посте. Просто копипастишь себе в конфиг и наслаждаешься.
Заключение
На этом, в принципе, всё! Я пробовал разные плагины из списков awesome-zsh-plugins, но показал только те, которыми я реально пользуюсь каждый день. Надеюсь, какие-то плагины покажутся полезными и тебе. Поделись своим .zshrc в комментариях.