CITKIT.ru - свободные мысли о свободном софте
Деловая газета CitCity.ru Библиотека CITForum.ru Форумы Курилка
Каталог софта Движение Open Source Дискуссионный клуб Дистрибутивы Окружение Приложения Заметки Разное
22.05.2017

Последние комментарии

ОСТОРОЖНО: ВИНДОФИЛИЯ! (2250)
24 December, 22:53
Kubuntu Feisty (15)
24 December, 18:42
Один на один с Windows XP (3758)
24 December, 11:46

Каталог софта

Статьи

Дискуссионный клуб
Linux в школе
Open Source и деньги
Open Source и жизнь
Windows vs Linux
Копирайт
Кто такие анонимусы
Лицензии
Нетбуки
Нужен ли русский Linux?
Пользователи
Дистрибутивы
Идеология
Выбор дистрибутива
Archlinux & CRUX
Debian
Fedora
Gentoo
LFS
LiveCD
Mandriva
OpenSolaris
Slackware
Zenwalk
Другие линуксы
BSD
MINIX
Движение Open Source
История
Классика жанра
Окружение
shell
Библиотеки UI
Графические среды
Шрифты
Приложения
Безопасность
Управление пакетами
Разное
Linuxformat. Колонки Алексея Федорчука
Заметки
Блогометки
Файловые системы
Заметки о ядре

Приложения

Vim-2 или "что может быть проще?"

1 версия - 13.09.2001

Заметка с размышлениями о vim, опубликованная 04.09.2001 (см. также), имела некоторый резонанс, в связи с чем разговор об этом мощном редакторе хочется продолжить. Парадоксально, но, признав некоторую сложность vim в прошлый раз, сейчас я попытаюсь обосновать утверждение о его исключительной простоте. Парадокса, собственно, никакого и нет: все зависит от того, с чьей позиции смотреть. Для пользователя, только что загрузившего дистрибутив vim, он действительно сложен. Достаточно сказать, что в файле index.txt свыше 1200 строк, а ведь этот файл - всего лишь перечень доступных команд с краткими описаниями в одно, максимум два предложения. 1000, пусть 500 команд не способствуют желанию познакомиться с редактором. Не будем торопиться. Во-первых, команды довольно часто дублируются. Во-вторых, часть из них унаследована от vi и предполагает возможность ввода на любом алфавитно-цифровом терминале. Современному пользователю более естественным покажется использование функциональных клавиш и клавиш позиционирования курсора, мыши, наконец. Все эти возможности vim, разумеется, поддерживает, но и старые варианты набора команд не отменяются. Список сокращается: предположим, до 150 команд. Не так уж и много для редактора, который может "все" (уточнять и в этот раз не будем), но есть ли основания говорить об "исключительной простоте"? Как это ни странно, есть. И основания эти следующие:

  • логика интерфейса, заложенная авторами, позволяет свести все многообразие команд к сочетаниям значительно меньшего числа их "составляющих";
  • исключительная модифицируемость vim дает возможность создавать "проблемно-ориентированные", при желании - очень простые конфигурации;
  • гибкая система помощи, которую, кстати, можно дополнять самостоятельно и на любом языке;
  • если же потребуется конфигурация, воспользоваться которой можно сразу, не обременяя себя знакомством с документацией, то можно воспользоваться возможностью создания меню, которая у vim тоже есть.

Таким образом сконфигурированный, документированный и дополненный системой меню vim становится "образцом дружественности" к пользователю. Вас что-то не устраивает? Cделайте так, как считаете более удобным! Для этого не нужно обладать какими-то специальными знаниями, но что-то ДЕЛАТЬ - действительно нужно. Здесь придется еще раз признать (и напомнить), что vim написан программистами и для программистов. Но поскольку ряды последних все ширятся, то и круг пользователей также должен расширяться. Если это не так, то, возможно, и потому, что вышеупомянутые более чем 1000 строк одного перечисления команд кого-то "оттолкнули" при знакомстве. Именно на этого кого-то и ориентирован данный материал.

Для начала стоит объяснить, зачем все-таки нужно такое количество команд, если большинство редакторов вполне обходится системой меню. Для примера предлагаю взять части текста, выделяемые для выполнения над ними какой-то операции и называемые, как правило, текстовыми объектами. Можно выделять их мышью, как это и делается во многих редакторах: решение универсальное, но крайне не эргономичное - попробуйте выделить абзацев 5-6. В общем случае текстовым объектом может быть символ, слово, предложение, абзац, текст в целом плюс блоки, которые, в свою очередь, могут быть ограничены угловыми, квадратными, фигурными или круглыми скобками (мы ведь говорим о тексте программы). Курсор (или указатель мыши) в момент выбора также может находиться в начале, конце или внутри текстового объекта. Можно, конечно, "метить" начало и конец текстового объекта - но это бывает так утомительно... Согласитесь, также, что меню, отражающие все эти возможности, выглядело бы весьма громоздким. А вот как это сделано в vim: если курсор в начале объекта, то первая буква команды выделения - <a> (add), а если внутри, то <i> (inner). Теперь осталось указать, что является объектом. Вторая буква - <w>, <s>, <p> или <b>. Нетрудно догадаться об их происхождении : word, sentence, paragraph, block. Не ошибетесь, если предположите, что любая из возможных скобок в качестве второго символа команды, означает, что объект - это блок, ограниченный этим типом скобок. Изящно. И просто. А между тем, это без малого три десятка команд в визуальном режиме.

