2
24
2011
10

让 Vim 的 Align 插件记住常用的对齐方式

本文来自依云's Blog,转载请注明。

今读到 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

 

Category: Vim | Tags: vim | Read Count: 22088
zbinlin 说:
Feb 25, 2011 03:05:14 AM

你好,博主!
刚用上 Align,有个问题想请教博主。
需要处理对齐的代码如下:
@name foo bar test
@discript foobar
@email foo@gmail.com
我需要的效果是
@name foo bar test
@discript foobar
@email foo@gmail.com
如果使用 <leader>tsp,出现的效果是
@name foo bar test
@discript foobar
@email foo@gmail.com
有没办法达到我预期的效果,谢谢!

zbinlin 说:
Feb 25, 2011 03:08:29 AM

怎么中间的空格都没了?
用 - 代码空格来说明吧:
@name-----foo-----------bar-test
@discript-foobar
@email----foo@gmail.com

预期效果是:
@name-----foo-ar-test
@discript-foobar
@email----foo@gmail.com

Avatar_small
依云 说:
Feb 25, 2011 05:45:25 AM

'<,'>Align! P0p1l: \S\@<=\s\@=

: 表示从这里开始到行尾作为一个域来对待。

多个空格被显示为一个是 HTML 的特性,查看源代码可以看到。

Avatar_small
依云 说:
Feb 25, 2011 06:25:19 AM

&  <  > 会被转义的 ;-)

zbinlin 说:
Feb 25, 2011 06:32:45 AM

Align 的分隔符是支持正则表达式的呀!
唉,一看到英文的帮助文件就头疼。要是有能翻译成中文就好了。这个插件真的不错!
回复里支持直接写 HTML 代码吗?

Avatar_small
依云 说:
Feb 25, 2011 08:40:14 AM

不支持 HTML 的。

搞技术的,不会英文不行啊。闲耘(hotoo)在组织翻译一些Vim插件的文档,你可以去看看。

zbinlin 说:
Feb 25, 2011 11:24:17 AM

是呀!目前在边学英语边学技术。。。
再次感谢!

Dante 说:
Mar 29, 2011 06:25:32 PM

哈哈,搜align搜到这来啦~

Avatar_small
依云 说:
Mar 29, 2011 10:48:15 PM

呵呵,看来我的博客渐渐地有点名气了?


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

| Theme: Aeros 2.0 by TheBuckmaker.com