11
29
2010
0

snipMate表达式扩展补丁

snipMate 是Vim的片断扩展插件之一,介绍网上很多,实在不想Google的话可以看看这里,我就不多言了。

我经常会把一些网站链接连同其标题写到自己的wiki或者邮件中,于是有个这个snippet:

snippet link
	[`@*` `system('getTitle '''.@*.'''')`]${1}

扩展 * 寄存器(也就是X选择区)中的URL,并使用getTitle这个我自己用Python写的程序获取标题。这个snippet大多数情况下工作良好,只是偶尔会使Vim停止响应,只能Ctrl-C中止。今天在扩展 http://larrupingpig.zoka.cc/?p=197 这个URL时又遇到这个问题,实在受不了了,于是自己看源代码。`...`的扩展在这里:

	if stridx(snippet, '`') != -1
		while match(snippet, '`.\{-}`') != -1
			let snippet = substitute(snippet, '`.\{-}`',
						\ substitute(eval(matchstr(snippet, '`\zs.\{-}\ze`')),
						\ "\n\\%$", '', ''), '')
		endw
		let snippet = substitute(snippet, "\r", "\n", 'g')
	endif

问题就出在substitute中的substitute上。:help substitute()可以看到,其第三个参数中有些特殊字符,比如前边那个网页标题中的&,会被特殊对待。

知道问题出在哪儿了,也就有改的办法了,我在Google Code上报告了bug,并提交了补丁。但看看那么多的issue和Github上的Pull Request,我感觉被采纳的可能性好小啊。。。

Category: Vim | Tags: vim
11
26
2010
8

在Win编译带Lua支持的GVIM

虽然已经在Linux下待了这么长时间,可是,还是有很多时候,我不得不面对难用的Windows。而在Linux下一直自己编译Vim的我,今天在得知刘春棍的行动的支持下,终于鼓足了勇气,下载安装MinGW,编译了GVIM。

在Windows下编译GVIM和Linux下不同,不能用./configure来配置,要到src目录下,修改这下面的Make_ming.mak文件,改好后直接make -f Make_ming.mak编译。

Win下编译东西花的时间长就不说了。我编译了好几遍。Python支持没问题,设定好路径就OK,Ruby我是为编译GVIM专门装的,除了静态编译时会报错外,还有个很严重的问题,导致我最后放弃了+ruby。这个后面再说。Lua我下的是最新的5.2版,一个lua5_2_work2_Win32_bin.zip包含了exe和dll文件,另一个lua5_2_work2_Win32_mingw4_lib.zip包含了头文件和一个 .a 文件。我最开始以为和ruby一样只能动态载入,于是设置了DYNAMIC_LUA=yes,结果编译是成功了,但载入失败:

luaL_typerror无法加载

我用cg搜索了下,luaL_typerror被 #define 成了luaL_typeerror,这看来是5.2改的。我手动在if_lua.c里把这个给改了,结果发现,还有其它函数也是类似的情况,比如lua_call等。于是我尝试静态编进去试试,竟然成功了!

然而,喜悦总是短暂的。我以前只知道ruby支持有问题,没想到这次问题更严重了,:edit命令都用不了:

当然,一开始我还不能肯定是ruby支持的问题,但当编译了不带ruby支持的版本后,这个奇异的问题就没有了。

Vim7.3对其他语言的支持的问题真是多啊:Python3的中文支持有问题,ruby的支持也有问题,要支持Lua5.2还得自己改源代码。。。

不管怎么说,Lua静态编译进去了我还是很高兴的。虽然在没装Lua的机器上没那些Lua的库的,但至少在Vimscript外又多了一种可用的语言了。

最后,想下载我编译的 Windows 32 版 vim 的请到这里来。

Category: Vim | Tags: vim windows Lua
9
30
2010
12

colorpicker: 给 Vim 加一个调色板!

作为一名一直喜欢写网页前端的vimmer,自然会使用Vim来编写CSS了。但是,CSS中经常需要调色。虽然相继有一些工具的出现(见可视化的配置Vim(gVim)配色-colorsel.vim),但一直不太理想。编辑CSS的颜色,不仅需要细致的调色,而且需要方便修改,并且支持从屏幕取色是最好不过了!

既然没有现成的,而自己不管怎么说已经入了GTK的门,就自己写了一个简单的工具。本来有个叫gcolor2的调色/取色工具的,可惜它不支持把取到的颜色输出到标准输出,或者任何其它可被其它程序调用的地方(难道这只是某个大牛闲着没事做时写着玩儿的 :-P)。所以,colorpicker与之类似,只有一个标准的GTK调色板。重要的不同之处在于:它可以和其它程序交互。

还是先放个图吧:

