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

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

25.1    Перенос строк
25.2    Выравнивание текста
25.3    Отступы и табуляция
25.4    Работа с длинными строками
25.5    Редактирование таблиц

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


25.1 Перенос строк

В Vim встроен целый набор функций, облегчающих работу с текстом. По умолчанию, редактор не переносит строки автоматически. Другими словами, для переноса строк вам необходимо нажимать <Enter>. Это полезно при написании программ, когда вам должно быть виднее, где заканчивается одна строка и где начинается другая. Но если вы создаёте документацию, то почти наверняка желаете, чтобы текст по ширине был примерно 70 символов.

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

:set textwidth=30

Теперь начнём набор текста (в примере также показана линейка):

         1         2         3
12345678901234567890123456789012345
Мы полюбили друг друга на ново ~

Когда вы набираете следующую букву, "г", то строка становится длиннее, чем
30 символов. Vim  вставляет перенос строки и вы видите следующее:

         1         2         3
12345678901234567890123456789012345
Мы полюбили друг друга на ~
новог ~

Продолжая таким образом вы можете набрать весь абзац:

         1         2         3
12345678901234567890123456789012345
Мы полюбили друг друга на ~
новогоднем балу. Виталик был ~
Дедом Морозом и очень мне ~
понравился в этом образе. В  ~
жизни же он оказался совсем не ~
весёлым человеком, и я с ~
нетерпением жду следующий ~
Новый Год. ~

От вас не требуется переносить строку -- Vim всё делает автоматически.

Замечание: Опция 'wrap' позволяет заставить Vim показывать длинные строки с переносами, но при этом переносы не будут сохранены в файле.

ИЗМЕНЕНИЕ ФОРМАТИРОВАНИЯ

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

         1         2         3
12345678901234567890123456789012345
Мы полюбили на ~
новогоднем балу. Виталик был ~
Дедом Морозом и очень мне ~
понравился в этом образе. В  ~
жизни же он оказался совсем не ~
весёлым человеком, и я с ~
нетерпением жду следующий ~
Новый Год. ~

Чтобы снова оформить абзац как полагается, используйте команду-оператор "gq". Попробуем использовать для этого Визуальное выделение.

Начиная с первой строки, наберите:

v7jgq

"v" переходит в Визуальный режим, "7j" перемещает курсор в конец абзаца, а затем мы используем оператор "gq", который применяется к выделенной области. Результат выглядит так:

         1         2         3
12345678901234567890123456789012345
Мы полюбили на новогоднем ~
балу. Виталик был Дедом ~
Морозом и очень мне понравился ~
в этом образе. В жизни же он ~
оказался совсем не весёлым ~
человеком, и я с нетерпением ~
жду следующий Новый Год. ~

Замечание: некоторые виды текста позволяют выполнять автоматическое
форматирование, см. |автоформатирование|.

Поскольку "gq" является оператором, то вы можете пользоваться одним из трёх способов выбора фрагмента текста, над которым он будет работать: Визуальный режим, перемещение курсора или текстовый объект.

Тех же самых результатов можно было бы достичь и командой "gq7j". Это потребовало бы меньше нажатий на кнопки, но от вас требуется знать, на сколько именно строк нужно переместить курсор. Более полезная, в данном случае, команда перемещения: "}". Эта команда позволяет переместить курсор в конец абзаца. Иными словами, команда "gq}" выполнит форматирование текста от текущей позиции курсора до конца текущего абзаца.

Для использования с командой "gq" очень полезен также текстовый объект "абзац". Попробуйте ввести команду:

gqap

"ap" это "абзац", "a-paragraph". Эта команда форматирует текст во всём текущем абзаце. Абзацы в тексте разделяются пустыми строками.

Если абзацы в вашем файле правильно разделены, то вы можете переформатировать весь файл по команде:

gggqG

"gg" перемещает курсор к первой строке, "gqG" выполняет форматирование до последней строки.

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

