如何在列X之间插入空格以排列列中的内容?

时间:2011-05-27 15:19:55

标签: vim

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

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 个答案:

答案 0 :(得分:98)

这里的其他答案都很棒,特别是@ 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. 中录制一个宏
  3. 0 - 转到第
  4. 行的开头
  5. f= - 转到第一个等号
  6. 100i <Esc> - (i后面有一个空格,而<Esc>表示按下转义符,请不要输入“&lt; Esc&gt;”。)插入100个空格< / LI>
  7. 8| - 转到第8列(抱歉,您必须手动找出要对齐的列)
  8. dw - 删除直到下一个非空格字符
  9. j - 转到下一行
  10. q - 停止录制。
  11. 然后运行存储在热键a中的宏,3次(对于其余3行),将光标放在第二行并按:

    3@a
    

答案 1 :(得分:24)

如果您使用的是类似unix的环境,则可以使用命令行工具column。使用可视模式标记您的线条,然后:

:'<,'>!column -t

这会在'<,'>!之后将所选文本粘贴到命令的标准输入中。请注意,在视觉模式下点击'<,'>!时会自动插入:

答案 2 :(得分:19)

有一个很好的插件可以完成,更多,称为Align.vim

对于您的情况,您需要选择表达式,然后键入:Align =。它会使用=作为分隔符和参考来对齐所有内容。

(有很多选项可以对齐,左,右,循环等)

您还可以查看提供类似功能的Tabular.vim。有关演示,请参见截屏视频there

答案 3 :(得分:6)

一种快速,简单的方法是添加X空格,然后删回回X列。例如,如果X = 40,则键入

40a<Space><Esc>d40|

答案 4 :(得分:1)

我们可以将以下路径中描述的这两个函数用于同一场景:https://stackoverflow.com/a/32478708/3146151

只需将这两个函数放在.vimrc或.gvimrc中,并在编辑器中随时调用函数作为普通函数调用。

我在此处发布的功能:https://github.com/imbichie/vim-vimrc-/blob/master/MCCB_MCCE.vim

我们需要在vim编辑器中调用此函数,并给出要移动的角色或空间的出现次数以及&#39;&#39;中的字符。和列号。

出现的次数可以从每一行的起点(MCCB功能)开始,也可以在每一行的末尾(MCCE功能)。

对于问题中提到的上述示例,我们可以使用MCCB函数和我们可以使用的字符&#39; =&#39;,因此在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

答案 5 :(得分:0)

我知道这已经过时了,但我认为@talklittle有正确的想法,答案刚刚变得冗长。更快捷的方法是在=之后插入空格,然后删除第10列之后的所有空格,如下所示:

0xffffffffbb804f8b <error_entry+91>:    data32 xchg %ax,%ax
0xffffffffbb804f8e <error_entry+94>:    jmpq   0xffffffffbb804f98 <error_entry+104>

答案 6 :(得分:0)

另一种解决方案是执行两次连续替换:

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

技巧是列模式\%>7c仅在第7列之后匹配空格 *。此处foobar是包含6字符的最长变量名称,因此我们在正则表达式中需要7