Вставка отступа для столбцов в Vim

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

Вставьте несколько интервалов после стрелок,

> one
> two
> three

можно выполнить с помощью <Ctrl-V>jjI <Esc>:

>   one
>   two
>   three
  • перейти в визуальный режим <Ctrl-V>,
  • расширить визуальный выбор jj,
  • вставьте пробелы I__,
  • распространить изменение на все строки блочного визуального выделения <Esc>

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

start() -- xxx
initialize() -- xxx
go() -- xxx

Теперь я хочу выровнять часть этого текста, чтобы упорядочить его в столбцы следующим образом:

start()       -- xxx
initialize()  -- xxx
go()          -- xxx

Проблема заключается в том, что я не могу вставить в каждую строку разное количество отступов, и просто отступы фиксированного количества пробелов/вкладок недостаточны. Как вы можете сделать отступ, где весь текст с отступом должен быть выровнен в одном столбце?


EDIT: я только вычислил довольно многословный и громоздкий метод:

  • найдите позицию строки с отступом: \--,
  • вставьте n (допустим, 20) пробелов до этого: 20i <Esc>,
  • удалите часть этих пространств обратно в определенный столбец (скажем, 15): d|15,
  • сохраните эти шаги в качестве макроса и повторите макрос как можно чаще,

... очень уродливо, хотя!

Ответ 1

Мне намного лучше без каких-либо плагинов vim. Вот мое решение:

<Shift-V>jj:!column -ts --

Затем вставьте -- в несколько строк так же, как вы писали в вопросе.


Вы также можете добавить несколько комментариев во время вставки.

:set virtualedit=all

<Ctrl-V>jjA-- xxx<Esc>

Ответ 2

Вы должны использовать определенный плагин, вы можете использовать Tabular или Align в этом случае.

Они оба позволяют выровнять текст по определенным символам, например -- в вашем примере. Их синтаксис немного отличается. Выберите тот, который вам больше всего подходит.

Ответ 3

Без плагина, и если вы уже ввели свои комментарии без решения emix:

:,+2 s/--/                                    &

Это обеспечит смещение всех комментариев влево, чтобы правильно их выровнять.

Затем поблочно выберите столбец, в который вы хотите выровнять текст, и: 100<

Ответ 4

Простым способом выравнивания текста в столбцах является использование Табличное или Выравнивание плагин. Если ни одна из них не готова под рукой, можно использовать следующие несколько сложный (и немного громоздкий), но отлично работает (для рассматриваемый случай) команды. 1,2

:let m=0|g/\ze -- /let m=max([m,searchpos(@/,'c')[1]])
:%s//\=repeat(' ',m-col('.'))

Цель первой команды - определить ширину столбца для слева от разделителя (который я предполагаю здесь --). Ширина рассчитывается как максимум длин текста в первом столбце среди все линии. Команда :global используется для перечисления строк содержащий разделитель (другие строки не требуют выравнивания). \ze атом, расположенный сразу после начала рисунка, устанавливает конец совпадают в том же месте, где он начинается (см. :help \ze). Изменение границы матча не влияют на работу команды :global, шаблон написан таким образом, чтобы соответствовать потребностям следующего команда подстановки: поскольку эти две команды могут использовать один и тот же шаблон, его можно опустить во втором.

Команда, выполняемая по согласованным строкам,

:let m=max([m,searchpos(@/,'c')[1]])

вызывает функцию searchpos() для поиска шаблона, используемого в родительском :global и получить позицию столбца совпадения. Шаблон называется @/ с использованием последнего регистра шаблона поиска (см. :help "/). Это использует тот факт, что команда :global обновляет / зарегистрируйтесь, как только он начнет выполнение. Флаг c прошел как второй аргумент в вызове searchpos() позволяет совпадение на первом символ строки (:global позиционирует курсор в самом начале строка для выполнения команды), потому что может быть, что нет текста слева от разделителя. Функция searchpos() возвращает список, первым элементом которого является номер строки согласованного положения, а вторая - позиция столбца. Если команда запущена на линии, линия соответствует шаблону содержащейся команды :global. Поскольку searchpos() для поиска того же шаблона, определенная совпадение на этой линии. Поэтому интересен только столбец, начинающий матч, поэтому он получает извлеченный из возвращаемого списка под индексом [1]. Это положение равно ширине текста в первом столбце строки, плюс один. Таким образом, m устанавливается на максимальное значение его текущего значения и положение столбца.

Вторая команда

:%s//\=repeat(' ',m-col('.'))

накладывает первое вхождение разделителя на все строки, которые содержат он, с количеством пробелов, которое отсутствует, чтобы сделать текст перед разделитель примет символы m, минус один. Эта команда является глобальной замену, заменяющую пустой интервал непосредственно перед разделителем (см. комментарий о команде :global выше) с результатом оценки выражение (см. :help sub-replace-\=)

repeat(' ',m-col('.'))

Функция repeat() повторяет свой первый аргумент (как строку) число времена, указанные во втором аргументе. Поскольку на каждой подстановке курсор переместился в начало совпадения шаблонов, m-col('.') равен точно количество пробелов, необходимых для сдвига разделителя вправо для выравнивания столбцов (col('.') возвращает текущую позицию столбца курсора).


1 Ниже приведена однострочная версия этой пары команд.

:let m=0|exe'g/\ze -- /let m=max([m,searchpos(@/,"c")[1]])'|%s//\=repeat(' ',m-col('.'))

2 В предыдущих версиях ответа команды были такими же следующим образом.

:let p=[0]|%s/^\ze\(.*\) -- /\=map(p,'max([v:val,len(submatch(1))+1])')[1:0]/
:exe'%s/\ze\%<'.p[0].'c -- /\=repeat(" ",'.p[0].'-col("."))'

Те, кто интересуется этими конкретными командами, могут найти подробные описание в истории изменений.

Ответ 5

Это модификация ответа Benoit, которая имеет два шага.

Первый шаг, блок select text search и replace - с большим количеством пробелов.

'<,'>s/--/                         --/

Теперь все комментарии должны иметь много пробелов, но все равно быть неравномерными.

Второй шаг, блок снова выберите текст и используйте другое регулярное выражение для соответствия всем символам, которые вы хотите сохранить (например, первые 20 символов), плюс все пробелы, следующие за ним, и замените его копией первых 20 символы:

'<,'>s/\(.\{20}\)\s*/\1/

Не так легко, как Бенуа, но я не мог понять, как сделать его второй шаг.