就是这样。从图中可以看到,这个标准的调色板除了支持RGB值,还支持HSV,而后者非常适合对色彩进行微调,不像RGB那样只有机器能够理解。左下角有之前颜色和当前颜色的显示(截图时没注意,都是白色。。。)。之前颜色是可以从命令行设置的,这个很有用(请往下看)。也有取色器,在Linux下是可以取到屏幕上任何一点的颜色的。但根据我使用GIMP的经验,好像在Windows上只能取到本程序的颜色。另外还可以看到,图中显示了“透明度”一项。关注Web前端的童鞋都知道,CSS3支持半透明色彩了,所以,本程序也支持输出rgba(79, 0, 159, 0.51)这样的颜色值。

关于程序自身的介绍就到这儿。下面是在Vim里使用的截图:

我需要输入一个颜色值,于是按了我自己定义的Alt-C键,colorpicker启动了。因为是新颜色,加之之前我没使用过,所以“之前颜色”那里显示的是默认的白色。

颜色已经输入了,但我想换一个颜色,怎么办呢?在普通模式下按cac(change a color)就可以了,“之前颜色”会被置为待修改的颜色,方便进行微调。


PS: 在图中可以看到CSS中的颜色值下方背景被高亮成了相应的颜色。这是使用css.vim实现的。

PS2: 这里演示的是修改CSS文件,但实际上是和文件类型无关的。你可以将它用于任何你想用的文件中。

PS3: colorpicker是独立的GTK程序,所以不一定非要和Vim配合工作啦。Emacs什么的一样可以调用,只要有人写出调用代码。

PS4: 程序在哪里下载呢?请移步我的陈列室。Vim调用部分的代码尚未整理,在我的vimrc中,搜索colorpicker就可以了(共两个函数,截图中可以看到函数名。目前(2010年9月30日)它们处于我的vimrc的前50行内)。


2011年4月9日更新

这里 jiazhoulvke 提供了编译好的 Windows 版程序(以及分离出来的 Vim 配置),当然GTK Runtime 环境还是得装,而且还可能遭遇著名的DLL Hell(如果不幸地出现了,那么请把出问题的 DLL 文件从 GTK 的 bin 目录复制到 colorpicker.exe 所在的目录中)。

2014年11月8日更新:

颜色值的高亮显示可以使用 colorizer 插件了哦~

Category: Vim | Tags: gtk css vim C代码
9
28
2010
2

Vim73之ruby $curbuf.number恒为零问题终于解决了!

上回说到Vim7.3在种种优点背后隐藏着种种bug,今天,其中之一终于被解决了!

Command-T 的作者在 vim_use 上的bug报告贴无人回应之后若干天,又在 vim_dev 上发了贴,今天终于有人回应了,指出configure时加上--disable-largefile选项此bug就消失了。我于是迅速地重新编译了下,果然OK了!

Category: Vim | Tags: vim ruby
9
16
2010
9

Vim的hidden选项真是好东西!

我在编辑一些HTML文件。写得觉得差不多了,浏览器里看过还不满足,竟然想到去W3C验证一下。这一验证,差点出大事了!

因为需要使用程序来处理,所以这些HTML文档全部都是合格的XML文件,所以我给它们加上了<?xml version="1.0" encoding="UTF-8"?>。但W3C却告诉我HTML里不能写这个。好吧,我把它们都删掉:

sed -i '/<\?/d'  *.html

我想的是,凡是有<?的行全部删掉。命令执行完后忽然有点不好的感觉,于是ll一下,结果看到了一堆长度为0的HTML文件!我愣了一下,随即欲哭无泪!虽然这些文件在SVN里,但是自我这次开始编辑后我就没提交过!sed也是危险的命令啊!

我只想到火狐里还保留着改动最多的一个页面,赶紧先把它的源代码复制出来。直接“查看源代码”还不管用,因为本地文件是没有缓存的,查看时火狐会去磁盘上找文件。于是打开Firebug,在<html>元素上点右键,复制HTML,然后手工整理。剩下的文件没办法,只有SVN和Vim的*~备份文件了,555……

好吧,我认命。于是我在Vim里打开另一个文件,想趁着还记得改了些什么赶紧重做一遍,却意外地发现打开的文件显示着我sed之前的内容。来不及多想,我赶紧:w保存了,然后想了下,才恍然大悟——

我现在习惯于一直开着一个GVim实例,而又经常只是挂起或者休眠,几天才shutdown一次,所以经常会有100多个buffer。虽然我通常是把hidden选项关闭的,但有时候为方便切换buffer,会去se hidden一下,然后一直忘记再设置回来。这次,不记得什么时候设置了hidden选项,于是,那些被我关闭的buffer都还在内存里!终于知道了hidden在文件已保存的情况下有什么重要作用了!怀着对Vim的感激,我在buffer找到了所有被sed误删的文本,泪流满面~~


2011年3月17日更新:

现在才知道,sed 原来是支持备份的,只要告诉它备份文件的后缀就行了,像这样-i~

另外,Perl 也支持类似的操作,但用的是PCRE,功能强大许多我也熟悉许多。用法是

perl -pin -e 'print /regex/' #相当于 sed -i '/regex/d'
perl -pi -e 's/regex/replacement/g' #相当于 sed -i 's/regex/replacement/g'

 

Category: Vim | Tags: vim 失误 perl sed
9
3
2010
5

Vim7.3: 爱你不容易

Vim7.3b出来后我就急不可耐地体验了把,但因为它的ruby支持中$curbuf.number始终返回零,不仅影响到了Command-T插件,也严重影响了我非常喜欢+常用的LustyExplorer插件——时不时地SEGSEGV一下可不行。

等正式版终于出来后,我又立即下载编译了,结果问题依旧。无奈,我只好自己动手,把LustyExplorer中用到$curbuf.number的地方都换成VIM::evaluate('bufnr("%")')了,但之后还是在调用此插件时经常SEGSEGV,郁闷了,于是换回Vim7.2。

但是Vim7.3真的有些很好的特性啊。此前介绍过的就不重复了,下面说说后来发现的两个我很喜欢的特性。

strwidth()函数

strlen()大家都知道,但它求的是字符串的字节数,而不一定等于字符串的宽度,比如中文就是如此。这会造成无法将内容对齐。于是,用于对齐代码的Align插件在处理CJK字符时(设置let g:Align_xstrlen = 3时)使用了一种很耗时的办法来求字符宽度:将字符串显示在Vim里,然后看它占用了多少虚拟列。

有了Vim7.3的strwidth()等函数就不必这么麻烦了。我去改了相关代码,执行效率提升N倍。

setf补全

setf是设置文件类型的指令。这个我很常用,比如写php文件的HTML部分时为了正确地缩进HTML,我会把文件类型设置成HTML,写PHP部分时还要切回去。写新脚本时由于通常没有文件扩展名,所以Vim无法识别文件类型。这些情况我只好手动:setf xxx了。Vim7.3增加了对此的补全支持,可以少敲点字母了。


所以——

所以为了用上Vim7.3,同时又不放弃LustyExplorer插件,我前不久又开始折腾Vim7.3的源代码,最后连gdb都用上了,在段错误时得到以下backtrace结果:

#0  __memset_sse2 () at ../sysdeps/i386/i686/multiarch/memset-sse2.S:160
#1  0x00d1d6ac in Perl_sv_upgrade () from /usr/lib/libperl.so.5.10
#2  0x00d1ea6a in Perl_sv_magicext () from /usr/lib/libperl.so.5.10
#3  0x00d1fc11 in Perl_sv_magic () from /usr/lib/libperl.so.5.10
#4  0x00d21882 in Perl_sv_setiv () from /usr/lib/libperl.so.5.10
#5  0x08203691 in perl_buf_free (bp=0x847b890) at if_perl.xs:638
#6  0x080742e3 in free_buffer (buf=0x847b890) at buffer.c:613
#7  0x08073fec in close_buffer (win=0x0, buf=0x847b890, action=4)
    at buffer.c:468
#8  0x08074de8 in do_buffer (action=4, start=0, dir=1, count=0, forceit=1)
    at buffer.c:1136
#9  0x0807465e in do_bufdel (command=4, arg=0x84b8aa1 "", addr_count=0, 
    start_bnr=12, end_bnr=1, forceit=1) at buffer.c:834
#10 0x080cbb2c in ex_bunload (eap=0xbfff9f8c) at ex_docmd.c:4939
#11 0x080c817d in do_one_cmd (cmdlinep=0xbfffa140, sourcing=1, 
    cstack=0xbfffa148, fgetline=0, cookie=0x0) at ex_docmd.c:2656
#12 0x080c5a56 in do_cmdline (cmdline=0x837c2d0 "bwipeout!", getline=0, 
    cookie=0x0, flags=11) at ex_docmd.c:1122
#13 0x080c5110 in do_cmdline_cmd (cmd=0x837c2d0 "bwipeout!") at ex_docmd.c:728
#14 0x0820cf98 in vim_command (self=3084803600, str=3084486540) at if_ruby.c:731
#15 0x010619a3 in ?? () from /usr/lib/libruby1.8.so.1.8
---Type  to continue, or q  to quit---

接着我很快发现了问题——明明是个ruby写的插件,最上面怎么调用到Perl了呢?遂关闭+perl特性重新编译,几天已经过去了,Vim7.3依旧运行良好,没有再出现以下烦人的提示了:

Vim: 拦截到致命信号(deadly signal) SEGV
Vim: 结束。
zsh: segmentation fault  vim

现在我一直在关注 ftp://ftp.vim.org/pub/vim/patches/7.3/,期待着这个问题从根本上解决……

Category: Vim | Tags: vim ruby
7
28
2010
4

Vim7.3 beta体验手记

昨天在LinuxToy上看到Vim 7.3b放出的消息,看到增加了Python3支持和持久性撒消(persistence undo)功能,于是忍不住从ftp.vim.org下了源码,编译到临时目录中体验了一下,觉得非常不错,遂卸载了前不久才编译安装的带有所有已发布补丁的Vim7.2,打上我自己的修改补丁,正式安装了。

持久性撒消

持久性撒消(persistence undo)是经常按u的人的福音,它把撒消树保存到文件中,从而即使文件被关闭再打开多次,就好像其间没有关闭过一样,所有的修改都可以u回去(当然不能超过'undolevel'的限制)。

要使用此功能,需要设置'undofile'选项。'undodir'指定撒消树保存的目录,默认是当前目录。会扩展'~',但是对于不存在的目录不会自动建立,这点有点不方便。文件名是所编辑的文件完整路径,(在Linux上)其中的'/'被换成了'%'

撒消树文件中会包含这个文件内容的hash值,这样当一个文件有了撒消树文件后,如果它被其他程序编辑过,Vim会忽略撒消树文件,而不会因此让撒消使文件乱掉。

命令:earlier:later也增加了一个单位:f——写入写入次数。比如说,我打开了一个配置文件,编辑N久,保存并测试后不满意,想恢复到原来的样子。怎么办呢?以前我会一直按着u键直到Vim告诉我不能撒消了,或者用备份文件(*~)来覆盖当前文件。现在可以使用命令:earlier 1f直接恢复到上次写入时了。

目前Vim只会去创建撒消树文件,而永远不会去删除它们,需要手动删除。因此,我只好把它们放到自己的tmpfs临时目录中,关机自动清除好了。

Python3接口支持

说实话,这个很令我失望。我是一直希望Vim支持Python3的,但是Python2也需要支持,因为有好些插件会用到的。所以,我同时编译了Python2和Python3特性进去,结果测试时Vim告诉我在同一会话中只能使用其中之一:

E999: Python: Cannot use :py and :py3 in one session

竟然错误号是999。。。

看来启动过程中就有某个脚本调用过:py了。看来我是没希望在Vim中用python3了。。。

相对行号

这个曾经有插件(效率很低地)实现过,什么意思应该很好理解,选项名称为'rnu',和'nu'(显示行号)不相容的。放图:

相对行号

+cursorbind

在比较文件的时候,有个scrollbind功能,可以让被比较的文件同步滚动。但是,在之前的版本中,光标经常并不在同一行。从一个窗口跳转到另一个窗口时,我经常找不到光标的位置了。。。现在好了,有了这个特性,光标的位置也同步了。

PS:这个新特性:help version-7.3中没有提到我太激动了,所以没有看完文档(囧。。。),是我自己对照:ver命令的输出结果发现的哦~~

其它

其它新特性还有:

  • +conceal隐藏文字
  • 增加强度更高的Blowfish加密
  • lua接口

这些我目前还不甚关心,所以没太关注。不过conceal text的确让帮助文件整洁漂亮了:-)。

Category: Vim | Tags: vim
7
9
2010
1

中键关闭GVim的标签

今天在Vim Talks群群地址)上看到闲耘™问到GVim能否像其它很多程序那样使用中键关闭对应的标签。虽然我自己在Vim鼠标用得比较少,但也曾想过这个问题。现在刚刚考试完毕,所以就去试着改了下Vim的源代码。没想到只需要加六行代码呵~~

#ifndef HAVE_GTK2
	    else
		gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline),
							    clicked_page - 1);
#endif
	}
	/* The following if is added by lilydjwg, to enable closing tab by
	 * middle-clicking. */
	else if (bevent->button == 2)
	{
	    send_tabline_menu_event(clicked_page, (int)(long)TABLINE_MENU_CLOSE);
	    if (gtk_main_level() > 0)
		gtk_main_quit();
	}
    }

    /* We didn't handle the event. */
    return FALSE;
}

以上的代码包含了上下文。把原本不存在的部分添加到gui_gtk_x11.c的3303行附近,然后重新编译即可~

PS: 这个只支持GTK版的GVim,所以不适用于Windows平台。

在此还要感谢Ubuntu大学群的Edward提供帮助。

Category: Vim | Tags: vim gtk C代码

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com