Как вставить пробелы до столбца X, чтобы выровнять вещи в столбцах? - PullRequest
58 голосов
/ 27 мая 2011

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

foo = rhs.foo;
foobar = rhs.foobar;
bar = rhs.bar;
toto = rhs.toto;

Я бы хотел выстроить все в ряд следующим образом (более читабельно, не так ли?).

foo    = rhs.foo;
foobar = rhs.foobar;
bar    = rhs.bar;
toto   = rhs.toto;

Есть ли в VIM волшебная вставка-до-столбца-N или что-то в этом роде, которое позволило бы мне выстроить строку, используя пару нажатий клавиш на строку?

Ответы [ 7 ]

101 голосов
/ 03 декабря 2011

Другие ответы здесь великолепны, особенно комментарий @ nelstrom для Tabular.vim и его превосходный скринкаст.

Но если бы мне было лень устанавливать какие-либо плагины Vim, но я все же хотел использовать макросы Vim, я бы использовал макросы.

Алгоритм:

For each line,
    Add tons of spaces before the symbol =
    Go to the column you want to align to
    Delete all text up to =, thereby shifting the = into the spot you want.

Для вашего примера,

foo = rhs.foo;
foobar = rhs.foobar;
bar = rhs.bar;
toto = rhs.toto;

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

qa0f=100i <Esc>8|dwjq

Что означает:

  1. qa - запись макроса в горячую клавишу a
  2. 0 - перейти к началу строки
  3. f= - перейти к первому знаку равенства
  4. 100i <Esc> - (После i есть один пробел, а <Esc> означает нажатие клавиши, не вводите "".) Вставьте 100 пробелов
  5. 8| - перейти к восьмому столбцу (извините, вам придется вручную выяснить, к какому столбцу выровнять)
  6. dw - Удалить до следующего непробельного символа
  7. j - перейти к следующей строке
  8. q - остановить запись.

Затем запустите макрос, сохраненный по горячей клавише a, 3 раза (для 3 оставшихся строк), поместив курсор на вторую строку и нажав:

3@a
25 голосов
/ 27 мая 2011

Если вы используете Unix-подобную среду, вы можете использовать инструмент командной строки column.Пометьте свои строки, используя визуальный режим, затем:

:'<,'>!column -t

Вставляет выделенный текст в стандартный ввод команды после '<,'>!.Обратите внимание, что '<,'>! вставляется автоматически, когда вы нажимаете : в визуальном режиме.

19 голосов
/ 27 мая 2011

Есть хороший плагин, который делает именно это и даже больше, он называется Align.vim

В вашем случае вам нужно будет выбрать выражение и затем набрать :Align =. Он выровняет все, используя = в качестве разделителя и ссылки.

(есть много вариантов выравнивания: слева, справа, циклически и т. Д.)

Вы также можете проверить Tabular.vim , который предоставляет аналогичные функции. Смотрите скринкаст там для демонстрации.

6 голосов
/ 19 июля 2017

Быстрый и простой способ - добавить X пробелов и затем удалить их обратно в столбец X. Например, если X = 40, введите

40a<Space><Esc>d40|
1 голос
/ 10 марта 2018

Альтернативное решение - выполнить две последовательные замены:

%s/=/     =/
%s/\%>7c *//

Хитрость - это шаблон столбца \%>7c, который соответствует пробелам * только после 7-го столбца.Здесь foobar - самое длинное имя переменной с 6 символами, поэтому нам нужно 7 в регулярном выражении.

1 голос
/ 14 сентября 2015

Мы можем использовать эти две функции, которые я описал в приведенном ниже пути для одного и того же сценария: https://stackoverflow.com/a/32478708/3146151

просто поместите эти две функции в ваш .vimrc или .gvimrc и вызовите функции как обычный вызов функциив вашем редакторе всякий раз, когда вы захотите.

Функции, которые я разместил здесь: https://github.com/imbichie/vim-vimrc-/blob/master/MCCB_MCCE.vim

Нам нужно вызвать эту функцию в редакторе vim и дать число вхождений символа или пробелачто вы хотите переместить и символ внутри '' и номер столбца.

Номер вхождения может быть от начала каждой строки (функция MCCB) или может быть в конце каждой строки (MCCEfunction).

для вышеприведенного примера, упомянутого в вопросе, мы можем использовать функцию MCCB и символ, который мы можем использовать '=', поэтому использование будет таким же в редакторе vim.

:1,4call MCCB(1,'=',8)

Таким образом, первый знак = переместится в восьмой столбец из строки № 1 в 4.

Это функции:

" MCCB - Move the Character to the Column from the Begin of line
" This is a function for Moving the specified Character 
" in a given range of lines to a the specified Column from the Begin of the line
" NOTE 1 :- If the specified character and the first character of the line are same
"           then the number of Occurance (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range 
"           of lines should be less than or equal to 80, if we need more than 80
"           then we need to insert more spaces by increasing the value 80 in the 
"           "nmap s 80i <ESC>" line inside the function
" Usage :-  in command mode do it like below
" Eg 1:-    :5,11call MCCB(1, '=', 8)
"           The above command will move the 1st Occurance from the begin of Character =
"           to the 8th Column of the lines from 5 to 11
" Eg 2 :-   :7,10call MCCB(2, '+', 12)
"           The above command will move the 2nd Occurance of Character = to the 12th
"           Column of the lines from 7 to 10
    function! MCCB (num_occr, mv_char, col_num) range
        if (a:firstline <= a:lastline)
            nmap s 80i <ESC>
            let line_num = a:firstline
            while line_num <= a:lastline
                execute "normal " . line_num . "G0" . a:num_occr . "f" . a:mv_char . "s" . a:col_num . "|dw"
                let line_num = line_num + 1
            endwhile
            nunmap s
        else
            execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
        endif
    endfunction

" MCCE - Move the Character to the Column from the End of line
" This is a function for Moving the specified Character 
" in a given range of lines to a the specified Column from the End of the line
" NOTE 1 :- If the specified character and the last character of the line are same
"           then the number of Occurance (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range 
"           of lines should be less than or equal to 80, if we need more than 80
"           then we need to insert more spaces by increasing the value 80 in the 
"           "nmap s 80i <ESC>" line inside the function
" Usage :-  in command mode do it like below
" Eg 1:-    :5,11call MCCE(1, ';', 20)
"           The above command will move the 1st Occurance from the End of Character ;
"           to the 20th Column of the lines from 5 to 11
" Eg 2 :-   :7,10call MCCE(5, 'i', 26)
"           The above command will move the 5th Occurance from the End of Character i
"           to the 26th Column of the lines from 7 to 10
    function! MCCE (num_occr, mv_char, col_num) range
        if (a:firstline <= a:lastline)
            nmap s 80i <ESC>
            let line_num = a:firstline
            while line_num <= a:lastline
                execute "normal " . line_num . "G$" . a:num_occr . "F" . a:mv_char . "s" . a:col_num . "|dw"
                let line_num = line_num + 1
            endwhile
            nunmap s
        else
            execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
        endif
    endfunction
0 голосов
/ 13 июля 2017

Я знаю, что это старо, но я подумал, что у @talklittle была правильная идея, ответ стал многословным. Более быстрый способ - вставить пробелы после =, а затем удалить все пробелы после 10-го столбца следующим образом:

   :1,4 s/^\(.*=\) *\(.*\)$/\1                           \2/
   :1,4 s/^\(.\{10\}\) *\(.*\)$/\1\2/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...