Vim позволяет также изменять формат не только у простого текста. Подробнее об этом смотрите |fo-таблица|. Также см. справку по опции 'joinspaces', которая позволяет настраивать количество пробелов, используемое после точки.

Для форматирования можно также использовать внешнюю программу, что может быть полезным, если встроенные средства Vim не позволяют правильно отформатировать ваш текст. См. справку по опции 'formatprg'.


25.2 Выравнивание текста

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

:{диапазон}center [ширина]

В качестве {диапазона} задаётся обычный для командной строки диапазон строк. [ширина] является необязательным параметром, указывающим на ширину строки, которую следует использовать для форматирования, по умолчанию она равна значению 'textwidth'. (Если 'textwidth' равна 0, то [ширина] по умолчанию принимается равной 80).

Например:

:1,8center 40

приводит к следующему результату:

   Мы полюбили друг друга на ~
  новогоднем балу. Виталик был ~
   Дедом Морозом и очень мне ~
  понравился в этом образе. В ~
жизни же он оказался совсем не ~
весёлым человеком, и я с ~
  нетерпением жду следующий ~
       Новый Год. ~
ВЫРАВНИВАНИЕ ПО ПРАВОМУ КРАЮ

Команда ":right" выравнивает текст по правому краю:

:1,8right 30

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

     Мы полюбили друг друга на ~
  новогоднем балу. Виталик был ~
     Дедом Морозом и очень мне ~
   понравился в этом образе. В ~
жизни же он оказался совсем не ~
      весёлым человеком, и я с ~
     нетерпением жду следующий ~
             Новый Год. ~
ВЫРАВНИВАНИЕ ПО ЛЕВОМУ КРАЮ

Кроме того, имеется также команда

:{диапазон}left [поле]

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

:1left 5
:2,8left

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

     Мы полюбили друг друга на ~
новогоднем балу. Виталик был ~
Дедом Морозом и очень мне ~
понравился в этом образе. В ~
жизни же он оказался совсем не ~
весёлым человеком, и я с ~
нетерпением жду следующий ~
Новый Год. ~
ПОЛНАЯ ВЫКЛЮЧКА ТЕКСТА

В Vim нет встроенных средств для выполнения полной выключки текста (т.е. выравнивания границ текста слева и справа). Однако, существует неплохой макрос, который отлично справляется с этой задачей. Для использования макроса надо выполнить команду

:runtime macros/justify.vim

Этот сценарий Vim определяет новую визуальную команду: "_j". Для выравнивания текста по обоим краям, требуется выделить текст в Визуальном режиме и выполнить команду "_j".

Более подробно об этом макросе можно посмотреть в самом файле сценария. Выполните команду "gf" на имени файла: $VIMRUNTIME/macros/justify.vim.

Альтернативным вариантом может быть использование внешней команды-фильтра, например:

:%!fmt

25.3 Отступы и табуляция

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

первая строка ~
вторая строка ~

Для ввода этого текста используется нажатие символа табуляции, затем ввод строки текста, <Enter>, табуляция, ввод следующей строки текста и т.д.

Опция 'autoindent' позволяет вставлять отступы автоматически:

:set autoindent

Каждая новая строка при этом автоматически вводится с тем же отступом, что и предыдущая. В приведённом выше примере, нажатие клавиши табуляции после ввода <Enter> больше не потребуется.

УВЕЛИЧЕНИЕ ОТСТУПА

Для увеличения отступа, используйте оператор ">". Часто также используется команда ">>", которая увеличивает отступ у текущей строки.

Количество пробелов, добавляемых в начало строки, определяется значением опции 'shiftwidth'. По умолчанию это значение равно 8. Для того, чтобы команда ">>" делала отступы по 4 пробела, введите команду

:set shiftwidth=4

Применив команду ">>" на второй строке нашего текста, мы получим:

