РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ VIM - Брам Мооленаар

Внесение серьёзных изменений

В главе 4 объяснялось, как вносить небольшие изменения в текст. Эта глава рассказывает, как вносить повторяющиеся изменения или затрагивающие большие объёмы текста, объясняет приёмы, полезные при работе с Визуальными блоками, и использование внешних программ для выполнения сложных операций.

10.1    Запись и воспроизведение команд
10.2    Замена текста
10.3    Диапазоны для команд
10.4    Команда global
10.5    Режим Визуального блока
10.6    Чтение и запись фрагментов файла
10.7    Форматирование текста
10.8    Изменение регистра символов
10.9    Использование внешних программ

Следующая глава: Восстановление после аварии
Предыдущая глава: Использование графического интерфейса
Содержание: Руководство пользователя Vim


10.1 Запись и воспроизведение команд

Команда "." повторяет предыдущее изменение. Но что делать, если вы хотите повторить нечто более сложное, чем простое изменение? Для этого существует запись команд. Вот три шага, которые надо для этого предпринять:

  1. Команда "q{регистр}" начинает запись нажатий кнопок в регистр {регистр}. Имя регистра должно быть в диапазоне от a до z.
  2. Введите требуемые команды.
  3. Для окончания записи нажмите q (без дополнительных символов).

Теперь вы можете воспроизвести записанный макрос при помощи команды "@{регистр}".

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

stdio.h ~
fcntl.h ~
unistd.h ~
stdlib.h ~

и вы хотели бы получить следующее:

#include "stdio.h" ~
#include "fcntl.h" ~
#include "unistd.h" ~
#include "stdlib.h" ~

Прежде всего подведём курсор к первому символу первой строки. Затем выполним следующие команды:

qa Начало записи макроса в регистр a.
^ Перемещение курсора в начало строки.
i#include "<Esc> Вставка строки #include " в начало строки.
$ Перемещение курсора в конец строки.
a"<Esc> Добавление символа двойной кавычки (") в конец строки
j Переход к следующей строке.
q Окончание записи макроса.

Выполнив эту работу лишь однажды, можно повторить весь процесс для остальных строк простым вводом команды "@a" три раза.

Команда "@a" может предваряться числом-приставкой, которое задаёт число повторений выполнения макроса. В данном случае можно просто набрать

3@a
ПЕРЕМЕЩЕНИЕ И ВЫПОЛНЕНИЕ

Возможно, строки, которые вы хотели бы изменить, раскиданы по разным частям файла. В этом случае просто подведите курсор к нужной строке и введите команду "@a". Проделав это один раз, можно в следующий раз вводить просто "@@", что немного легче для набора. Если вы теперь выполните содержимое регистра b при помощи команды "@b", то следующая команда "@@" будет выполнять содержимое регистра b.

Сравнивая метод воспроизведения команд из регистра с использованием команды ".", мы обнаружим несколько отличий. Во первых, "." может повторить только одно изменение, а команды вроде "@a" могут выполнять целые серии изменений, включая перемещения курсора, как это видно из приведённого выше примера. Во вторых, в "." хранится только одно последнее изменение. При использовании регистра можно вносить любые изменения не опасаясь, что содержимое регистра будет изменено. Наконец, в вашем распоряжении целых 26 регистров, вы можете записать для последующего воспроизведения до 26 различных макросов.

ИСПОЛЬЗОВАНИЕ РЕГИСТРОВ

Регистры, которые используются для записи макроса - те же, что и для команд копирования и удаления. Это позволяет вам использовать запись вместе с другими командами, которые работают с регистрами.

Предположим, вы записали в регистр n несколько команд. При воспроизведении содержимого регистра при помощи команды "@n" вы вдруг замечаете, что допустили ошибку. Можно, конечно, записать макрос с самого начала, но кто даст гарантию, что вы не совершите новых ошибок? Вместо этого можно воспользоваться вот каким приёмом:

G Переместитесь в конец файла.
o<Esc> Создайте пустую строку.
"np Вклейте текст из регистра n.  Вы сможете видеть набранные команды в виде текста.
{редактирование} Измените команды, в которых была допущена ошибка, как будто вы редактируете обычный текст.
0 Перейдите в начало строки.
"ny$ Скопируйте исправленную строку в регистр n.
dd Удалите ненужную строку.

