10
31
2011
16

在 Linux 下交叉编译带 Python 3 支持的 gvim.exe

今天再一次在 yaourt 的输出中瞥见 mingw 这几个字符,好奇地看了下说明:A C and C++ cross-compilers for building Windows executables on Linux。这个不就是传说中的交叉编译器么?

试试看。以前自己在虚拟机里为 Windows 编译过很多次的 vim,要是能弄到真机下来编译效率应该会高很多。(不,我不是说虚拟机的性能差,而是 Windows 下跑 mingw 这种一堆进程的东西效率差。)

说干就干,几十 M 的 mingw-gcc 及其依赖下好,git archive all|tar x -C ~tmp/vim弄份崭新的 vim 源码,把以前在 win 下用的Make_ming.mak拷过来改改,设置CROSS=yes什么的,然后开始编译!然后很快就出错了,找不到编译器i586-pc-mingw32msvc-gcc。唔,我确实没有那个东东,只有i486-mingw-gcc,去把CROSS_COMPILE这个变量改了就好。然后再 make。这一次的结局是——找不到 Python/Ruby/Lua 的头文件、找不到它们中的符号……好吧,你这交叉编译器当然找不到它们,先注释掉好了。然后重新编译,很顺利地出来个 gvim.exe 了~拿到 Windows 虚拟机里跑一下,一切正常~

好开心,第一次玩交叉编译就成功了。不过还有些小遗憾:没有那些外部脚本语言的支持。这可怎么办呢?我上哪儿找用于交叉编译的库呢?光想是没有用的,还是得尝试。用 Linux 版的库肯定不行,那就试试 Windows 版的。先拿 Python 3 支持测试。把 Windows 下安装的 Python 3 文件夹复制过来,修改下路径,再 make。很正常地,我的第一次尝试总是不成功,好在也不是大问题:Make_ming.mak里写的 include 目录不对:

ifeq ($(CROSS),no)
PYTHON3INC=-I $(PYTHON3)/include
else
PYTHON3INC=-I $(PYTHON3)/win32inc
endif

看看自己的 Python 3 目录,这里的win32inc应该是include。改改就好了 ;-)

嗯,顺利成功了!接下来,把 Windows 版的 Ruby 和 Lua 也弄过来就不用再跑到虚拟机里去编译 Windows 版的 Vim 了!嗯,NSIS 也有 Linux 版,虽然是在 AUR 里。

最后,编译好的 gvim 还是在这里

Category: Vim | Tags: vim windows 交叉编译 编译 linux
10
12
2011
27

Windows 版 gvim 7.3.333 打包/安装程序下载

下载链接在这里

好久没有编译 Windows 版 gvim 了。这次又编译了一次,同时支持 Python 2.7 和 Python 3.2 的,并且可以同时使用哦!另外还弄了个安装包出来,不过 Vim 自带的那个 NSIS 配置文件nsis/gvim.nsi似乎过时很久了,编译的时候各种错误。于是第一次接触 NSIS 的我就不得不去改那个配置文件。令人郁闷的是,NSIS 和 make 不同,每次重新编译时它都要全部重新处理一遍!最终弄出来后还发现没有多语言翻译的消息文件。于是装上 gettext,去src/po下 make 了,却发现不知道怎么改 NSIS 配置来处理这些.mo文件的重命名问题。于是只好放弃,另用 7zip 打包了一个包含消息文件的版本。

最后吐槽下,下载 NSIS 和 gettext 等时,正好遇到 SourceForge 故障,下载地址返回了条 JSON 消息:

{
    "error": true
}

还是被 JSONView 插件格式化好的。。。


2011年10月31日更新:搞定了交叉编译,于是安装包的语言支持被我用 shell 脚本搞定了!

Category: Vim | Tags: vim windows NSIS
10
7
2011
82

fcitx.vim 1.0 正式发布

Fcitx 输入法自动切换

在离开/重新进入插入模式时自动切换输入法状态,以便在普通模式下始终是英文输入模式,切换回插入模式时恢复离开时的输入法输入模式。状态为每个缓冲区单独保存,所以在中文文档和英文代码间交叉跳转编辑也得心应手!

