今读到 LinuxToy 上介绍 Tabular 的文章,不由得又折腾了下功能更加强大的 Align 插件。这个插件我装了很久了,也曾读过它的文档,但是实际用得却并不多,原因除了我一般写的时候就对齐好了之外,还有一点很重要——要让它精确地按照自己所希望的方式对齐一些文本可以,但得敲好长的命令,而且还需要思考,比如对齐CSS样式声明:Align! WP0p1l: :\@<=。
于是我就想,能不能把常用的对齐指令都以某种方式记录下来,需要时再调用。我首先想到的是映射或者命令。实际上Align自带了一个 AlignMapsPlugin.vim,其中就定义了很多常见的映射,但是不太容易记忆,而且不知道怎么添加。每种对齐方式定义个命令有点麻烦,于是就考虑用一个命令加参数的办法,于是就写了以下函数:
function Lilydjwg_Align(type) range try let pat = g:Myalign_def[a:type] catch /^Vim\%((\a\+)\)\=:E716/ echohl ErrorMsg echo "对齐方式" . a:type . "没有定义" echohl None return endtry call Align#AlignPush() call Align#AlignCtrl(pat[0]) if len(pat) == 3 call Align#AlignCtrl(pat[2]) endif exe a:firstline.','.a:lastline."call Align#Align(0, '". pat[1] ."')" call Align#AlignPop() endfunction
其中对齐样式的定义是这样子的:
let g:Myalign_def = { \ 'css': ['WP0p1l:', ':\@<=', 'v \v^\s*/\*|\{|\}'], \ }
Myalign_def的值是一个列表,各项分别是对齐方式的控制序列、分隔符正则、可选的用于筛选选区的控制序列。
想到以后定义的对齐方式多了之后,那些自定义的名字会有些不记得,于是补全函数不可少:
function Lilydjwg_Align_complete(ArgLead, CmdLine, CursorPos) return keys(g:Myalign_def) endfunction
现在函数和变量定义都有了,可以定义命令了:
command -nargs=1 -range -complete=customlist,Lilydjwg_Align_complete \ LA <line1>,<line2>call Lilydjwg_Align("<args>")
用的时候只要选中需要对齐的文本,然后按:LA 已定义的对齐方式名即可。
PS: Align 的中文对齐速度很慢,而且还有移动光标位置等“不良行为”,因此 patch 之:
--- autoload/Align.vim +++ autoload/Align.vim @@ -984,6 +984,11 @@ " nonzero value. Solution from Nicolai Weibull, vim docs " (:help strlen()), Tony Mechelynck, and my own invention. fun! s:Strlen(x) + " lilydjwg: vim7.3 有 strwidth 函数 + if exists('*strwidth') + return strwidth(a:x) + endif + " call Dfunc("s:Strlen(x<".a:x.">") if g:Align_xstrlen == 1 " number of codepoints (Latin a + combining circumflex is two codepoints) @@ -1006,6 +1011,8 @@ call setline(line("."),a:x) let ret= virtcol("$") - 1 d + " lilydjwg: 这样才不会让光标乱跑 + normal k let &l:mod= modkeep



