- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF96:Vim
Материал из Linuxformat.
Содержание |
Vim: Введение в основы
Почтенный Vim – любимый редактор многих Linux-профессионалов. Он имеет репутацию трудного в освоении, но стоит трудов, уверяет д-р Крис Браун.
Текстовых редакторов в Linux намного больше, чем вы можете себе представить. Похоже, хотя бы по одному создали каждый человек и его собака. Продукты от собак обычно норовят обнюхивать гнезда на задней панели компьютера, и их, вероятно, лучшеигнорировать, но и без них остается много – emacs, kedit, gedit, kwrite, kate, mousepad, leafpad, fte, joe, jed, nano, pico... список можно продолжить. Но большинство профессионалов Unix и Linux выбирает их общего дедушку, Vi, и его собрата помоложе, Vim. (Vim происходит от «Vi improved» [улучшенный Vi] – это Vi , переписанный в 1991 г. Брэмом Муленаром [Bram Moolenar]. Исходный Vi написал Билл Джой [Bill Joy] в далеком 1976 г. На данном уроке используется Vim, хотя основной набор команд для Vi и Vim одинаков.) Одна из причин популярности Vim – эффективность редактирования даже при отсутствии графического интерфейса: например, если вы перевели машину в однопользовательский режим для профилактики, или это сервер, где не установлен рабочий стол.
Vim не самый простой редактор для изучения – его практически невозможно понять без чтения хоть какой-то документации. Не жди те также мгновенной отдачи. Как преподаватель Linux при переходе к разделу о Vim я вижу в глазах студентов ужас. Один парень сказал мне, что если нужно будет редактировать файлы Unix, он скорее скопирует их на дискету и отредактирует в Windows, чем изучит Vim. Это отвращение к Vim’у позорно, потому что, изучив его, вы будете редактировать текст намного быстрее, чем ранее. Так что стисните зубы, прочитайте учебник и станьте Vim-гением.
Обычно Vim запускается с именем файла в качестве аргумента. Файл открывается для редактирования, если он существует – а если нет, то создается. Так что начнем с команды
vi gpl.txt
Если вы хотите работать с тем же файлом, загрузите себе его копию, используя
wget www.gnu.org/licenses/gpl.txt
Одна из причин трудности изучения Vim и Vi – их режимы работы (некоторые скажут «перебор режимов!»). Другими словами, результат ввода символов зависит от режима, в котором вы находитесь. Например, в командном режиме ввод w вызывает переход на одно слово вперед, а в режиме вставки просто в текст вставляется ‘w’. Режимы и переходы между ними показаны на Рис. 1.
Командный режим
Стартуя, Vim входит в командный режим. Большинство команд – это отдельные символы. Классические команды перемещения курсора в Vi и Vim – h, j, k и l, выполняющие перемещение на один символ влево, вниз, вверх и вправо. Мнемоники тут никакой: они выбраны потому, что это базовые клавиши при печати вслепую, и всегда под руками. (В Vim используются также клавиши-стрелки, но поскольку к ним нужно еще передвинуть руку, получается медленнее.) Большинство команд перемещения курсора могут иметь числовой префикс для повтора команды; так, 5j перемещает на пять строк вниз, а 3w – на три слова вперед. В команде G префикс указывает номер строки: например, 23G перенесет вас на 23-ю строку.
Поиск в тексте при помощи / и ? – это наискорейший способ перемещения по нему. Искомый текст может быть (ограниченным) регулярным выражением, например, /[Ss]oftware будет искать Software и software. Если вы нашли не тот экземпляр нужной строки, продолжайте вводить n для поиска следующего.
Режим вставки
Для добавления текста вы должны перейти в режим вставки. Простейшие команды для этого – i, производящая вставку перед текущей позицией курсора, и a, вставляющая после него. Команды I и A укрупненные версии команд i и a; они производят вставку до и после текущей строки соответственно. Команды o и O создают пустую строку ниже или выше текущей, а затем переходят в режим вставки.
Будучи в режиме вставки, вы можете вставлять что угодно: от одного символа до нескольких строк. Однако в режиме вставки нельзя перемещать курсор или давать любые другие команды редактирования –для этого придется вернуться в командный режим (хотя есть версии, где можно заставить использовать клавиши-стрелки для перемещения курсора даже в режиме вставки).
Имеется лишь один способ вернуться из режима вставки в командный: нажать Esc. Заведите привычку нажимать Esc почаще.
Удаление и изменение текста
Команда x удаляет один символ. Она имеет префикс повтора, так что 6x удаляет шесть символов. Команда d более мощная, и должна сопровождаться командами перемещения курсора, указывающими объем удаляемого текста. Вот как она работает: d, в комбинации с перемещениями курсора, удаляет текст между его начальным и конечным положением. Например, dw удаляет слово, d3w удаляет три слова, d удаляет все до конца строки, d} удаляет все до конца абзаца, а dG удаляет все до конца файла. Имеется также специальная версия команды d – dd, которая удаляет всю строку. Префикс повтора работает и здесь, так что 3dd удалит три строки.
Обождем минутку... не являются ли команды поиска (/ и ?) просто видом перемещения курсора? Можете ли вы использовать их с командой d? Оказывается, можете. Например, d/PUBLIC удалит все до слова PUBLIC (не включая его). Более элегантный пример, d/^[0-9] удалит все до первой строки, начинающейся с цифры. (Когда я преподаю Vim, обычно в этом месте враждебность уступает неохотному признанию силы набора команд.)
Команда с (change [изменить]) работает почти как команда d, за тем исключением, что она к тому же переводит редактор в режим вставки. Так что c3w можно рассматривать как указание «изменить три слова»; и так далее.
Команда u отменяет последние сделанные изменения. Vim поддерживает многоуровневую отмену – каждая u отменяет одно изменение. В исходном Vi она работает не так. Если вы ввели две u, то вторая отменит действие первой!
Режим нижней строки
Режим нижней строки используется для всего, но команда нижней строки, без которой не обойтись – это w для записи отредактированного текста в исходный файл и q для выхода. Из командного режима можно перейти в режим нижней строки, набрав :, так что :wq –стандартный способ записать ваш файл и выйти из редактора. Если вы хотите выйти из редактора без сохранения, используйте :q!. Попозже мы рассмотрим другие команды нижней строки. Вы узнали достаточно, чтобы рулить в Vim по крайней мере на второй скорости, но если вы хотите уметь развить суперскорость и выполнить разворот на месте, читайте дальше...
Операции вырезания и вставки
Vim поддерживает операции вырезания и вставки, используя буфер удалений. Текст, удаляемый вами по команде d, сохраняется в этом буфере и может быть вставлен обратно в новой позиции курсора командой p (положить). Например, переместить текущий абзац в конец файла можно так:
- Перейти к началу текущего абзаца при помощи {
- Удалить абзац командой d}
- Перейти в конец файла командой G
- Вставить удаленный абзац обратно при помощи p
(Сравните-ка эти несколько команд с числом действий мышью, необходимым для выполнения того же действия в редакторе с управлением мышью.)
Копирование и вставка выполняются практически так же, за тем исключением, что вы используете команду y вместо d. Команда y «выдергивает» текст – то есть помещает его в буфер удаления, но на самом деле не удаляет. Как и d, она действует совместно с командами перемещения курсора, так что y2) скопирует два предложения, а 4yy скопирует четыре строки. Например, для дублирования текущей строки, наберите yyp, чтобы скопировать строку и вставить копию ниже.
Становиться круто
Если одного буфера удаления вам мало, то вам будет приятно узнать, что их 26, с именами от ‘a’ до ‘z’. Двойные кавычки используются для указания имени буфера. Например, “t4yy скопирует четыре строки в буфер с именем ‘t’, а “tp вставит содержимое буфера ‘t’. Содержимое именованных буферов сохраняется, пока вы работаете в редакторе или пока вы его не перезапишете. Vim выполняет также «глобальные» подстановки. Допустим, вы решили переделать текст лицензии GPL с американского английского на британский, заменив все слова ‘license’ на ‘licence’. Имеется два способа: ручной и автоматический. Ручной выглядит так:
- Перемещаемся к началу файла командой 1G
- Ищем первое вхождение ‘license’ при помощи /license
- Меняем его на ‘licence’, используя cwlicence<ESC>
- Ищем следующее вхождение при помощи n
- Если вы хотите и его заменить, наберите . (точка). Эта команда повторяет последнее сделанное изменение (в данном случае, команду cw) в текущей позиции курсора
- Продолжайте так по всему файлу, используя n и . для повторения поиска и замены.
Если вы просто хотите заменить ‘license’ на ‘licence’ во всем файле насквозь, без просмотра отдельных изменений, можете использовать команду подстановки нижней строки Vim. Для данного примера она выглядит так:
:1,$s/license/licence/g
Рассмотрим ее поподробнее:
- Команда : переносит нас в режим нижней строки.
- Запись 1,$ указывает диапазон номеров строк. 1 – первая строка, а $ означает последнюю. Если мне необходимо сделать замену только в первых 50-ти строках, я должен буду использовать здесь 1,50.
- Запись s/license/licence – простой пример команды подстановки
- g в конце означает ‘global’; то есть, если указанный текст содержится в строке больше одного раза, то заменить все экземпляры. Vim выдаст число сделанных замен и номера измененных строк.
Опции
Для настройки Vi и Vim могут использоваться десятки изменяемых опций. Те, что я счел наиболее полезными, приведены в Таблице 2, но их намного больше. Для изменения опции следует использовать команду нижней строки set. Некоторые опции являются логическими – они принимают значения только on [включено] или off [выключено]. Например, для изменения опции автоотступа следует ввести :set autoindent (: служит для перехода в режим нижней строки, помните?). Для выключения этой опции введите :set noautoindent. Имена многих опций к тому же имеют сокращения. Например, автоотступ можно укоротить до ‘ai’, так что :set ai и :set noai тоже сработают. Другие опции имеют строковые или числовые значения. Опция shiftwidth, например, указывает количество символьных позиций, используемых для отступа. Ясно, что это числовое значение, устанавливаемое как-то вроде :set shiftwidth=4.
Можно определить «постоянные» значения опций (они будут читаться при каждом запуске Vim), поместив их в файл ~/.vimrc. Например, строка этого файла вида set sw=2 ai запустит Vim в режиме с автоотступом с величиной смещения 2. (Заметим, что в файле .vimrc нет : перед командой set).
Фильтрация
Среди всех возможностей Vim, одна из моих любимых – это возможность обрабатывать текстовые буферы (или любую их часть) при помощи внешнего фильтра Linux.
Фильтрация использует команду !, которая, как и команда d, требует сопутствующих перемещений курсора. Текст между текущей позицией курсора и тем местом, куда он переместится, следуя командам, пропускается через выбранные вами внешние команды, и результат их действия вновь вставляется в текстовый буфер вместо начального содержимого. При использовании команды ! курсор помещается в нижнюю строку, чтобы дать место для ввода команд фильтрации. Более детально о фильтрах я поговорю потом, но пара примеров поможет понять идею.
Фильтр cat, с опцией -n, добавит к выводу номера строк.Последовательность команд 1G!Gcat -n выполнит следующее:
- Перемещение в начало файла (1G)
- Выбор всего файла для фильтрации (!G)
- Указание cat -n в качестве фильтра. (Эта часть команды будет выведена в нижней строке.)
Заметьте, что вставка номеров строк этим способом и в самом деле добавляет их к буферу редактирования. Это не то же самое, что включение нумерации строк при помощи опции :set number, которая просто велит Vim нумеровать строки на экране.
Другой пример: последовательность команд 1G!Gwc запустит wc для всего файла, чтобы выдать нам количество символов, слов и строк. Прочитав это, используйте команду u для отмены изменений и замены вывода команды wc исходным текстом.
Наш третий пример фильтрации использует двойную форму команды ! (!!), для работы с полными строками, и использует grep и подходящее регулярное выражение для фильтрации пустых строк. Вот команда: 10!!grep -v ‘^$’. А вот как она работает:
- 10!! выбирает десять строк для фильтрации.
- Команда grep -v запускает grep для вывода строк, не соответствующих регулярному выражению.
- Регулярное выражение ^$ означает «начало строки, за которым сразу же идет конец строки» – то есть соответствует пустым строкам.
Функции для программистов
В Vi и Vim имеется множество функций специально для программистов. Во-первых, имеется режим автоотступа, активируемый при помощи опции :set ai. При включенном автоотступе, по мере ввода текста, Vim автоматически отодвигает новую строку в соответствии с предыдущей. Если необходимо, вы можете увеличить отступ при помощи ^T или уменьшить – ^D.
Для исправления отступов существующих строк, используйте команды > и <. Они работают так же, как и команда d, и требуют указания перемещений курсора, так что >} увеличит отступ до конца абзаца (то есть до следующей пустой строки). Однако эти команды в основном используются в сдвоенном виде, например, 4>> сделает отступ у четырех строк.
По умолчанию, отступ равняется восьми позициям – вероятно, это многовато. Вы можете изменить размер отступа (Vim называет это ‘shiftwidth’) командой вроде :set sw=4.
Еще одна дружественная к программистам функция – способ управления различными типами скобок. Если курсор находится на скобке одного из типов (, ), {, }, [ или ], то ввод % переместит курсор к соответствующей скобке того же уровня вложенности. Конечно, вы можете использовать % для перемещения курсора так же, как и команды d, c или y, и если вы редактируете исходный код на языке C, в котором используются фигурные скобки для ограничения блоков, вы можете удалить блок очень просто, поместив курсор к открытой скобке и набрав d%.
Кроме того, если вы установите опцию showmatch командой :set showmatch, Vi немедля переместит курсор к соответствующей открывающей скобке каждый раз, когда вы вставите закрывающую скобку, такую как ), } или ]. Исходный Vi не умеет этого делать с угловыми скобками – < и >, и Vim, по умолчанию, тоже; однако вы можете его заставить, добавив <:> к строке опции matchpairs по команде :set matchpairs+=<:> – это пригодится, если вы редактируете HTML или XML-документы.
Кроме того, имеется подсветка синтаксиса, которую лично я не очень люблю, хоть и знаю, что многие программисты считают ее полезной. Исходный Vi ее не поддерживает, поскольку терминалы тех дней могли отображать только один цвет (обычно зеленый). В Vim она включается при помощи команды нижней строки :syntax enable. Vim автоматически распознает тип файла и загружает соответствующую цветовую схему.
Мы только начали...
Имеется еще много команд и опций Vim, для которых у нас просто нет места. Если вы читаете это, будучи экспертом Vi, и я пропустил вашу любимую функцию, пожалуйста, простите меня! Втиснуть в четыре страницы все, что пользователи Vi считают заслуживающим внимания, просто невозможно, так что рассматривайте это как беглое введение. Есть расширенная документация по Vim на www.vim.org/htmldoc/ и PDF-версия книги Стива Оллина [Steve Oualline] о Vim на www.truth.sk/vim/vimbook-OPL.pdf. И заметьте, что даже я готов признать: нужно быть большим энтузиастом редактора, чтобы для ознакомления с его работой пуститься читать 572-страничную книгу...
Врезка
Произносите правильно
Vi следует произносить как «ви-ай». Вы опозоритесь перед знатоками Unix, если произнесете это как «вай». И уж точно не следует говорить «шесть», как предложил один мой коллега, вообразивший, что он происходит от римлян...
Немного истории
Дизайн Vi станет более понятен, если рассматривать его в контексте устройств, существовавших в 1976 г., когда Билл Джой написал его. Типичным терминалом того времени был Lear-Siegler ADM3A, машина на основе ЭЛТ-монитора (перейдите по ссылке www.vintage-computer.com/otheritems.shtml – и увидите такую). ADM3A имел полную QWERTY-клавиатуру, но без функциональных клавиш и стрелок, имеющихся на современной клавиатуре. Дизайн Vi отражает эти ограничения: все перемещения курсора и операции редактирования могут быть выполнены без их использования.
ADM3A был одним из первых терминалов, имевших адресуемый курсор (то есть вы могли отсылать ему специальные последовательности ASCII-символов для определения места появления на экране следующего символа). Сейчас мы принимаем это как должное, но тогда это была новация, и она вызвала всплеск активности: люди стали писать настоящие «экранные редакторы» для замены прежних строковых редакторов. Такие терминалы подключались к компьютерам через последовательный порт – либо напрямую, либо при помощи телефонных соединений по модему, который тогда предоставлял скорость обмена 300 или (у везунчиков) 1,200 bps. В некоторых экранных редакторах после удаления строки и вставки пары слов вы могли за время обновления экрана успеть не то что выпить, а наварить пива. Одним из преимуществ Vi была эффективность обновления экрана, наряду с возможностью управлять большим числом терминалов, используя базу данных termcap. В последних версиях Vi и Vim все еще есть переменная среды TERM, определяющая тип терминала.
Базовые команды
h,j,k,l | Перемещение курсора на один символ влево, вниз, вверх, вправо |
w | Вперед на одно слово |
b | Назад на одно слово |
0 | Начало строки(цифра ноль) |
$ | Конец строки |
( | Начало предложения |
) | Конец предложения |
{ | Начало абзаца |
} | Конец абзаца |
G | Конец файла |
% | Перейти к соответствующей парной скобке того же уровня |
/string | Первое вхождение строки (поиск вперед) |
?string | Первое вхождение строки (поиск вперед) |
n | Следующее вхождение(поиск продолжаеться в том же направлении) |
N | Предыдущее вхождение(поиск продолжаеться в том же направлении) |
i | Вставить текст перед курсором |
а | Вставить текст после курсора |
I | Вставить текст в начало строки(заглавная 'i') |
A | Добавить текст в конец строки |
o | Создать новую строку выше текущей |
O | Создать новую строку ниже текущей |
x | Удалить один символ |
d | Удалить (и скопировать в буфер удаления) |
y | Выдернуть (скопировать в буфер удаления) |
p | Положить (вставить) содержимое буфера удаления |
c | Изменить |
. | Повторить последнее изменение (но в текущей позиции курсора) |
u | Отменить последнее изменение |
J | Объединить текущую строку с предыдущей |
< | Уменьшить отступ |
> | Увеличить отступ |
Опции Vim
Опции | Аббревиатура | Тип | Что делает |
---|---|---|---|
number | nu | bool | Включает нумерацию строк |
showmode | smd | bool | Заставляет Vim отображать название режима, используя метку в нижней строке |
cindent | cin | bool | Включает отступы в стиле C |
ignorecase | ic | bool | Игнорировать регистр при поиске |
magic | - | bool | Учитывать регистр при поиске |
wrapmargin | wm | number | Номер позиций относительно правого края экрана, где Vim вставит перенос строки в режиме вставки |
autoindent | ai | bool | Включение автоотступа |
shiftwidth | sw | number | Число символов отступа |
matchpairs | mps | string | Список парных символов, используемых для функции ‘showmatch’ и для команды %. Набор по умолчанию: matchpairs=(:),{:},[:] |
wrapscan | ws | bool | Осуществление поиска по тексту с конца файла к началу |