无需任何配置!


要求:

fcitx 版本 3.6 以上,建议 fcitx 4.0 以上。建议关闭 fcitx 的预编辑输入功能,否则在 GVim 中可能会有问题(见评论;最新 git 版 fcitx 已经能够在 GVim 中自动禁用预编辑输入)。

注意事项:

1. Python 3 或者 Python 支持以获得更快更好的效果。注意对于 vim 版本<7.3.288,如果同时编译了 Python 2 & 3 支持,因为此 vim 不能同时运行两个版本的 Python,而本脚本首先检查 Python3,所以会导致出错或者 Python 2 不可用。

2. 终端下请设置 Vim ttimeoutlen 选项为较小值(如100),否则退出插入模式时会有较严重的延迟。同样会造成延迟的还有 screen 的 maptimeout 选项以及 tmux 的 escape-time 选项。

如果你需要跨主机使用 fcitx.vim,请参考此文

开发:

https://github.com/lilydjwg/fcitx.vim

安装:

解压到 ~/.vim 下即可。如果没有并且不准备使用 Python 接口,可只将 so/fcitx.vim 放到 ~/.vim/plugin 目录下。


插件地址http://www.vim.org/scripts/script.php?script_id=3764

Category: Vim | Tags: vim fcitx
8
24
2011
22

改变终端下的光标颜色,包括 screen 和 tmux!

曾经在Ubuntu中文论坛里看到一个改变光标颜色的方法,用光标颜色来指示是在 Vim 的普通模式还是插入模式下(因为 gnome-terminal 不支持使用转义序列改变光标形状)。Vim Wiki 上的 tip

if &term =~ "xterm\|rxvt"
  silent !echo -ne "\e]12;HotPink\007"
  let &t_SI="\e]12;RoyalBlue1\007"
  let &t_EI="\e]12;HotPink\007"
  autocmd VimLeave * :!echo -ne "\e]12;green\007"
endif

可惜它不适用于当时我正在使用的 screen。现在我改用 tmux 了,偶然改变TERM变量测试的时候,发现光标颜色竟然改变了——虽然还附带一些“不良反应”。我想到:一定有办法来正确地改变光标颜色的!

于是求助于 Google,很快找到了这个,有了用于 screen 的转义序列。不过依旧不适用于 tmux。把“tmux”也加到关键词里再搜,终于找到了这个。根据这个帖子,screen 和 tmux 比 xterm 多出来的那些字符序列是告诉 screen 或者 tmux 把其中的字符序列直接发送到终端模拟器处理。

于是,我的 vimrc 又可以更新了:

let color_normal = 'HotPink'
let color_insert = 'RoyalBlue1'
let color_exit = 'green'
if &term =~ 'xterm\|rxvt'
  exe 'silent !echo -ne "\e]12;"' . shellescape(color_normal, 1) . '"\007"'
  let &t_SI="\e]12;" . color_insert . "\007"
  let &t_EI="\e]12;" . color_normal . "\007"
  exe 'autocmd VimLeave * :!echo -ne "\e]12;"' . shellescape(color_exit, 1) . '"\007"'
elseif &term =~ "screen"
  if !exists('$SUDO_UID')
    if exists('$TMUX')
      exe 'silent !echo -ne "\033Ptmux;\033\e]12;"' . shellescape(color_normal, 1) . '"\007\033\\"'
      let &t_SI="\033Ptmux;\033\e]12;" . color_insert . "\007\033\\"
      let &t_EI="\033Ptmux;\033\e]12;" . color_normal . "\007\033\\"
      exe 'autocmd VimLeave * :!echo -ne "\033Ptmux;\033\e]12;"' . shellescape(color_exit, 1) . '"\007\033\\"'
    else
      exe 'silent !echo -ne "\033P\e]12;"' . shellescape(color_normal, 1) . '"\007\033\\"'
      let &t_SI="\033P\e]12;" . color_insert . "\007\033\\"
      let &t_EI="\033P\e]12;" . color_normal . "\007\033\\"
      exe 'autocmd VimLeave * :!echo -ne "\033P\e]12;"' . shellescape(color_exit, 1) . '"\007\033\\"'
    endif
  endif
