суббота, 21 ноября 2009 г.

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

Копируете статью — поставьте ссылку!

14 комментариев:

virens комментирует...

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

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

Programmaster комментирует...

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

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

al31f комментирует...

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

sash-kan комментирует...

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

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

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

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

al31f комментирует...

>о, америка!
Ну да, я знаю, баш показывает варианты. А в баше можно настроить так чтобы по второму нажатию 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

Я конечно не лазил по настройкам баша, но у меня при включенных автодополнениях криво обрабатывал файлы с пробелами и не хотел их дополнять, рассматривая введеное ранее мной как два слова. Символ \ ему ничего не говорил.

Programmaster комментирует...

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

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

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

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

al31f комментирует...

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

Programmaster комментирует...

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

al31f комментирует...

Вот первый недостаток zsh, который я обнаружил: не работает cclive, программка, скачивающая видеофайлы с ютуба и подобных сайтов. Почему, не выяснял. Говорит следующее:
$ cclive http://www.youtube.com/watch?v=HEheh1BH34Q
zsh: no matches found: http://www.youtube.com/watch?v=HEheh1BH34Q

Programmaster комментирует...

2 al31f:

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

al31f комментирует...

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

Анонимный комментирует...

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

RTFM! pkill mpc123

Анонимный комментирует...

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

Programmaster комментирует...

2 Анонимный:

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

bindkey '^[[A' up-line-or-search

(источник).

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

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.

 
Blogger logo Debian logo Creative Commons License FeedBurner Subscribers Counter