在vim中将文本对齐到等号上

47

我倾向于在等号对齐代码以提高可读性。从这个例子:

$ = jQuery.sub()
Survey = App.Survey
Sidebar = App.Sidebar
Main = App.Main

变成这样:

$       = jQuery.sub()
Survey  = App.Survey
Sidebar = App.Sidebar
Main    = App.Main

在vim中有简单的方法可以做到这一点吗?

10个回答

48
到目前为止,我发现最好的插件是Tabular.vim
安装它的最简单方法是使用Pathogen插件,然后将Tabular git存储库克隆到~/.vim/bundle/tabular中。 Pathogen的完整说明在README中。
安装完成后,使用它只需要将光标放在您想对齐的段落中的任何位置,然后运行:
:Tab /=

3
这个插件很棒!在可视化模式下,你还可以输入 Tab 键来对齐高亮文本。 - ericraio

24

对于不需要安装插件的简单解决方案,只需通过Unix列命令进行过滤即可。

请注意,有两种方法可以做到这一点,具体取决于您的column命令是否支持-o

GNU column命令(Linux等)

:% ! column -t -s= -o=

就是这样。

BSD column 命令(Mac OS X等)

第一步,通过 column -t 进行筛选:

:% ! column -t

第二步,去除分隔符周围的填充:
:%s/ = /=/

初始文本为

$ = jQuery.sub()
Survey = App.Survey
Sidebar = App.Sidebar
Main = App.Main

在第一步之后,它变成了

$        =  jQuery.sub()
Survey   =  App.Survey
Sidebar  =  App.Sidebar
Main     =  App.Main

在第二步之后,
$       = jQuery.sub()
Survey  = App.Survey
Sidebar = App.Sidebar
Main    = App.Main

或者,如果你想一步完成:

:% ! column -t | sed 's/ = /=/'

更多信息请参考man column


3
很棒,不需要第三方工具!不知道为什么有人投反对票,因为它完全可行。 - tmck-code
2
值得注意的是,按照此答案的写法,它会对整个缓冲区/文件进行对齐。 如果您只想对缓冲区的一部分进行对齐,可以将%替换为范围(例如 :<range>! column -t -s= -o= ),或者只需选择所需部分,按 : 然后输入 ! column -t -s= -o= (这样您就应该得到 :'<,'>! column -t -s= -o= )。 - Cybolic
在我的macOS和BSD上,它只是抛出一个错误,而且使用该方法会让文件变得混乱。 - StevieD

17

这不是最简单的方法,但可以在没有任何插件的情况下完成。

  • 使用V:s/=/ =/在等号前插入一堆空格。
  • 使用Ctrl-V选择你想要移动等号符号到的列。
  • <<将每个等式的右侧“取消缩进”向你选择的列移动,然后重复按.直到等号符号排成该列。

我想我找到了一种更简单的方法。 :) - Alex Harvey
不,我的意思是我找到了一种新的方法,而无需安装插件,正如我在上面的新答案中所解释的那样。我不确定为什么你没有看到,但这是直接链接:https://dev59.com/o2ox5IYBdhLWcg3wyXVx#51462785 - Alex Harvey
我发现这是最好的解决方案。如果您有带空格的字符串,则@AlexHarvey无法正常工作。 - Hunaphu
@Hunaphu 如果你有GNU版本的column,我的解决方案将很好地工作。否则,请尝试向column传递“-s=”。 - Alex Harvey
我只能说这对我不起作用。 - Hunaphu
显示剩余3条评论

13

我相信使用 Tabular 插件就可以轻松完成此操作。 这里有演示。

在可视模式下选择范围(实际上不是必需的),然后执行以下操作:

:Tabularize /=

该插件通常可以自动找到正确的范围,而无需进行可视化选择或指定 ex 命令的范围。


4

一个替代 Tabular 的插件:

https://github.com/tommcdo/vim-lion

根据文档介绍:

For example, glip= will turn

$i = 5;
$username = 'tommcdo';
$stuff = array(1, 2, 3);

into

$i        = 5;
$username = 'tommcdo';
$stuff    = array(1, 2, 3);