endif
unlet color_normal
unlet color_insert
unlet color_exit

因为 tmux 的TERM变量和 screen 的一致,所以得使用TMUX变量来判断是在 tmux 里还是在 screen 里。

最后,说下指定颜色的方法。可以使用和 HTML 中一样的#rrggbb甚至简写#rgb,也可以使用颜色名。这里有个 xterm 的颜色名表。

2011年8月25日更新:

写了个 zsh 函数:

if [[ $TERM == xterm* ]] || [[ $TERM == *rxvt* ]]; then # {{{2 设置光标颜色
  cursorcolor () { echo -ne "\e]12;$*\007" }
elif [[ $TERM == screen* ]]; then
  if [[ -n "$TMUX" ]]; then
    cursorcolor () { echo -ne "\ePtmux;\e\e]12;$*\007\e\\" }
  else
    cursorcolor () { echo -ne "\eP\e]12;$*\007\e\\" }
  fi
fi
Category: Linux | Tags: vim 终端 screen zsh tmux
6
15
2011
33

让 Vim 在终端下和 GVIM 一样漂亮:gui2term.py 更新至 3.0 版

gui2term.py是我用Python写的一个脚本,用于给仅支持 GVIM 的配色方案添加256色终端支持。介绍文章以及截图可以看Dante的《强烈推荐-将gui配色转化为终端配色的vim插件-gui2term-py》以及muzuiget的《Vim终端配色转换工具》。

缘起

GVIM 比起终端版的 Vim 来,支持丰富的色彩,而且使用 RGB 表示,更易于编辑,所以有很多配色方案都是只适用于 GVIM 的。但很多人不甘心忍受终端下丑陋的 Vim,于是,如muzuiget的博文所述,有好几个插件都尝试让终端版 Vim 能够使用为 GVIM 写的插件。但是,它们无一例外都是在 Vim 运行时动态转换配色的,估计有点影响启动速度。更重要的是,它们都是在 RGB 空间寻找最接近的终端色彩。这样造成的结果是,经常找到的颜色不是视觉上最接近的。甚至,在转换 spring 配色的时候,原本浅绿色的背景变成了灰色!

于是,我决定写一个脚本,永久性地为配色添加终端支持;同时,使用更好的算法来寻找最接近的颜色。所以,gui2term.py 是独立于 Vim 的 Python 脚本。所以,在最初的版本中我使用了 HSL 空间。没办法,不懂相关的色彩知识,只好凭感觉选择算法了。

更新

前天,我收到了一封来自 Eric Pruitt 的邮件。他建议我使用 colormath 这个库来寻找最接近的颜色。我看了下,发现 colormath 依赖于 numpy。我可不喜欢这么大的依赖。于是,我从 colormath 以及别的地方找出了需要用到的三个算法:RGB 空间到 XYZ 空间的转换、XYZ 空间到 CIELab 空间的转换,以及一个名为 delta_e_cie2000 的 delta 算法。

新的算法比原先的要好一些。我测试了三个配色(lilypink、spring、以及另外一个自己修改的)。其中,有两个的转换结果与 GUI 版更为接近(但是其中一个我更喜欢之前的算法转的),另外一个与原来的算法结果相同。

除此之外,我也更改了寻找 rgb.txt 的逻辑,因为不少人用的时候程序报告找不到 rgb.txt 文件。现在,gui2term.py 会首先尝试使用 locate 程序寻找 rgb.txt。

Category: Vim | Tags: python vim 配色
5
17
2011
16

强大的Vim插件——CountJump

今天,vim_dev邮件列表里有人说Vim要不要内建camelCase的移动方式。于是一帮人在那里讨论。我平时都是用fU找到下一个字母U的方式在很长的camelCase变量里移动,所以并不怎么关心讨论的结果,但想看看他们到底怎么想的。然后就看到 Ingo Karkat 说到了他的camelcasemotion插件和CountJump插件。Ingo Karkat 这人最近我经常通信的,他给我的colorizer插件(vim.orggithub)提了很多很好的意见(今天又来信了)。他还有个mark插件也很好用,同时高亮多个不同的单词/正则匹配的。

camelCase没太大的兴趣,所以我先没怎么看,看了CountJump的介绍,又见到这个在 patch 文件中跳转的插件,就下回来安装了,仔细读了帮助,才发觉,它可以实现我曾经希望有的功能。

下面开始正式介绍。首先,你得知道text-object是什么(不知道的童鞋请先:help text-object)。这个插件并不干实事,只提供了些函数,大体来说,完成了两类东西的自定义。其一是 patch 块这种区域,其二就是文本对象。定义的方式也很好,想简单,可以使用正则表达式;想更强大,支持使用自定义的函数。

我曾经折腾 Javascript 时非常希望有这样一个功能,可以像使用ci"来更改"string"中的内容这样快速更改 Javascript 正则表达式/regex/双斜线里的内容。可惜 Vim 没有内建这种文本对象。现在有了CountJump,自定义一个易如反掌:

call CountJump#TextObject#MakeWithCountSearch('', '/', 'ai', 'v', '\\\@<!/', '\\\@<!/')

就这样一句命令,然后就可以像使用i"a'这样使用i/a/来表示 Javascript 正则表达式双斜杠的文本内容了。

CountJump的区域移动也不错,不过除了那个用于 patch 的我还真没想到好的使用实例,只弄了这个:

1 call CountJump#Motion#MakeBracketMotion('', 'b', 'e', '\<\w\|\l\@<=\u\|_\@<=\w', '\w\>\|\l\u\@=\|_\w\@=', 1)
2 for mode in ['n', 'o', 'v']
3   exec mode . 'map b [b'
4   exec mode . 'map e ]b'
5 endfor

这个和camelcasemotion的功能类似,使用becamelCase或者under_score中的单词中移动,不过很不完美,实际使用时有一些问题。

最后,有一个非常令我兴奋的是,这样定义的文本对象也被surround.vim支持!在 Javascript 中想把一个字符串字面值改成一个正则表达式?cs"/即可!不过有点遗憾的是,自定义文本对象的名字不能是中文字符,自定义的中文标点文本对象surround.vim也不支持。

Category: Vim | Tags: vim
4
19
2011
3

Vim的Python3有内存泄漏?继续修正!

给Vim的Python3支持打了个补丁,发到邮件列表上只有Bram表示希望有人来测试就没有下方了。于是,这么久了,这个补丁的内存泄漏问题一直未被发现,直到看到蓝色基因的这篇文章。花了一个下午,发现我原来的补丁不仅没有修正本来就有的内存泄漏,反而雪上加霜,浪费了更多的内存。现在终于弄好了,放在我的陈列室里了,同时还莫名其妙地修正了另一个小问题

既然是内存泄漏,我首先想到的是valgrind这个工具。于是跑了一下:

valgrind --leak-check=full --show-reachable=yes vim

在开启的 Vim 中我 source 了蓝色基因的测试脚本:

lcd %:h
tabedit tmpbuffer
setlocal buftype=nofile
 
python3 << EOF
for i in range(3):
    flines= ['x'*200] * 50000
    vim.command("%s+\\_.*++g")
    for fl in flines:
        vim.current.buffer.append(fl)
    del flines[:]
EOF

整个过程CPU占到100%,而且运行速度极慢,内存消耗也非常多。最后Vim终于按我的指令退出时,valgrind刷屏了大约十几秒钟!而其间我看到除了Python的字样外,还有不少rb的字样。难道Ruby支持也有类似的问题?不过我不管它。重新编译了个只有--enable-python3interp选项的 Vim,这回跑起来快了一些,也没有那么多不相干的内存泄漏了。我也学聪明了点,把信息重定向到文件:

valgrind  --leak-check=full --show-reachable=yes src/vim 2> log

这样可以方便地在log中找“if_py”字符串了。可惜我弄的时候没想到自己会来写博客,所以log文件并没有保存。。。