Теперь вы можете выполнять исправленную команду с помощью "@n". (Если записанная вами команда содержит переносы строки, то учтите этот факт в предыдущем примере, когда будете копировать текст команды, чтобы скопировать все строки).

ДОБАВЛЕНИЕ В РЕГИСТР

До сих пор мы пользовались строчными буквами в качестве имени регистра. Прописные имена служат для операции добавления в регистр.

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

qC/word<Enter>q

Начав с "qC" вы записываете в конец команды, которая уже содержится в регистре c. Таким образом, запись в регистр, имя которого является прописной буквой имеет значение добавления в регистр, имя которого является той же самой буквой, но строчной.

Этот приём работает как с командами для записи, так и с командами для копирования и удаления. Например, вы хотите собрать последовательность строк в регистр a. Скопируйте первую строку при помощи команды:

"aY

Теперь перейдите к следующей необходимой строке и наберите

"AY

Эту команду можно повторить для всех строк. Регистр a теперь содержит все необходимые строки в том порядке, в котором вы их скопировали.


10.2 Замена текста

Команда ":substitute" (подстановка) позволяет совершать замену текста в данном диапазоне строк. В общем виде синтаксис этой команды следующий:

:[диапазон]substitute/откуда/куда/[флаги]

Эта команда изменяет строку "откуда" на строку "куда" во всех строках, на которые указывает [диапазон]. Например, вы можете изменить "хакер" на "ламер" такой вот простой командой:

:%substitute/хакер/ламер/

Замечание: Имя команды :substitute почти никогда не вводится полностью. Чаще всего используется сокращённый вариант ":s". Далее мы также будем пользоваться сокращённой записью.

Диапазон "%" перед командой указывает на все строки текста. Без указания диапазона ":s" работает над текущей строкой. Мы расскажем о диапазонах подробнее в следующем разделе 10.3.

По умолчанию, ":substitute" изменяет только первое появление "откуда" на строке. Например, предыдущая команда изменит строку

Неожиданно, хакер Крутой заметил, что хакер Пупкин вошёл в сеть. ~

на

Неожиданно, ламер Крутой заметил, что хакер Пупкин вошёл в сеть. ~

Чтобы заменить все соответствия на строке, необходимо добавить в команду флаг g (global, повсюду). Команда

:%s/хакер/ламер/g

заменит первоначальную строку на

Неожиданно, ламер Крутой заметил, что ламер Пупкин вошёл в сеть. ~

Другие флаги, которые можно использовать с командой ":s" включают: p (print, печать) для вывода всех строк, которые изменяются командой, c (confirm, подтверждение) для вывода подтверждения перед выполнением замены. Введите следующую команду:

:%s/хакер/ламер/c

Vim найдёт первое соответствие строке "хакер" и покажет текст, который собирается изменить. Вы увидите вопрос:

заменить на ламер (y/n/a/q/l/^E/^Y)?

В этот момент вы должны ввести один из вариантов ответа:

y Да (yes), заменить.
n Нет (no), пропустить.
a Все (all); сделать эту замену и все последующие без дальнейших вопросов.
q Выйти (quit); не делать дальнейших изменений.
l Последний раз (last); сделать это изменение и выйти.
CTRL-E Прокрутить текст на одну строку вверх.
CTRL-Y Прокрутить текст на одну строку вниз.

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

:s/^хакер/ламер/

Если "откуда" или "куда" содержит косую черту, то перед ней необходимо поместить обратную косую черту. Более простой способ заключается в использовании другого символа в качестве разделителя, например "+":

:s+один/два+один или два+

10.3 Диапазоны для команд

Команда ":substitute" и многие другие :команды  могут работать с диапазонами строк. Диапазон в самой простой форме выглядит так: {номер},{номер}. Например:

:1,5s/это/то/g

выполняет команду замены на строках с номерами от 1 до 5 включительно. Диапазон всегда указывается перед командой.

Одиночное число может указывать на строку с определённым номером:

:54s/Хакер/Ламер/

Некоторые команды работают со всем файлом целиком, если вы не указываете диапазон. Для таких команд можно использовать адрес ".", который указывает на текущую строку. Например, к таким командам относится команда ":write". Без указания диапазона она записывает весь файл. Напротив, команда

:.write другой_файл

запишет в другой_файл только текущую строку.

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

:.,$s/да/нет/

Диапазон "%", о котором мы говорили в начале, на самом деле просто сокращённая форма для записи "1,$", "от первой до последней строки в файле".

ИСПОЛЬЗОВАНИЕ ШАБЛОНА В ДИАПАЗОНЕ

Предположим, вы редактируете главу в книге и хотите заменить все слова "хакер" на слово "ламер", но только в этой главе. Вы также знаете, что границы глав имеют слово "Глава" в первой колонке текста. Тогда можно выполнить такую команду:

:?^Глава?,/^Глава/s=хакер=ламер=g

Обратите внимание, что шаблон поиска используется дважды. Первый шаблон "?^Глава?" ищет строку со словом "Глава" в первой колонке над текущей позицией. Вообще, диапазон ?шаблон? используется для поиска в обратном направлении. Аналогично, "/^Глава/" используется для поиска слова "Глава" в первой колонке вперёд по тексту.

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

СЛОЖИТЬ И ВЫЧЕСТЬ

В указанной выше команде есть небольшая ошибка: Если в заголовке следующей главы есть слово "хакер", то оно будет также заменено. Что если это не совсем то, что вам нужно? Тогда придётся использовать смещение.

Для поиска по шаблону и использования строки над найденным соответствием пишите:

/Глава/-1

Вместо 1 можно использовать любое другое число. Для адресации второй строки снизу от соответствия шаблону:

/Глава/+2

Смещения можно использовать и с другими элементами диапазона. Например:

:.+3,$-5

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

ИСПОЛЬЗОВАНИЕ ОТМЕТОК

Вместо вычисления номеров строк в тех или иных позициях для использования в диапазоне, можно использовать отметки.

Разместите отметки в тексте, как об этом рассказано в главе 3. Например, используйте отметку "mt" для верхней части области диапазона, и "mb" для отметки нижней части. Теперь можно использовать отметки для указания строк в диапазоне (включая строки с отметками):

:'t,'b
ВИЗУАЛЬНЫЙ РЕЖИМ И ДИАПАЗОНЫ

Текст можно выделять в Визуальном режиме. Если вы введёте ":" в Визуальном режиме, чтобы начать ввод команды, то увидите в командной строке следующее:

:'<,'>

Теперь вы можете печатать свою команду и она будет применяться ко всему диапазону строк, который был выбран визуально.

Замечание: При использовании Визуального режима для выбора части строки, или при использовании CTRL-V для выбора блока текста, команда с двоеточием всё равно будет применяться к целым строкам. Такое поведение возможно будет изменено в следующих версиях Vim.

Обратите внимание, что '< и '> это отметки, которые помещаются автоматически в начале и конце Визуального выделения. Эти отметки остаются на месте до тех пор, пока не будет сделано другое Визуальное выделение. Поэтому можно использовать команду "'<" для перемещения к позиции начала Визуального выделения. Кроме того, отметки можно совмещать с другими элементами:

:'>,$

что является адресацией диапазона строк от конца Визуального выделения и до конца файла.

ЧИСЛО СТРОК

Если вы знаете сколько строк вам требуется изменить, то можно просто набрать это число перед ":". Например, наберите "5:", и вы получите:

:.,.+4

Теперь вы сможете набирать команды, которые хотите использовать. Они будут работать в диапазоне от "." (текущая строка) до ".+4" (еще четыре строки вниз), в итоге получается пять строк.


10.4 Команда global

Команда ":global" является одной из самых мощных особенностей Vim. Она позволяет найти соответствие шаблону и выполнить над найденным соответствием команду. Синтаксис этой команды следующий:

:[диапазон]global/{шаблон}/{команда}

Выглядит очень похоже на команду ":substitute", но вместо замены текста, отвечающего соответствию на другой текст, выполняется команда {команда}.

Замечание: В команде ":global" в качестве {команды} должна быть использована команда, начинающаяся с двоеточия. Команды Обычного режима не могут быть использованы в ":global" напрямую, но в этом случае вам может помочь команда |:normal|.

Предположим, вы хотите поменять "foobar" на "barfoo", но только внутри комментариев в стиле C++, которые начинаются с "//". Используйте такую команду:

:g+//+s/foobar/barfoo/g

Разберёмся, что происходит. Команда начинается с ":g", что является сокращением для ":global", точно так же как ":s" является сокращением для ":substitute". Далее следует шаблон, заключённый в символ "+", поскольку шаблон, который мы ищем содержит символ косой черты, поскольку шаблон, который мы ищем содержит символ косой черты. Далее следует команда замены, которая заменяет "foobar" на barfoo".

Диапазон для команды global по умолчанию это весь файл. Поэтому, в этом примере не был указан диапазон, что отличается от команды ":substitute", в которой диапазоном по умолчанию считается текущая строка.

Указанная команда не является пределом совершенства, поскольку также будет находить появление "//" в середине строки и замены будут производиться перед символами "//".

Как и в случае с ":substitute", можно использовать любой шаблон. Мы изучим более сложные шаблоны позднее.


10.5 Режим Визуального блока

При помощи CTRL-V можно выделить прямоугольный блок символов. Существует несколько команд, выполняющих специальные операции с такими блоками текста.

Команда "$" при использовании в режиме Визуального блока работает несколько иначе. Если "$" была последней командой, использованной для перемещения курсора, то все строки в Визуальном выделении будут выделены вплоть до конца строки, в том числе в тех случаях, когда строка, в которой находится курсор, была более короткой, чем остальные строки. Такое выделение будет оставаться в силе до тех пор, пока вы не воспользуетесь командой горизонтального перемещения курсора, иными словами "j" будет сохранять указанный режим выделения, а "h" прекратит его.

ВСТАВКА ТЕКСТА

Команда "I{строка}<Esc>" вставляет текст {строка} в каждую строку слева от визуального блока. Начните с выделения Визуального блока при помощи CTRL-V, переместите курсор в требуемое положение. Теперь перейдите в режим вставки по команде I и введите текст для вставки. Во время набора текст будет появляться только в первой строке.

После нажатия <Esc> в конце вставки, текст будет вставлен во всех строках, входящих в визуальный блок. Например:

include one~
include two ~
include three ~
include four ~

Переместите курсор к символу "o" в "one" и нажмите CTRL-V. Далее, переместите курсор на три строки вниз командой "3j", чтобы получился визуальный блок на четыре строки. Теперь введите:

Imain.<Esc>

В результате получится следующее:

include main.one ~
include main.two ~
include main.three ~
include main.four ~

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

Эта строка длинная ~
короткая ~
Эта строка длинная ~

           ^^^^^^^ выделенный блок

Теперь введите команду "Iочень <Esc>". В результате получим:

Эта строка очень длинная ~
короткая ~
Эта строка очень длинная ~

В короткой строке текст не был вставлен.

Если в тексте, который вы вставляете, есть символ новой строки, то "I" будет работать как обычная команда вставки и повлияет только на первую строку блока выделения.

Команда "A" работает похожим образом, добавляя введённый текст в конец каждой строки выделенного блока.

У команды "A" также есть особый случай: выделите Визуальный блок и воспользуйтесь "$" для расширения блока до конца каждой строки. Теперь команда "A" будет добавлять введённый текст к концу каждой строки в блоке.

Используя пример, приведённый выше, введём "$A XXX<Esc>" и получим такой результат:

Эта строка длинная XXX ~
короткая XXX ~
Эта строка длинная XXX ~

Для достижения такого эффекта требуется использование команды "$" для перемещения курсора. Выполнение такого же выделения с помощью другой команды, перемещающей курсор в конец самой длинной строки, приведёт к другому результату.

ИЗМЕНЕНИЕ ТЕКСТА

Команда "c" в Визуальном блоке удаляет блок и переводит вас в режим Вставки. Набранный текст будет вставлен в каждой строке, которая содержала выделенный блок.

Используя всё тот же пример, наберите команду "c_ДЛИННАЯ_<Esc>", и вы получите следующий результат:

    Эта строка _ДЛИННАЯ_ ~
    короткая ~
    Эта строка _ДЛИННАЯ_ ~

Как и в случае с командой "I", короткая строка не была изменена. Аналогично, чтобы это работало, в новом тексте нельзя вводить символ перевода строки.

Команда "C" удаляет текст от левого края блока до конца строки и переводит в режим Вставки, где вы можете ввести текст для добавления в конец каждой строки.

Используем наш пример еще раз и введём команду "Cс новым текстом<Esc>". Заметьте, что даже если вы выделите слово "длинная" лишь частично, оно всё равно будет удалено полностью, поскольку с этой командой имеет значение только левый край выделения:

