11

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

 3 years ago
source link: https://blog.lilydjwg.me/2011/2/24/remember-common-align-patterns-in-vim.24706.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

让 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

发送到 Kindle


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK