ZSH: делаем второй шаг

В предыдущем посте было немало сказано о вкусностях, которые сулит пользователю Z-Shell. Но та статья имела вводной характер, её призвание — заинтересовать потенциального пользователя любопытными возможностями. Свою задачу она выполнила на целых 200%, поэтому по требованию читателей я расскажу о том, как на практике юзать вкусности zsh.

Обсуждать каждую используемую мной возможность было бы очень долго и довольно скучно — могу поспорить, читателям не терпится перейти от простого чтения к правке своих .zshrc. По этой причине статья будет построена на цитировании наиболее интересных кусков моего конфига с добавлением некоторых пояснений.

Автодополнение

Автодополнение — это то, что чаще всего упоминается в разговоре о zsh. Включить его очень просто:

autoload -Uz compinit && compinit

Поведение этой функции можно конфигурировать очень долго, но т.к. я этим пока не занимался — меня вполне устраивают дефолтные настройки — ничего более подробного я не расскажу.

История

# файл истории
HISTFILE=~/.history
# кол-во команд, хранимых шеллом в текщей сессии
HISTSIZE=10240
# кол-во команд, которые будут сохранены в истории
SAVEHIST=8192
# все работающие копии zsh будут иметь одинаковую историю
# не беспокойтесь — команды вроде «!» (повтор последней команды) будут использовать
#  только историю текущего шелла
setopt SHARE_HISTORY
# при добавлении в историю новой команды все её дупликаты будут удалены, а команда
#  будет помещена в конец
setopt HIST_IGNORE_ALL_DUPS
# не сохранять команды, начинающиеся с пробела
# очень удобно, если вы вынуждены указать в командной строке имя пользователя,
#  пароль или другую конфиденциальную информацию
setopt HIST_IGNORE_SPACE
# команды «history» и «fc» в историю заноситься не будут
setopt HIST_NO_STORE

Приглашение командной строки (prompt)

В ZSH, в отличие от bash’а, prompt’ов два — левый и правый. Лично я считаю очень удачным вариантом такие настройки:

# левое приглашение — «%» для обычного юзера и «#» — для рута
PROMPT="%# "
# правое приглашение — путь к текущей директории (от ~, если вы где-то в домашней
#  директории, или от /, если вы пошли бродить по системе), отображаемый зелёным
#  цветом
RPROMPT="%{$fg[green]%}%~%{$reset_color%}"

Хорошей альтернативой ручному заданию prompt’а является использование promptinit. Откройте zsh и наберите следующее:

% autoload promptinit
% promptinit
% prompt -p

По экрану быстро промелькнёт около 20 вариантов приглашений, которые вы можете использовать. Если какая-то из тем вам понравилась, наберите:

% prompt имя_темы

и тема будет применена. Подтвердить, что вы хотите использовать именно эту тему, можно следующей командой:

% prompt -s имя_темы

Мой zsh (версии 4.3.6) пока что не поддерживает сохранение, но если вы столкнулись с такой же ситуацией — не расстраивайтесь. Вам достаточно самостоятельно закомментировать вышеприведённые PROMPT и RPROMPT (если вы добавили их в конфиг, конечно) и вместо них написать следующее:

autoload -U promptinit && promptinitprompt имя_понравившейся_темы

Алиасы

Казалось бы, алиасы — простая сущность, что же здесь можно было улучшить? Тем не менее, авторы zsh нашли что добавить к привычной функциональности.

В прошлой статье упоминалось автоматическое исправление команд — например, если вы набрали «aptitde install пакет», шелл предложит вам заменить aptitde на aptitude. Иногда эта возможность может обернуться лихом, пытаясь заменить какие-то команды (mc на mv или наоборот). Если такое случается, добавьте соответствующий алиас:

alias mc="nocorrect mc"

Ключевым здесь является слово nocorrect — оно указывает zsh’у ни в коем случае не исправлять «mc».

Вторым расширением алиасов, которое я оценил лишь недавно, являются так называемые суффиксальные алиасы. Они призваны упростить работу с файлами. Рассмотрим пример:

alias -s pdf=evince
alias -s djvu=evince
alias -s fb2=fbless

Думаю, некоторые читатели уже догадались — суффиксальные алиасы служат для установки соответствия между расширениями файлов и программами. Например, теперь мне не надо писать «evince file.pdf» — я набираю только «file.pdf», а суффиксальный алиас «разворачивает» это в «evince file.pdf». Эта штука реально экономит время и силы.

Ещё одним улучшением в алиасах стали глобальные алиасы, но я с ними пока не разбирался, так что просто отошлю вас к заметке muhas’а — он описал всё достаточно подробно. Кстати, именно из этого его поста я узнал про суффиксальные и глобальные алиасы.

