Дата публикации: 29-05-2022

Мой .zshrc с использованием zinit

zshell_hero.png

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

Теперь промпт должен смениться на минималистичный треугольник: zshell1.png

Модификаторы

Кроме имени репозитория ещё принимается список модификаторов, которые так или иначе влияют на процесс загрузки плагина. Для того чтобы применить модификаторы есть два вида синтаксиса на выбор: легаси ice и новенький for. Два модификатора придётся лепить почти на все плагины - это lucid, который убирает спам отладочными сообщениями и light-mode, который выключает некоторые фичи zinit типа статистики использования плагина, чтобы грузиться как можно быстрее. Применю их, используя for синтаксис.

zinit lucid light-mode for \
  geometry-zsh/geometry

Fzf - лучший друг zsh

В терминале часто приходится выбирать какие-то опции. Варианты автокомплита, элементы истории, файлы в директории. Справляться со всем этим помогает fzf - библиотека для fuzzy search. К примеру, так можно интерактивно выбрать файл по сочетанию клавиш ctrl+t. zshell2.gif

Установка

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

zshell3.png

Избранные директории

У меня много проектов, между которыми приходится часто переключаться. Поэтому я себе поставил плагин для избранных директорий 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 и позволяет фильтровать результат, да ещё и с автокомплитом полей. zshell4.gif Чтобы заполучить эту красоту, достаточно пары строчек. Обрати внимание на 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 в комментариях.

Подпишись и обсуждай в Telegram