Выровнять текст только по первому разделителю в VIM

Предположим, у меня есть этот код:

width: 215px;
height: 22px;
margin-top: 3px;
background-color: white;
border: 1px solid #999999;

Я хочу выровнять его следующим образом:

width:            215px;
height:           22px;
margin-top:       3px;
background-color: white;
border:           1px solid #999999;

используя Align.vim, я могу сделать :Align \s, чтобы использовать пробел в качестве разделителя, но это имеет 2 проблемы

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

Я прочитал множество вариантов, предлагаемых Align.vim, но не нашел способа сделать это.


person Matteo Riva    schedule 25.01.2010    source источник
comment
Небольшие, но относительно универсальные приемы выравнивания, которые работают без плагинов, см. в ответе на вопрос Вставка отступов для столбцов в Vim.   -  person ib.    schedule 03.12.2011


Ответы (4)


Если вы используете Tabular, вы можете просто сделать :Tabularize /:\zs/.

Глядя на описание Align на vim.org, аналогичный вызов должен работать для него. Вы можете попробовать :Align :\zs. Я не использую Align, поэтому я не уверен.

person jamessan    schedule 25.01.2010
comment
Да, это работает с Align. Вы можете использовать :AlignCtrl l: (или аналогичный), чтобы игнорировать любые дальнейшие двоеточия. - person Michał Marczyk; 25.01.2010
comment
Кто-нибудь может объяснить, что означает \zs? - person kizzx2; 07.07.2011
comment
Использование \zs сопоставит все, что было до \zs, но вернет его в результаты. То есть он оставит все, что у вас есть до \zs, нетронутым (точно так же, как если бы вы поместили группу (...) вокруг него и сначала использовали \1 в замене. См. :h /\zs - person Adam Lindberg; 22.11.2011

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

qa0f:w100i <Esc>19|dwjq4@a

Обратите внимание на один пробел после 100i, а ‹Esc› означает «нажмите escape» — не вводите «‹Esc›» буквально.

Перевод:

qa         -- record macro in hotkey a
0          -- go to beginning of line
f:         -- go to first : symbol
w          -- go to next non-space character after the symbol
100i <Esc> -- insert 100 spaces
19|        -- go to 19th column (value 19 figured out manually)
dw         -- delete spaces until : symbol
j          -- go to next line
q          -- stop recording macro
4@a        -- run the macro 4 times (for the remaining 4 lines)

И да, я использовал аналогичный макрос для форматирования приведенного выше блока кода :)

Ср. мой ответ на аналогичный вопрос о выравнивании Vim.

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

:norm!@a
person TalkLittle    schedule 02.12.2011
comment
здорово, что вы последовали за объяснением - без него я бы не посмел напечатать это волшебное заклинание, опасаясь за свою душу и содержимое диска, но с ним я даже узнаю несколько новых интересных (хотя и извращенных) команд vim! - person akavel; 16.11.2012
comment
@TalkLittle отличное использование решения без плагинов, которое не требует никаких дополнительных надстроек. Отличное использование команды vim с комментариями для помощи новым пользователям. Вся хорошая практика в поддержке и объяснении возможностей нативного vim. - person dreftymac; 30.03.2016

Используйте алгоритм @TalkLittle, это можно сделать с помощью этого кода, который мне немного проще для глаз :)

  • добавить достаточно пробелов после первого двоеточия

    :%s/^[^:]:\zs/много пробелов/

  • но если постоянное нажатие пробелов причиняет боль большому пальцу, используйте это вместо этого

    :%s/^[^:]:\zs/\=repeat(' ',100)/

  • затем удалите все пробелы после столбца 19

    :%s/\%19v\s*//

    ПРИМЕЧАНИЕ. % сделает это во всех строках, укажите диапазон, если вы этого не хотите.

  • если вам не хочется считать до 19, используйте это:

    %s/:\zs.*// | %s/.*/\=len(submatch(0))/ | sort! n | let n=getline(1) | undo | echo 'the column nmuber of the right most ":" is' n

person ipirlo    schedule 08.04.2013
comment
дополнительные баллы за решение, не требующее никаких плагинов - person dreftymac; 30.03.2016

Вы по-прежнему можете сделать это с помощью предпочитаемого вами плагина Align.vim с помощью команды:

Align! lp0P0: \s

Align! означает, что первый аргумент имеет формат AlignCtrl, где вы заказываете, чтобы первое совпадение было выровнено по левому краю (l) без заполнения пробелами (p0P0), а также вы хотите пропустить (:) все последующие совпадения. Этот пример может быть расширен для более сложных выравниваний.

person mrajner    schedule 18.10.2017
comment
У меня аналогичный вопрос, но я не хочу заполнять вопрос ОП. Я попытался изменить ваш ответ как: Align! 1: и: Выровнять! 1:\s и :Align 1: и т.д., но не нашел, как использовать что-то похожее на ваш ответ, чтобы заставить Align выравниваться только по поводу первого:. Как бы я это сделал? - person Shawn; 15.07.2020