Функции

Вот мы и подошли к функциям — довольно обыденной вещи, которую, тем не менее, тоже нафаршировали вкусностями :) Одна из них — это функции precmd и preexec. Первая вызывается перед выводом prompt, вторая — перед выполнением какой-либо команды. Я это использовал для того, чтобы добавлять в заголовок urxvt имя запущенной программы

case $TERM in
  xterm* | rxvt*)
    # precmd вызывается непосредственно перед выводом prompt
    precmd() {
      print -Pn "\e]0;zsh\a"
    }

    # preexec вызывается перед выполнением команды
    # $1 — имя команды (точнее, вся команда со всеми переданными параметрами)
    # sed используется для «отрезания» от команды параметров
    preexec() {
      print -Pn "\e]0;`echo $1 | sed -r 's/^([^[:space:]]+).*/\1/'`\a"
    }
  ;
esac

Определения функций заключены в case, срабатывающий только в иксовых терминалах — если бы эти функции выполнялись в tty, перед выводом приглашения и перед выполнением команды вы получали бы на экране всякую чепуху.

Ещё одна функция, которой я хотел бы с вами поделится — это lcd:

function lcd() {cd "$1" && ls}

Лично мне она экономит довольно много времени, т.к. обычно после перехода в директорию я вызываю ls.

Miscellaneous

Напоследок мне осталось рассказать о всяких незначительных опциях, которые нельзя ни выбросить, ни отнести к какому-то из вышеприведённых разделов.

# переходить в директорию даже если пользователь не ввёл cd в начале, но набрал
#  верный путь
setopt AUTO_CD
# по возможности исправлять команды
setopt CORRECT
# цвета для ls
# при переносе на другую машину не забудьте захватить мой ~/.dir_colors, в котором
#  переопределён цвет для директорий
eval `dircolors ~/.dir_colors`
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
# Включение поддержки выражений вроде «{1-3}» или «{a-d}» — они будут разворачиваться
#  в «1 2 3» и «a b c d» соответственно
setopt BRACECCL
# загрузка системы помощи
# для удобства использования можно добавить алиас help="run-help"
autoload run-help

Требуется сделать небольшое примечание касательно цветов для ls: мой ~/.dir_colors вы можете получить здесь, почитать о том, что же сподвигло меня менять умолчальные настройки — тут.

Собственно, на этом разговор об используемых мною вкусностях zsh можно закончить. Советую заглянуть в блог muhas’а, там довольно много записей с тегом zsh.

P.S. В процессе экспериментов вам обязательно захочется сразу применять изменённый .zshrc. Для этого после редактирования и сохранения изменений вам достаточно набрать в терминале следующее:

source .zshrc

Comments (migrated from Blogger)

On 2009-11-23T14:11:11.602+02:00, virens wrote:

Пост классный и так и тянет попробовать zsh - может, руки и дойдут. Интересно, а zsh перекрывает возможности wicd? Просто как-то мимо меня пролетало, что у zsh есть такая возможность, ибо держать ещё и wicd не очень хочется (работает она криво в плане настройки).
И ещё раз за пост мерси.

P.S. Насчёт заблокированных комментариев - я уже не в первый раз на это налетаю в блоггере: меняем стиль комментов и настройки сбрасываются.

On 2009-11-23T14:54:07.198+02:00, Programmaster wrote:

Пост классный и так и тянет попробовать zsh - может, руки и дойдут.
Ты только время подбирай — а то zsh штука интересная, закопаешься в неё, забыв обо всём на свете :)

Интересно, а zsh перекрывает возможности wicd?
wicd или wcd?
Хотя без разницы — я ни про первое, ни про второе не знаю :) Может быть, как-то пересекаться с wcd zsh и может, а вот с wicd вряд ли.

On 2009-11-24T21:09:05.735+02:00, al31f wrote:

Здорово, спасибо, поставил, попробовал, классная вещь. До этого на стандартном баше сидел, даже не цветном. Правда конфиг из первой части не подошел, по табу сразу меню вылазило, так и не нашел какая строчка за это отвечает, начал с нуля, постепенно добавляя разные вещи. Теперь по одному нажатию на таб показываются варианты, а уже по следующему начинается перебор. Это в стандартном варианте так. Спасибо за статью.

On 2009-11-25T03:36:59.350+02:00, sash-kan wrote:

любители zsh такие любители!
из описанного в этом посте в bash нету только
setopt CORRECT

>по одному нажатию на таб показываются варианты
о, америка!
readline (в котором есть и такое поведение), как бы к слову, используеться не только bash-ем но и:
$ apt-cache rdepends libreadline5 | sed 1,2d | wc -l
282

