如何插入空格到列 X,以排列列中的东西?

我将复制操作符的源代码编写如下。

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,或类似的东西,可以让我使用一对按键每行排列的东西?

18675 次浏览

如果您正在使用一个类 Unix 的环境,您可以使用命令行工具 column。使用视觉模式标记线条,然后:

:'<,'>!column -t

这会在 '<,'>!之后将选定的文本粘贴到命令的 stdin 中。请注意,当您在可视化模式中命中 :时,会自动插入 '<,'>!

有一个很好的插件,其中做的正是这一点,并更多,所谓的 Align.vim

对于您的情况,您需要选择您的表达式,然后键入 :Align =。它将对齐一切,使用 =作为分隔符和引用。

(有很多选项可以对齐、左对齐、右对齐、周期性对齐等)

你也可以查看提供类似功能的 表格

这里的其他答案都很棒,尤其是@nelstrom 对 Tabar.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. 在热键 a中记录宏
  2. 转到行的开头
  3. f=——转到第一个等于号
  4. 100i <Esc>——(在 i后面有一个空格,<Esc>表示按 Esc 键,不要键入“ < Esc >”。)插入100个空格
  5. 8|——转到第8列(抱歉,您必须手动确定要对齐到哪一列)
  6. dw——删除直到下一个非空格字符
  7. 转到下一行
  8. 停止录音。

然后运行存储在热键 a的宏,3次(对于剩下的3行) ,将光标放在第二行并按下:

3@a

我们可以在下面的路径中为相同的场景使用这两个函数: https://stackoverflow.com/a/32478708/3146151

简单地把这两个函数放到你的。Vimrc 或者。Gvimrc,并随时在编辑器中将函数作为普通函数调用来调用。

我在这里发布的函数是: https://github.com/imbichie/vim-vimrc-/blob/master/MCCB_MCCE.vim

我们需要在 vim 编辑器中调用这个函数,并给出要移动的字符或空间的出现次数以及“和列号中的字符。

出现的次数可以从每行开始(MCCB 函数) ,也可以在每行结束(MCCE 函数)。

对于问题中提到的上面的例子,我们可以使用 MCCB 函数和我们可以使用’=’的字符,所以在 vim 编辑器中的用法是这样的。

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

因此,这将把第一个 =符号从第1行移动到第8列。

这些功能是:

" 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

我知道这很老套,但我认为@talklittle 的想法是正确的,答案只是变得冗长。更快捷的方法是在 = 后面插入空格,然后删除第10列后面的所有空格,如下所示:

   :1,4 s/^\(.*=\) *\(.*\)$/\1                           \2/
:1,4 s/^\(.\{10\}\) *\(.*\)$/\1\2/

一种快速、简单的方法是添加 X 空格,然后删除回列 X

40a<Space><Esc>d40|

另一种解决办法是执行两个连续的替换:

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

诀窍在于,列模式 \%>7c只匹配第7列后面的空白 *。这里的 foobar是最长的变量名,带有 6字符,所以我们需要在正则表达式中使用 7