первая строка ~
    вторая строка ~

"4>>" позволяет увеличить отступ у четырёх строк сразу.

ШИРИНА ТАБУЛЯЦИИ

Если вы хотите сделать отступы кратными 4, то для этого надо установить значение опции 'shiftwidth' равным 4. Однако, нажатие кнопки табуляции по прежнему будет приводить к появлению отступа шириной в 8 символов. Для изменения этого значения, пользуйтесь опцией 'softtabstop':

:set softtabstop=4

Теперь нажатие на кнопку <Tab> будет приводить к вставке 4 пробелов. Если перед этим уже имеется 4 пробела, то будет вставлен символ <Tab>, что позволяет сделать размер файла на 7 байтов меньше. Если вам хочется, чтобы все символы табуляции всегда заменялись на пробелы, то включите опцию 'expandtab'.

Замечание: Вы можете также установить значение опции 'tabstop' равным 4, но если позднее вы будете редактировать этот файл со значением опции 'tabstop' равным 8, то файл будет выглядеть не так, как вы ожидаете. Кроме того, отступы будут выглядеть неправильно при печати и в других программах. Поэтому, рекомендуется всегда устанавливать значение опции 'tabstop' равным 8, поскольку это значение является стандартным.

ИЗМЕНЕНИЕ ТАБУЛЯЦИИ

Вы редактируете файл, в котором использовалось значение опции 'tabstop', равное 3. Вы пользуетесь стандартным значением этой опции, 8, и поэтому файл в редакторе выглядит безобразно. Можно было бы исправить положение, временно установив значение опции 'tabstop' равным 3, но это пришлось бы делать каждый раз, когда вы редактируете этот файл.

Vim может изменить значение ширины табуляции, используемое в файле. Прежде всего установите значение 'tabstop', затем используйте команду ":retab":

:set tabstop=3
:retab 8

Команда ":retab" изменит значение 'tabstop' в 8, попутно изменяя форматирование текста соответствующим образом. Она изменяет весь пробельный материал, используя необходимое сочетание символов табуляции и пробелов. После выполнения этой операции можно сохранить файл, чтобы при редактировании в следующий раз все отступы были на месте.

Предупреждение: При использовании команды ":retab" в тексте программы возможна ситуация, при которой пробельный материал будет изменён в строковой константе. Поэтому, вместо настоящего пробела в строковых константах лучше использовать "\t".


25.4 Работа с длинными строками

Иногда вам придётся столкнуться с ситуацией, когда вы редактируете файл, в котором строки длиннее, чем количество колонок в окне. Vim может переносить строки, чтобы они убирались в окне.

Если вы отключите опцию 'wrap', то строки переноситься не будут. Окончания длинных строк будут теряться за правой границей окна.

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

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

:set guioptions+=b

Теперь на экране отображается горизонтальная полоса прокрутки.

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

zh прокрутка вправо
4zh прокрутка на четыре символа вправо
zH прокрутка вправо на половину ширины экрана
ze прокрутка вправо до положения курсора
zl прокрутка влево
4zl прокрутка на четыре символа влево
zL прокрутка влево на половину ширины экрана
zs прокрутка влево до положения курсора

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

                      |<--  текущее окно  -->|
        длинная строка текста, частично умещающаяся в окне ~
ze          |<--           окно      -->|
zH           |<--      окно     -->|
4zh                  |<--            окно      -->|
zh                     |<--      окно          -->|
zl                       |<--         окно            -->|
4zl                          |<--            окно      -->|
zL                                |<--          окно      -->|
zs                               |<--         окно            -->|
ПЕРЕМЕЩЕНИЕ С ОТКЛЮЧЕННЫМ ПЕРЕНОСОМ СТРОК

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

g0 к первому видимому символу на текущей строке
g^ к первому видимому непробельному символу на текущей строке
gm к середине строки
g$ к последнему видимому символу в текущей строке
        |<--          окно     -->|