2
vim-easy-align 插件也可以实现此功能。以下是其中一个示例:

vim easy align 命令示例


2
如果你需要快速对齐表达式,而不想安装和学习任何插件,可以使用以下快捷方式:
1. 选择要操作的行。例如,如果要对整个缓冲区进行操作,可以使用 `ggVG`,但是如果这些行在文件中间,则应适当选择。也许使用 `V4j`?
2. 在等号前插入足够的空格,可以使用 `:normal f=9i `。这将在可视选择的每一行的等号前添加 9 个空格。如果 9 不够多,请添加更多(如 99 或 999)。请注意,当您在可视选择中键入 `:` 时,Vim 将自动插入范围,因此实际命令是 `:'<,'>normal f=9i `,但您不需要键入这些字符。
3. 移动到您希望等号对齐的列。在这种情况下,第二行具有最长的变量名,因此移动到该名称的结尾后两个空格的位置,即等号应在其末尾的位置。如果这是整个缓冲区,请使用 `2G2e2l` 来移动。
4. 保持在同一列上,移动到块的第一行。在这种情况下,您正在从第二行移动到第一行,因此只需按 `k` 即可。
5. 开始可视块选择,按下 `Ctrl-V`。
6. 移动到块的最后一行。如果这是整个缓冲区,请使用 `G`,如果这是文件的中间,则可以使用 `4j` 向下移动四行等。
7. 现在,您可以使用 `<` 命令将行向左移动,直到它们达到可视块的左侧。每个 `<` 只会将其向左移动一个 `'shiftwidth'`,因此您可能需要多次移动。因此,为确保操作正确,请使用 `9<`(或 `99<`,或 `999<`,如果您在第 2 步中添加了大量空格)。
完成!这是一种非常酷的技术,当您需要比插件更灵活的操作时,它会很有帮助。这是一个很好的技巧,可以放入您的 Vim 工具箱中。

如果您想根据不同的标准进行对齐,而不仅仅是=,那么这个方法也非常灵活。例如,如果您想要根据每行的第三列(第三个单词)进行对齐,则在步骤2中使用:normal 2W9i


2
您可以使用 Align Vim 插件 来对这些块进行对齐,例如通过键入
vip:Align =

在命令模式下,当光标位于待对齐块内时。

在此处使用vip进入虚拟模式并选择当前段落。 Align命令非常强大,例如您还可以指定多个模式,模式会被解释为正则表达式等。

2
通过在vimrc中添加一行代码,你只需要选择文本并输入相应的命令即可。
:Aleq

将以下内容添加到你的vimrc文件中:

command! -range Aleq execute <line1>.",".<line2> . "! sed 's/=/PXXXQYYY/'| column -t -s 'PXXX'| sed 's/QYYY\s*/= /'"

说明:

上述代码等同于输入

'<,'>! ! sed 's/=/PXXXQYYY/'| column -t -s 'PXXX'| sed 's/QYYY\s*/= /'
  1. -range 给出了当前选择的范围
  2. 将第一个 = 替换为 PXXXQYYY,不要触及其他 =。
  3. 基于 -s 'PXXX' 创建列,移除 PXXX 并保留 QYYY
  4. 通过替换 QYYY 来放回第一个 =。移除不必要的空格

更新:现在支持多个 =。


0

安装tabularize插件并修改由tpope创建的代码片段,使其类似于以下内容:

inoremap <silent> :   :<Esc>:call <SID>align(':')<CR>a
inoremap <silent> =   =<Esc>:call <SID>align('=')<CR>a

function! s:align(aa)
  let p = '^.*\s'.a:aa.'\s.*$'
  if exists(':Tabularize') && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p)
    let column = strlen(substitute(getline('.')[0:col('.')],'[^'.a:aa.']','','g'))
    let position = strlen(matchstr(getline('.')[0:col('.')],'.*'.a:aa.':\s*\zs.*'))
    exec 'Tabularize/'.a:aa.'/l1'
    normal! 0
    call search(repeat('[^'.a:aa.']*'.a:aa,column).'\s\{-\}'.repeat('.',position),'ce',line('.'))
  endif
endfunction

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接