как говорили классики, учите, граждане, матчасть…

p.s. что это за жестокий редактор постов тут у вас стоит? эта его медвежья услужливость как-нибудь отключается?

On 2009-11-25T18:26:17.587+02:00, al31f wrote:

>о, америка!
Ну да, я знаю, баш показывает варианты. А в баше можно настроить так чтобы по второму нажатию tab начинался перебор вариантов?
И скажем сейчас я набираю unrar , нажимаю таб, а мне снизу сразу список:

e   -- extract files to current directory
l   -- list archive
lb  -- list archive (bare format)
lt  -- list archive (technical format)
p   -- print file to stdout
t   -- test archive files
v   -- verbosely list archive
vb  -- verbosely list archive (bare format)
vt  -- verbosely list archive (technical format)
x   -- extract files with full path
Я конечно не лазил по настройкам баша, но у меня при включенных автодополнениях криво обрабатывал файлы с пробелами и не хотел их дополнять, рассматривая введеное ранее мной как два слова. Символ  ему ничего не говорил.

On 2009-11-25T18:40:46.142+02:00, Programmaster wrote:

из описанного в этом посте в bash нету только setopt CORRECT
Никогда не слышал об общей истории для нескольких сессий, о суффиксальных и глобальных алиасах, AUTO_CD и правом prompt'е в bash. Если и есть, то закопано в какой-то отдельный пакетик — зачем?

Я за последние полтора года стал до жути ленив в плане компов, zsh этой лени очень сильно способствует. На конфиг, части которого выше, я потратил всего день или два, потом ещё несколько раз по часику допиливал, добавляя новые возможности, а теперь вот юзаю себе на радость.

Про редактор ничего не понял. Стандартненький blogspot'овский редактор, ничего особенного… О какой «медвежьей услужливости» речь?

P.S. sash-kan, а расскажите-ка о том же, что и я, но применительно к bash? Это не провокация, мне правда интересно сравнить количество затрачиваемых усилий и качество результата.

On 2009-11-25T19:32:29.770+02:00, al31f wrote:

Тоже настраивал, благодаря статье час-два. И еще, если мне нужно убить процесс mpc123 я набираю kill m, нажимаю таб и мне выдает список из 8 возможных пунктов, процессы, начинающиеся с буквы m. Как такое сделать в баше?
ps А как тут, в комментариях, выделять жирным шрифтом?

On 2009-11-25T19:41:58.776+02:00, Programmaster wrote:

А как тут, в комментариях, выделять жирным шрифтом?
Разрешены html теги b (полужирный) и i (курсив). Пользуйся.

On 2009-11-27T14:22:58.520+02:00, al31f wrote:

Вот первый недостаток zsh, который я обнаружил: не работает cclive, программка, скачивающая видеофайлы с ютуба и подобных сайтов. Почему, не выяснял. Говорит следующее:

$ cclive http://www.youtube.com/watch?v=HEheh1BH34Q
zsh: no matches found: http://www.youtube.com/watch?v=HEheh1BH34Q 

On 2009-11-27T16:14:13.165+02:00, Programmaster wrote:

2 al31f:

ZSH считает URL регулярным выражением и пытается его развернуть. Используй кавычки.

On 2009-11-28T09:54:28.813+02:00, al31f wrote:

А, с кавычками заработало. Привык, что в баше работало и без кавычек, что даже и не подумал об этом.
Спасибо за совет.

On 2009-12-02T19:09:57.539+02:00, Анонимный wrote:

> И еще, если мне нужно убить процесс mpc123 я набираю kill m, нажимаю таб и мне выдает список из 8 возможных пунктов, процессы, начинающиеся с буквы m. Как такое сделать в баше?

RTFM! pkill mpc123

On 2009-12-06T06:34:15.348+02:00, Анонимный wrote:

А как настроить zsh, чтобы он автодополнял по клавише Up из истории команд. Т.е. вводил я предроложим ранее:

#ssh bla@bla
#ssh bla@foo
Мне нужно опять набрать bla@foo, я набираю #bla и начинаю перебирать курсором все команды из истории начинающиеся на #bla. В bash-completistion привык, а в zsh - не знаю как настроить.

On 2009-12-06T14:59:49.781+02:00, Programmaster wrote:

2 Анонимный:

Добавьте в Ваш ~/.zshrc следующую строку:

bindkey ‘^[[A’ up-line-or-search

(источник).

P.S. Кстати, об автодополнении имени хоста для ssh сегодня в RSS упала неплохая заметочка (я, правда, не тестил).

Drop me a line! (wonder where’s the comments form?)