длинная строка текста, частично умещающаяся в окне ~
    g0 g^    gm          g$
ПЕРЕНОС ПО СЛОВАМ

Если вы готовите текст для использования в другой программе, то вам возможно захочется, чтобы абзацы не содержали лишних переносов строки. При использовании опции 'nowrap' вы не сможете видеть предложения целиком, а при включённой опции 'wrap' слова будут переноситься в середине слова, что осложняет работу над текстом.

Хорошим решением при редактировании такого текста будет использование опции 'linebreak'. Vim в этом случае будет переносить слова при просмотре текста в подходящих местах, например, на пробелах, а текст в самом файле останется без изменений.

Без включённой опции 'linebreak' текст в окне может выглядеть так:

+---------------------------------+
|исподлобья глянул на Фёдора и зве|
|зданул его по больному уху. Фёдор|
|, не утерпев, ответил ударом в по|
|ддыхало. Максим, превозмогая боль|
|, продолжил урок -- дал Фёдору в |
+---------------------------------+

После выполнения команды:

:set linebreak

Текст будет выглядеть следующим образом:

+---------------------------------+
|исподлобья глянул на Фёдора и    |
|звезданул его по больному уху.   |
|Фёдор, не утерпев, ответил ударом|
|в поддыхало. Максим, превозмогая |
|боль, продолжил урок -- дал      |
+---------------------------------+

Другие опции:

  • 'breakat' перечисляет символы, на которых возможен перенос строки.
  • 'showbreak' определяет строку, которая должна быть показана в начале перенесённой строки.
  • Чтобы длинные строки в абзацах не переносились, установите значение опции 'textwidth' равным нулю.
ПЕРЕМЕЩЕНИЕ ПО ВИДИМЫМ СТРОКАМ

Команды "j" и "k" перемещают курсор к следующей и предыдущей строке. При перемещении по длинным строкам это может привести к перемещению на полэкрана за один раз.

Для перемещения на одну строку экрана вверх или вниз можно использовать команды "gj" и "gk". Если строка не переносится, то эти команды работают точно так же, как и команды "j" и "k". Различие проявляется на перенесённых строках, в этом случае эти команды перемещают курсор по вертикали на одну экранную строку, вместо перемещения к следующей или предыдущей строке текста.

Вам может понравиться использовать такие привязки для удобства использования этих команд:

:map <Up> gk
:map <Down> gj
УДАЛЕНИЕ ПЕРЕНОСОВ СТРОКИ ВНУТРИ АБЗАЦА

Если вы хотите импортировать текст в MS-Word или другую подобную программу, то вам понадобится сделать каждый абзац текста одной строкой. Если ваши абзацы разделены пустыми строками, то можно использовать для этой операции такую команду:

:g/./,/^$/join

Давайте посмотрим, что происходит. Разберём эту команду по частям:

:g/./ Команда ":global" находит все строки, которые содержат хотя бы один символ.
     ,/^$/ Диапазон, начинающийся от текущей (непустой) строки до следующей пустой строки.
          join Команда ":join" объединяет указанные в диапазоне строки в одну строку.

Посмотрим, что сделает эта команда с текстом, состоящим из семи строк, разорванных в 30 колонке символом перевода строки:

+----------------------------------+
|Протокол IPX/SPX является быстрым |
|маршрутизируемым протоколом для   |
|небольших сетей, но у него есть   |
|недостаток -- он разработан фирмой|
|Novell...                         |
|                             |
|"Секреты Windows NT 4.0 Server"   |
+----------------------------------+

В итоге у нас получится две строки:

+----------------------------------+
|Протокол IPX/SPX является быстрым |
|маршрутизируемым протоколом для не|
|больших сетей, но у него есть недо|
|статок -- он разработан фирмой Nov|
|ell...                            |
|"Секреты Windows NT 4.0 Server"   |
+----------------------------------+