Эта строка с новым текстом ~
короткая ~
Эта строка с новым текстом ~

Короткая строка, которая не вошла в блок, не будет изменяться.

Другие команды, изменяющие символы в блоке:

~ изменить регистр    (a -> A и A -> a)
U в верхний регистр   (a -> A и A -> A)
u в нижний регистр    (a -> a и A -> a)
   
   
   
ЗАПОЛНЕНИЕ СИМВОЛОМ

Для заполнения целого блока одним символом используйте команду "r". Попробуйте на нашем примере ввести команду "rx":

Эта строка ххххххх ~
короткая ~
Эта строка ххххххх ~

Замечание: Если вы хотите вставить символы после конца строки в блоке, то прочитайте об особенности 'virtualedit' в главе 25.

СДВИГ

Команда ">" сдвигает выбранный текст вправо на величину ширины сдвига, вставляя пробелы. Начало сдвига находится на левом краю визуального блока.

Всё с тем же примером ">" даёт следующий результат:

Эта строка     длинная ~
короткая ~
Эта строка     длинная ~

Величина сдвига указывается в опции 'shiftwidth'. Например, для установки сдвига на 4 символа воспользуйтесь командой:

:set shiftwidth=4

Команда "<" удаляет пробелы в количестве ширины одного сдвига у левого края блока. Эта команда ограничивается количеством имеющегося текста. Если в тексте содержится пробелов меньше, чем ширина сдвига, то будет удалено столько пробелов, сколько возможно.

СОЕДИНЕНИЕ СТРОК

Команда "J" соединяет все выбранные строки в одну, удаляя символы перевода строки. В действительности при этом происходит замена символа перевода строки, а также предшествующих ему и последующих пробелов на один пробел. После окончания предложения используется два пробела (это можно изменить при помощи опции 'joinspaces').

Воспользуемся нашим примером. Результатом использования команды "J" будет:

Эта строка длинная короткая Эта строка длинная ~

Команда "J" не требует выделения блока. Она также будет работать и с выделениями "v" и "V" точно таким же образом.

Если вы не хотите, чтобы изменялись пробелы, то используйте команду "gJ".


10.6 Чтение и запись фрагментов файла

Представьте, что вы пишите письмо и хотите включить в него другой файл. Это можно сделать при помощи команды ":read {имя-файла}". Текст, который содержится в файле, будет помещён под строкой с курсором.

Допустим, у вас в редакторе набран следующий текст:

Ваня, привет! ~
Лови diff, который исправляет глюки. ~

Твой Петя. ~

Подведите курсор ко второй строке и наберите:

:read patch

Содержимое файла с именем "patch" будет вставлено в текст. Вот результат:

Ваня, привет! ~
Лови diff, который исправляет глюки. ~
2c2 ~
<       for (i = 0; i <= length; ++i) ~
---~
>       for (i = 0; i < length; ++i) ~

Твой Петя. ~

Команде ":read" можно также сообщить диапазон, в этом случае содержимое файла будет вклеено под последней строкой диапазона. Так, ":$r patch" добавляет содержимое файла "patch" в конец редактируемого файла.

А что делать, если вы хотите поместить содержимое файла перед первой строкой? Тогда пользуйтесь строкой с номером ноль. Эта строка, конечно, в реальности не существует, и при использовании нуля в качестве диапазона в большинстве команд вы получите сообщение об ошибке, но эта команда разрешена:

:0read patch

Теперь содержимое файла "patch" вклеено в текст над первой строкой.

ЗАПИСЬ ДИАПАЗОНА СТРОК

Для записи диапазона строк в файл можно использовать команду ":write". Без указания диапазона она записывает весь файл целиком, но если указать диапазон, то будут сохранены только указанные строки:

:.,$write tempo

Эта команда сохранит строки от текущей до последней в файл "tempo". Если файл уже существует, то вы увидите сообщение об ошибке. Vim предохраняет вас от случайной перезаписи существующего файла. Если вы отдаёте себе отчёт в своих действиях, то добавьте к команде !:

:.,$write! tempo

ОСТОРОЖНО: ! должен следовать непосредственно за командой ":write", без пробелов. В противном случае ! воспринимается как команда-фильтр, которая объясняется ниже в этой главе.

ДОБАВЛЕНИЕ В ФАЙЛ