Логика интерфейса такова, что если вы обнаружили какую-то возможность в одном из режимов, то почти наверняка найдете аналогичную в другом. Упомянутые в первой статье <Ctrl-n> и <Ctrl-p>, обеспечивающие в режиме вставки переход к следующему (next) и предыдущему (previous) вариантам автозаполнения, при автозаполнениях работают практически везде. Одни и те же символы в командах, как правило, несут одну и ту же смысловую нагрузку: <i> - идентификатор, <d> - макроопределение, <f> - файл. Поэтому <[i> - найти первое появление идентификатора (фактически - определение переменной), <[d> - то же для макроопределения. Понятие "первое появление" для файла смысла не имеет, поэтому <[f> идентично <gf> и означает открытие для редактирования файла, имя которого находится под курсором. Если тем же i,d,f предшествует <Ctrl-W> (признак window-команд), то результатом будет открытие нового окна (а для файла - и нового буфера) с переходом к определению переменной или макрокоманды. Если команда имеет "соседей по смыслу", то скорее всего они будут вызываться изменением регистра второго (уточняющего) символа. Так, <[I> и <[D> распечатают все строки с данным идентификатором или макропеременной. Те же символы присутствуют в составе <Ctrl-X> (eXtended - расширенного) подрежима режима вставки. Этот подрежим полностью ориентирован на автозаполнение. Нетрудно догадаться, что символы <I>, <D>, <F> в качестве завершающих (после <Ctrl-X-Ctrl>) инициируют автозаполнение имен переменной, макрокоманды и файла соответственно, а <n> и <p>, как и прежде, будут означать следующий и предыдущий варианты автозаполнения.

"Универсальными" могут быть не только последние символы команд, как в предыдущих примерах, но и первые. Прежде всего, это уже упоминавшиеся <Ctrl-X> - первый символ расширенного подрежима вставки, и <Ctrl-W> - первый символ window-команд. Как правило, команда детализируется вторым символом. Кроме уже названных, для window-команд это: <+> - увеличить, <-> - уменьшить, <=> - сделать равными размеры окон, <s> - разделить (split), <c> - закрыть (close), <n> - открыть новое (new), <r> и <R> - поменять местами (rotate) окна. Еще одним "универсальным" символом может быть символ, идентифицирующий именованный буфер или, в соответствии с документацией, регистр. Если помните, комбинация <"x> (где 'x' - любой символ: a-zA-Z0-9%#:-") означает использование регистра с командами <y>,<d>,<p> - копирование, удаление, вставка (yank, delete, paste). Аналогично, <qx> означает переход в режим записи в регистр, а <q> - выход из него. Записываются как символы, так и управляющие последовательности (фактически - команды редактора). Если в регистр записаны команды редактора, то его содержимое можно выполнить командой <@x>. Но это возможно уже только с регистрами a-z. Содержимое регистра можно вставить командой <Ctrl-R>, причем это допустимо как непосредственно в тексте (режим вставки), так и в командном режиме. На этом список символов - "универсальных составляющих" команд - можно считать исчерпанным, но - не исчерпывающим, поскольку есть и уникальные комбинации, не имеющие аналогов в других режимах. Например, <Ctrl-U> в режиме вставки удаляет строку, а <Ctrl-V> позволяет ввести символ посредством ввода его трехзначного десятичного кода. В нормальном режиме <Ctrl-L> перерисовывает экран, <Ctrl-R> отменяет действия undo (<u>), а <Ctrl-A> и <Ctrl-X> инкрементируют или декрементируют число под курсором. Так же уникальны команды поиска и замены, перечисленные в первой статье. <U> в визуальном режиме переводит выделенный фрагмент в верхний регистр, а <u> - в нижний. <~> поменяет регистр для одного символа в нормальном режиме и для выделенного фрагмента - в визуальном.

Некоторые символы сохраняют свое назначение и в командном режиме: <!> - фильтр, <@x> - выполнить содержимое регистра 'x', '<' и '>' - уменьшить и, соответственно, увеличить "отступ" строк. Вообще, командный режим стоит несколько "особняком", поскольку является практически самодостаточным: в нем доступны практически все действия, инициируемые командами остальных режимов, разве что объем ввода будет больше. Зато текст команд достаточно "прозрачен". Например:

:buffer N - перейти к буферу N;
:Print - распечатать;
:set - показать или установить опции.

А количество вводимых символов уменьшается благодаря допустимым сокращениям и уже неоднократно упоминавшемуся автозаполнению. Перечислять эти самые "EX" команды нет смысла - их без малого три сотни, а вот просмотреть этот список - стоит. Хотя бы для того, чтобы знать, какие еще возможности имеет vim. Кроме команд, дублирующих команды других режимов, мы найдем здесь команды управления буферами (==открытыми файлами), меню, "привязкой" команд к клавиатурным последовательностям (map), средства программирования, индексации (tags), управления редактором и многое, многое другое.

Так мы подошли к следующему достоинству vim, обеспечивающему его "простоту" - исключительным возможностям настройки. Прежде всего обратимся к конфигурационному файлу vimrc (для графического режима - gvimrc). На www.vim.org стоит взять vimrc.forall - файл написанный Свеном Гуксом (Sven Guckes) "на все случаи жизни". Файл прекрасно прокомментирован и действительно при некоторых модификациях может устроить многих. Но лучше использовать его как "руководство к действию". Познакомившись для начала с командой map:

map   \\   <C-]>

которая заменяет <Ctrl-]> (переход по ссылке в help (tag)), на более удобную последовательность <\\>, переходим к весьма обширному блоку определения опций (set ...). Автоотступ, автоматическое сохранение копий, размер табуляции и так далее, и так далее: перечисление в рамках статьи представляется невозможным - vimrc.forall имеет объем в 75К. Но одну опцию я все-таки приведу:

set langmap=йцу...ЙЦУ...;qwe...QWE...

Три точки в данном случае означают "все остальные символы на клавиатуре" в нижнем и верхнем регистрах для раскладок ru и us. <;> перед 'qwe' отделяет "подменяемый" набор от "подменяющего". Точку с запятой (в наборе, а не разделяющую) и двойные кавычки нужно исключать (quote) с помощью backslash (\), как обычно. Данная опция делает не нужным переключение раскладки клавиатуры, когда требуется латинский символ в нормальном режиме - несуществующий, как видите, недостаток vim, о котором я писал в первой статье. Спасибо всем указавшим на эту опцию. Что касается Свена Гукса, то, позаботившись о вводе таких необходимых ему умляутов, он действительно не учел нашу привязанность к кириллице - вполне простительно для жителя Берлина.

Следующая секция vimrc.forall научит использовать сокращения - abbreviations. Дело вкуса. Занятно использовать сокращения в качестве "автокорректора" опечаток: aslo->also. Или - записной книжки: Ysnail->Sven Guckes<C-M>Pariser Str. 52<C-M>D-10719 Berlin. Обратите внимание, что сокращению команды abbreviate (ab) могут предшествовать символы <i>, <c> и <un> (insert, command, undo). Как Вы, наверное, догадались, это означает актуальность (действенность) сокращения для режимов вставки и команд или отмену сокращения. Если этот небольшой список мы расширим еще символами <a>, <n>, <o> и <v> (all, normal, operator и visual) - то получим список "универсальных" модификаторов, применимых и к некоторым другим командам, таким, как map и menu. Узнаваемая логика, не правда ли?

Следующая секция 'MAPings' содержит определения привязки команд к определяемым пользователем клавиатурным последовательностям. Вот где истинный простор для "подгонки" vim под Ваши вкусы. Хотите выходить из редактора по <F10>? Пожалуйста:

map    <F10>   :q<CR>
imap   <F10>   <Esc>:q<CR>
cmap   <F10>   <Esc><Esc>:q<CR>

Последние две команды можно заменить одной: map! <Esc>:q<CR>, но для этого уже нужно знать о существовании map! (map для режимов команд и вставки) Во второй позиции может быть и последовательность символов. Например,

map   <F6>:set number<CR>
map   <F6>:set nonumber<CR>

будет по <F6> включать нумерацию строк, а по <n><F6> - выключать.
Последующие секции, описывающие применение автокоманд для использования vim в качестве почтового клиента, PGP-шифрование и операции с синтаксисом, очень интересны, но уже не имеют отношения к разговору о "простоте" vim.

Вышеизложенное должно было убедить читателя, что "не так страшен vim..." и изучать устрашающих размеров help может быть, и не придется... У меня, во всяком случае, на каком-то этапе знакомства в этим редактором сложилось впечатление, что имей я под рукой 1-2 странички подсказок... А почему - нет? Поскольку по <F1> vim вызывает файл help.txt из каталога $VIMRUNTIME/doc/ (значение $VIMRUNTIME можно уточнить по :set helpfile), почему бы его не "подменить", сохранив оригинальный help.txt и переименовав в help.txt свой файл? Несколько "варварский", но действенный способ. Изящнее будет вставить свой help в существующую систему помощи: путь к персональному help-у удлинится на пару нажатий клавиш, но зато в Вашем распоряжении всегда будут и свой файл и оригинальная система помощи. Не вдаваясь в тонкости работы со ссылками (tags) приведу краткий рецепт:

  • Предположим, Ваш файл называется myhelp.txt. Первой строкой в него вставим что-то вроде: *myhelp.txt* . Текст может быть любым - это всего лишь ссылка, на которую будет позиционироваться система поиска в help-файлах.
  • В файле help.txt, в строке, например, второй (чтобы сразу была видна на экране) вставим указатель. Например: |$MyHelp| . Текст, опять-таки значения не имеет, а символ <$> поставлен на первую позицию лишь затем, что бы наша ссылка оказалась поближе к началу индексного файла tags.
  • В индексный файл tags вносим строку:
    $MyHelp   myhelp.txt   /*myhelp.txt*
    Все элементы строки, надеюсь, понятны: первый - ссылка, второй - имя файла, третий - позиция в этом файле. Файл tags - сортирован по алфавиту и, если не хотите сортировать его заново, строку нужно поместить в соответствующее место. В данном случае между строками, $LANG.... и $VIM...

Готово. Запускаем vim, нажимаем <F1> и переходим по ссылке $MyHelp (<Ctrl-]> - по умолчанию, <\\> - если Вы воспользовались советом Свена, или двойной клик, если предпочитаете мышь).

Ну, а поскольку "эталоном" дружественности интерфейса долгое время считалась система выпадающих меню, то осталось посмотреть, как таковая реализуется в vim. Дистрибутив содержит файл menu.vim, активный по умолчанию только для графической среды. Для появления меню в консольном режиме во все тот же vimrc нужно вставить следующие команды:

source $VIMRUNTIME/menu.vim
set wildmenu
set cpo-=<
set wcm=<C-Z>
map <F9> :emenu <C-Z>


На месте <F9> может быть, разумеется, любая клавиатурная последовательность. Можно иметь личный меню-файл, тогда первая строка должна указывать на него. Меню как меню. Но это - vim, а, значит, его можно модифицировать. Файл menu.vim сравнительно невелик: менее 22К для версии 5.6. Часть его составляют функции, собственно и обеспечивающие функционирование системы меню. Поскольку программирование в vim нас на настоящий момент не интересует, то обратим внимание только на блоки, первым словом строк которых является команда menu с предшествующими ей уже известными модификаторами <a>, <c>, <i>, <n>, <o> и <v> в соответствии с существующими режимами. Плюс tmenu - для организации всплывающих подсказок (tooltips) в графической среде. Обычно строка такого блока выглядит следующим образом:

amenu  mp;File.&Close<Tab>:q  :confirm q<CR>

Элементы строки разделяются пробелами. В данном случае первый из них, amenu - команда, обеспечивающая появление данной позиции меню во всех (all) режимах. Второй - число, часть до точки которого определяет позицию в главном (горизонтальном), а после точки - в выпадающем (вертикальном) меню. Подобным образом лексемы до и после точки третьего элемента строки представляют собой текстовое содержание позиции меню. Пробелы и точки в составе этих лексем исключаются (quote) с помощью обратной косой черты (backslash). Допустим только один служебный символ - <Tab>. Ведущим (hot) символам в составе лексем предшествует амперсенд (&). Четвертый элемент - собственно команда, которую нужно выполнить. Просто и эффективно. Если команда предполагает редактирование или если Вам требуется дополнительный контроль над командами - не завершайте строки <CR>. Фактически, система меню просто вводит за вас необходимую "EX"-команду.

Таким образом vim может обретести интерфейс, проще которого (при заданном уровне функциональности) уже не будет. Все желаемые усовершенствования Вы можете сделать сами. Средств для этого - достаточно. Не стану утверждать, что путь к этой "простоте" так уж, извините за тавтологию, прост, но "нет ничего ценнее хорошего инструмента". В том числе и для программиста.

Многих возможностей vim, кстати, ни, первая ни вторая статья даже не касались. Вне рассмотрения остались интеграция с Perl и Python, программирование пользовательских функций, форматирование текста и многие другие темы, достойные отдельного обсуждения.





Новости:

Все новости на CitCity.ru

Компании месяца

 
Последние комментарии
Почему школам следует использовать только свободные программы (101)
20 Декабрь, 14:51
ОСТОРОЖНО: ВИНДОФИЛИЯ! (2250)

24 Декабрь, 22:53
Linux в школе: мифы про школу и информатику (334)
24 Декабрь, 22:43
Kubuntu Feisty (15)
24 Декабрь, 18:42
Software is like sex: it's better when it's free.
©Linus Torvalds