Замечание: эта команда не будет работать, если разделяющая абзацы строка не пустая, даже если она состоит из одних пробелов или символов табуляции. Команда, которая работает с пробельными строками в качестве разделителей абзаца, выглядит так: :g/\S/,/^\s*$/join

В конце файла должна находиться пустая или пробельная строка, иначе последний абзац обработан не будет.


25.5 Редактирование таблиц

Допустим, вы редактируете таблицу с четырьмя колонками:

nice table      test 1    test 2        test 3 ~
input A         0.534 ~
input B         0.913 ~

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

Для подобного рода случаев существует специальная опция:

set virtualedit=all

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

Переместите курсор в необходимую позицию введя команду поиска заголовка последней колонки:

/test 3

Теперь нажмите "j" и вы окажетесь в позиции, где нужно ввести значение для строки "input A". Введите "0.693":

nice table      test 1     test 2     test 3 ~
input A         0.534             0.693 ~
input B         0.913 ~

Vim автоматически заполняет пространство перед вставленным текстом требуемым количеством пробелов. Для заполнения следующей строки в этой колонке введите команду "Bj". "B" перемещает курсор в начало слова, "j" опускает курсор на одну строку вниз.

Замечание: В этом режиме курсор можно подвести в любое место экрана, в том числе за конец строки. Однако, Vim вставит в строку пробелы только в том случае, если вы вставите в этой позиции какой-либо текст.

КОПИРОВАНИЕ КОЛОНКИ

Теперь вам требуется добавить колонку, которая должна быть копией последней колонки, но размещена перед колонкой "test 1". Эта операция займёт семь шагов:

  1. Переместите курсор в левый верхний угол колонки, например с помощью команды поиска "/test 3".
  2. Перейдите в режим Визуального блока по команде CTRL-V.
  3. Переместите курсор на две строки вниз по команде "2j". Вы находитесь на месте "виртуального пробела": строка "input B" колонки "test 3".
  4. Переместите курсор вправо, чтобы выделить всю колонку целиком, включая необходимое пространство между колонками. Например, можно ввести для этой цели команду "9l".
  5. Скопируйте выделенный блок командой "y".
  6. Переместите курсор к колонке "test 1", где должна быть вклеена новая колонка.
  7. Нажмите "P".

Вот что должно получиться в результате:

nice table      test 3    test 1     test 2       test 3 ~
input A          0.693    0.534            0.693 ~
input B                0.913 ~

Обратите внимание, что вся колонка "test 1" была сдвинута вправо, включая ту строку, в которой в колонке "test 3" не было текста.

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

:set virtualedit=
РЕЖИМ ВИРТУАЛЬНОЙ ЗАМЕНЫ

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

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

inp    0.693   0.534    0.693 ~

       |
   rx  |
       V

inpx0.693  0.534    0.693 ~

Как видите, структура таблицы оказалась нарушена. Чтобы этого избежать, используйте команду "gr":

inp     0.693   0.534    0.693 ~

       |
  grx  |
       V

inpx    0.693   0.534    0.693 ~

Команда "gr" позволяет убедиться, что новый введённый символ занимает необходимое пространство. Для заполнения пустоты используется необходимое количество пробелов и символов табуляции. В действительности, символ табуляции заменяется на "x" и затем добавляется необходимое количество пробелов, чтобы текст после символа табуляции оставался на своём месте. В данном случае будет вставлен символ табуляции.

Если вам потребуется заменить несколько символов, то можно использовать команду "R" для перехода в режим замены (см. |04.9|). Но мы опять сталкиваемся с той же проблемой: структура таблицы нарушается и заменяются не те символы:

inp     0        0.534    0.693 ~

      |
R0.786 |
     V

inp     0.78634    0.693 ~

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

inp     0        0.534    0.693 ~

        |
gR0.786 |
        V

inp    0.786    0.534    0.693 ~

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