В первом разделе этой главы мы рассказали о том, как собрать несколько строк в один регистр. То же самое можно сделать для сбора строк в файл. Записывайте первую строку при помощи команды:

:.write collection

Теперь переместите курсор ко второй строке и введите:

:.write >>collection

">>" указывает Vim, что не надо создавать новый файл "collection", но нужно добавить указанную строку в конец файла. Вы можете повторить указанную операцию несколько раз.


10.7 Форматирование текста

При наборе обычного текста было бы неплохо, если бы длинные строки автоматически переносились, чтобы убираться по ширине окна. Чтобы это происходило во время набора, установите значение опции 'textwidth' в требуемую длину строки:

:set textwidth=72

Как вы вероятно помните, в примере файла vimrc эта команда была установлена для использования во всех текстовых файлах, так что если вы используете этот файл инициализации, то, вероятно, эта опция уже установлена. Чтобы проверить текущее значение опции 'textwidth', наберите:

:set textwidth

Теперь строки будут переноситься автоматически, если их длина превышает 72 символа. Однако, если вы вставляете текст в середине строки или удаляете текст, то строки все равно будут слишком длинными или слишком короткими. Vim не производит автоматического форматирования текста на лету.

Чтобы Vim переформатировал текущий абзац, введите команду

gqap

Начало этой команды -- оператор "gq", затем следует указание на текстовый объект "ap", то есть "абзац". Абзац отделяется от следующего абзаца пустой строкой.

Замечание: Пустая строка, содержащая пробелы, НЕ разделяет абзацы!

Вместо "ap" можно использовать любую команду перемещения или текстовый объект. Если ваши абзацы разделены надлежащим образом, то для форматирования целого файла используйте команду

gggqG

"gg" осуществляет переход к первой строке, "gq" это оператор форматирования, а "G" это команда перемещения к последней строке.

В том случае, если абзацы в тексте не определены чётко, строки можно форматировать вручную. Переместите курсор к первой строке, которую вы хотите отформатировать и введите команду "gqj", которая отформатирует текущую строку и строку, расположенную под ней. Если первая строка была слишком короткой, то к ней будут добавлены слова из следующей строки. Если она была слишком длинной, то слова будут перенесены на следующую строку. Теперь можно использовать "." для повторения команды до тех пор, пока вы не окажетесь в конце текста, который хотели отформатировать.


10.8 Изменение регистра символов

Допустим, у вас есть текст, в котором все подзаголовки набраны строчными буквами, и вы хотите, чтобы слово раздел было набрано строчными. Для этого пользуйтесь оператором "gU". Например:

                          gUw
<    раздел первый       ---->      РАЗДЕЛ первый

Оператор "gu" выполняет прямо противоположную операцию:

                           guw
<    РАЗДЕЛ первый        ---->      раздел первый

Для изменения регистра также можно использовать команду "g~", которая также является оператором, поэтому может работать с любыми командами перемещения и текстовыми объектами, а также в Визуальном режиме.

Чтобы оператор работал на всей строке его обычно повторяют дважды. Оператор удаления "d", будучи повторённым дважды, удаляет всю строку: "dd". Аналогично, "gugu" переводит всю строку в нижний регистр символов. "gugu" можно сократить до "guu", "gUgU" до "gUU" и "g~g~" до "g~~". Пример:

                                  g~~
<    Девчонки ЛЮБЯТ Мороженое    ---->   дЕВЧОНКИ любят мОРОЖЕНОЕ ~

10.9 Использование внешних программ

В Vim встроено множество очень полезных и мощных команд, которые могут с текстом почти всё. Тем не менее, могут существовать программы, которые делают те или иные операции быстрее или лучше.

Команда "!{перемещение}{программа}" берёт блок текста из редактора и пропускает его через внешнюю программу. Другими словами, эта команда запускает системную команду, представленную {программой}, предлагая ей на вход блок текста, отмеченный {перемещением}. Вывод программы заменяет выбранный блок.

Если вы не знакомы с фильтрами в UNIX, то вам наверное это сложно представить. Давайте посмотрим на примере. Команда sort сортирует файл. Если вы выполните команду

sort <вход.txt >выход.txt

то неотсортированный файл вход.txt будет отсортирован и записан в файл выход.txt. (Это работает как на UNIX, так и на Microsoft Windows.)