首先我找到了DoPy3Command这个函数,valgrind说它里面分配的内存没有被释放。这里边的PyUnicode_AsEncodedString这块是我加的:

    /* PyRun_SimpleString expects a UTF-8 string. Wrong encoding may cause
     * SyntaxError (unicode error). */
    cmdstr = PyUnicode_Decode(cmd, strlen(cmd), p_enc, NULL);
    PyRun_SimpleString(PyBytes_AsString(PyUnicode_AsEncodedString(cmdstr, "utf-8", NULL)));

然后我能怎么办呢?当然是查Python的文档了。于是注意到文档上说PyUnicode_AsEncodedString返回的是新的引用。又去看官方教程上的示例,才知道如果一个API返回了新的引用,那么用完后应当手动Py_XDECREF!就像是strdup函数,它内部帮你malloc了,你自己用完后要记着free掉。(Py_XDECREFPy_DECREF的差别是,前者可以传NULL。)

于是就改吧,所有通过PyUnicode_AsEncodedString得到的对象都要Py_XDECREF下。为此,不仅需要临时变量来存储这个对象,更让我郁闷的是,在两个Python版本共有的函数StringToLine中有这样一段代码:

    str = PyString_AsString(bytes);
    len = PyString_Size(bytes);

这里的两个函数/宏我之前是这样定义的:

#define _PyUnicode_AsBytes(obj) PyUnicode_AsEncodedString(obj, p_enc, NULL)
#define PyString_AsString(obj) PyBytes_AsString(_PyUnicode_AsBytes(obj))
#define PyString_Size(obj) PyBytes_GET_SIZE(_PyUnicode_AsBytes(obj))

这下我没辙了,只好又改了if_py_both.hif_python.c文件,加了两个宏:PyString_AsBytesPyString_FreeBytes。它们在 Python2 的代码中什么也不做,但是在 Python3 的代码中用来保存和释放中间对象:

#define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, p_enc, NULL);
#define PyString_FreeBytes(obj) Py_XDECREF(bytes)
#define PyString_AsString(obj) PyBytes_AsString(obj)
#define PyString_Size(obj) PyBytes_GET_SIZE(bytes)

有人说,if it ain't broken, don't fix it。可是,虽然问题只出在 Python3 部分,我还是得改 Python2 部分,感觉很不爽。

这样改完,再次反复运行测试代码,结果不遂人愿,依旧泄漏了不少内存。于是继续valgrind,又找到这里:

    static void
BufferDestructor(PyObject *self)
{
    BufferObject *this = (BufferObject *)(self);

    if (this->buf && this->buf != INVALID_BUFFER_VALUE)
	this->buf->b_python3_ref = NULL;
}

然后再次查教程中的示例:

static void
Noddy_dealloc(Noddy* self)
{
    Py_XDECREF(self->first);
    Py_XDECREF(self->last);
    Py_TYPE(self)->tp_free((PyObject*)self);
}

再看看 Python2 部分的代码,在相应的函数里有Py_DECREF,于是把这示例的最后一行给BufferDestructor以及WindowDestructorRangeDestructor加上。再测试,内存不再消耗100多M了,反复source也不会继续增加,于是作出结论:Vim 的 Python3 支持部分没有已知的 bug 了!

做完这一切,我只想说:Vim 这 Python3 支持也太 broken 了吧,中文经常乱码就算了,vim.error不能用我也忍了,竟然还内存泄漏!难道写这个代码的人也是初学Python C API啊?

不过抱怨归抱怨,还是很感谢原作者的,不然我连修正都不可能。不过,patch 弄好也提交了,却一直没人理我,原作者难道是一时兴起才写的、然后就消失了?

最后,补丁现在放到陈列室了。

Category: python | Tags: vim python C代码
4
7
2011
9

带补丁gvim 7.3 Arch软件包下载

准备向 Arch 迁移了,于是编译了个GVIM。之所以要自己编译,当然是要打非官方补丁了。

主要的 bug 修正为:

其中第三条只在 Arch 上出现,据说是某个库的 bug。后来折腾了段时间,发现如果 gvim 不 fork,或者 fork 后父进程生存的时间长一点点,就不会错误地出现这个提示(但是真正使用超级用户权限时也没有这个提示,不知道是否属正常情况)。


2011年7月14日更新:最新版下载地址

Category: Vim | Tags: arch C代码 linux vim
3
4
2011
4

Python3.2mu 与 Vim

曾经,我辛苦两星期自以为终于弄好了 Vim 的 +python3 特性,却未曾想到,编译新发布的安装 Python3.2 后 Vim 的 Python3 支持再次悲剧……

事情是这样的。在vim-cn群有人编译 Python3.2 出错问我。我于是把之前为尝新鲜而 make 的 Python3.2 又 make install 了。然后 ./configure 时就出问题了。具体错误不记得了,反正是找不到什么文件。后来我找出了我以前写的一个从 C 调用 Python 代码的小程序,编译通过,链接时找不到某些符号。折腾了好久,才知道是 Python3.2 的安装出错了,./configure 时要加 --enable-shared 参数。当然,我还比较习惯加上 --with-wide-unicode 参数。

于是我的 C 小程序编译运行成功。但 Vim 的依旧悲剧。看了 src/configure.in,注意到它并没有使用 pkg-config,而是按以前 Python 的头文件和库文件的规律硬编码进去的。这时我才发现 Python 的相关文件/目录都多了个 mu 后缀:

>>> pkg-config --cflags --libs python-3.2
-I/usr/local/include/python3.2mu  -L/usr/local/lib -lpython3.2mu
>>> ls -li /usr/local/bin/python*
163890 -rwxr-xr-x 3 root root 10877 2011-03-01 23:16 /usr/local/bin/python3
163890 -rwxr-xr-x 3 root root 10877 2011-03-01 23:16 /usr/local/bin/python3.2
164216 lrwxrwxrwx 1 root root    18 2011-03-01 23:18 /usr/local/bin/python3.2-config -> python3.2mu-config
163890 -rwxr-xr-x 3 root root 10877 2011-03-01 23:16 /usr/local/bin/python3.2mu
164107 -rwxr-xr-x 1 root root  1827 2011-03-01 23:18 /usr/local/bin/python3.2mu-config
164252 lrwxrwxrwx 1 root root    16 2011-03-01 23:18 /usr/local/bin/python3-config -> python3.2-config

这个 mu 后缀是什么意思呢?搜了半天,终于找到了:m 是普通版,u 是宽字符版(--with-wide-unicode),还有个 d 表示使用了 --with-pydebug 参数编译的。加了这些后缀,于是 Vim 配置脚本的硬编码就失败了。(它为什么要硬编码呢……T.T)对于 mu 版,修改方法是这样的:

# For Python3.2
if which python3 >/dev/null 2>&1 && [ $(python3 -c 'import sys; print(sys.version_info.minor)') -ge 2 ]; then
  sed -i -e 's|-lpython${vi_cv_var_python3_version}[dmu]*|-lpython${vi_cv_var_python3_version}mu|' \
         -e 's|python${vi_cv_var_python3_version}/config[^"]*|python${vi_cv_var_python3_version}/config-3.2mu|' \
         -e 's|include/python${vi_cv_var_python3_version}[dmu]*|include/python${vi_cv_var_python3_version}mu|' \
    src/configure.in
  # Fixed: no longer needed.
  # sed -i -e 's|PyEval_InitThreads();|/* PyEval_InitThreads(); */|' \
  #   src/if_python3.c
  autoconf=1
fi

[ $autoconf -eq 1 ] && (cd src && autoconf)

后面那个对 src/if_python3.c 的修改我也不知道是为什么,反正不这样的话调用 Python 时就 SIGABRT 出错退出,而这样改了之后好像也没什么负面影响。至于找出这个语句的办法嘛,当然是不知比 jdb 好用多少倍的 gdb 啰。


2011年4月19日更新修正了 Python3 接口的内存泄漏问题,发现已不再需要删掉那句代码了(删掉后反而出错)。

Category: python | Tags: python vim 编译
2
24
2011
10

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

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

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com