Теперь сделаем то же самое в Vim. Допустим, вы хотите отсортировать строки файла с первой по пятую. Поместим курсор на первую строку и введём команду

!5G

"!" указывает Vim, что вы осуществляете операцию фильтра. Теперь редактор ждёт команды перемещения, которая укажет ему с какой частью текста надо провести эту операцию. Команда "5G" как раз указывает редактору на перемещение к строке 5, так что теперь Vim знает, что необходимо фильтровать строки с 1-ой по 5-ую.

Ожидая ввода команды-фильтра, курсор перемещается в нижнюю строку экрана и появляется приглашение для ввода команды !. Теперь вы можете ввести имя команды фильтра, в данном случае "sort". Полностью команда будет выглядеть следующим образом:

!5Gsort<Enter>

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

line 55                     line 11
line 33                  line 22
line 11        -->          line 33
line 22                  line 44
line 44                   line 55
last line               last line

Команда "!!" пропускает через программу-фильтр текущую строку. В системе Unix команда "date" выводит текущую дату и время. "!!date<Enter>" заменяет текущую строку выводом команды "date", что бывает полезно для добавления отметки о времени в текст файла.

ПОЧЕМУ ФИЛЬТР МОЖЕТ НЕ РАБОТАТЬ?

Запуск оболочки, отправка текста программе и получение вывода требуют, чтобы Vim знал о том, как работает ваша оболочка. Если у вас возникают проблемы с использованием фильтров, то проверьте значения следующих опций:

'shell' указывает на имя программы, используемой Vim для запуска внешних программ.
'shellcmdflag' аргумент, требуемый оболочкой для выполнения внешней программы
'shellquote' тип кавычки для использования вокруг команды
'shellxquote' тип кавычки для использования вокруг команды и перенаправления вывода
'shelltype' тип оболочки (только для Amiga)
'shellslash' использовать косую черту в команду (только для MS-Windows и подобных систем)
'shellredir' строка для перенаправления вывода команды в файл

На Unix проблем возникнуть не должно, потому что там всего два основных типа оболочки: sh-подобные и csh-подобные. Vim проверяет опцию 'shell' и автоматически устанавливает остальные опции в соответствии с её значением, в зависимости от того, встречается ли в опции 'shell' строка "csh".

На MS-Windows, однако, присутствует много различных оболочек и вам возможно потребуется настроить опции для правильной работы фильтров. За дополнительной информацией по этим опциям обращайтесь к справке.

ЧТЕНИЕ ВЫВОДА КОМАНДЫ

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

на Unix:

:read !ls

на MS-Windows:

:read !dir

Вывод команды "ls" или "dir" подхватывается редактором и вставляется непосредственно в текст, под курсором. Это аналогично чтению файла, с тем исключением, что используется "!" для указания команды, которую нужно выполнить.

Команда может иметь аргументы, а также можно использовать диапазон для указания позиции, в которой Vim должен поместить строки:

:0read !date -u

вставляет текущую дату и время в формате UTC в верхней строчке файла (Если у вас в системе есть команда date и она принимает аргумент "-u".)

Замечание: обратите внимание на различие между командой "!!date", которая заменяет строку в тексте, и командой ":read !date", которая вставляет строку.

ПЕРЕДАЧА ТЕКСТА КОМАНДЕ

Команда Unix "wc" подсчитывает слова. Чтобы подсчитать слова в текущем окне, введите:

:write !wc

Вы используете всё ту же команду write, но вместо имени файла указываете "!" и имя используемой внешней команды. В этом случае текст будет передан внешней команде в виде стандартного входа. Вывод команды может выглядеть так:

4      47     249 ~

Команда "wc" не очень многословна. Это означает, что у вас в файле 4 строки, 47 слов и 249 символов.

Будьте осторожны, чтобы не ввести

:write! wc

иначе текст будет записан в файл "wc" в текущем каталоге в обход всех проверок. Пробел имеет здесь большое значение!

ОБНОВЛЕНИЕ ЭКРАНА

Если внешняя команда вывела сообщение об ошибке, то это может нарушить отображение текста на экране. Vim обновляет только те части экрана, которые в этом нуждаются для эффективности работы, но может не знать о том, что вывела на экран внешняя программа. Чтобы Vim обновил экран, введите:

CTRL-L

Следующая глава: Восстановление после аварии
Авторские права: см. Авторские права