本文来自依云's Blog,转载请注明。
今天,vim_dev邮件列表里有人说Vim要不要内建camelCase的移动方式。于是一帮人在那里讨论。我平时都是用fU
找到下一个字母U的方式在很长的camelCase变量里移动,所以并不怎么关心讨论的结果,但想看看他们到底怎么想的。然后就看到 Ingo Karkat 说到了他的camelcasemotion插件和CountJump插件。Ingo Karkat 这人最近我经常通信的,他给我的colorizer插件(vim.org、github)提了很多很好的意见(今天又来信了)。他还有个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的功能类似,使用b
、e
在camelCase
或者under_score
中的单词中移动,不过很不完美,实际使用时有一些问题。
最后,有一个非常令我兴奋的是,这样定义的文本对象也被surround.vim支持!在 Javascript 中想把一个字符串字面值改成一个正则表达式?cs"/
即可!不过有点遗憾的是,自定义文本对象的名字不能是中文字符,自定义的中文标点文本对象surround.vim也不支持。
May 17, 2011 11:38:56 PM
看你写的还是比看英文介绍快一些的。(也有可能是因为我先看的英文介绍
到现在为止对这样的功能要求得还不多,以后如果遇到用得着的地方,再用上吧。
May 17, 2011 11:46:37 PM
fU是怎么回事?
May 17, 2011 11:55:59 PM
比如有个变量名叫 toUpperCase,光标在 to 上的时候,按 fU 就到 U 字母上了。
May 18, 2011 12:16:47 AM
vim-dev 那些人吃饱了撑的,讨论这些鸡零狗碎的问题。Vim 最应该做的是赶紧增加自身作为外部程序 UI 的支持。我曾经想基于 Vim 的补全列表来实现一个下拉式选单,方便进行 GUI 式的操作。做还是能做的,但是因为缺乏支持,Vim 不是为这个设计的,结果费了老鼻子的劲了。还有 Vim 在 v 模式或者 i 模式下调用的函数里不允许使用 normal 命令,据说是为了安全性的关系(E523),是个蠢决定。Vim 里的资源都是公有的,buffer,option 这些,谁想改就改,还安全个鬼啊,考虑方便性才是主要的。
May 18, 2011 12:21:31 AM
对了,小声问下,你在 linux 下怎么翻墙呀 :) vim-dev 和 vim-use 平时都上不去。
May 18, 2011 12:46:58 AM
这个你到 vim_dev 提出来吧。没人跟他们说他们就以为一切OK了。。。
May 18, 2011 01:15:33 AM
我记得 vim-dev 是只有特定用户才能发言的吧。我顶多在 vim-use 里问个问题。而且我的兴趣一直很小众,比如拿 Vim 当 UI 什么的,基本引不起什么注意。而且在 linux 下还上不去。
May 18, 2011 01:22:54 AM
哪天也试试看好了。我觉得 Vim 对 i mode 和 v mode 下的函数限制太多,这些限制看上去都是人为的,没什么必要,严重影响功能。比如这段:
vnoremap <buffer> <expr> <A-i> <SID>VmodeMapping('A-i')
vnoremap <buffer> <expr> <A-k> <SID>VmodeMapping('A-k')
function! s:VmodeMapping(inputkey)
echomsg "called !"
call cursor(1, 1)
endfunction
这是一个 v 模式下调用的函数,里面试着用 cursor() 函数改变光标位置。这个是很实用的,比如编辑 html 的时候,在 start tag 上进入 v 模式,按自定义按键,就可以跳到 end tag 上,选中整个 element 的内容。问题是,这个函数完全不起作用。调用 cursor() 没任何反应。换成 normal gg 就更不用说了,直接 E523。我怀疑这种限制到底有没有必要。
May 18, 2011 07:38:18 AM
如果你捐助 VIM 几百欧元的话,相信 BM 会考虑把它们放到优先开发的列表里。
http://www.vim.org/sponsor/faq.php#counting
May 18, 2011 07:40:53 AM
ssh 或虚拟机里的 win 转发。
May 18, 2011 12:23:39 PM
这个功能 xml.vim 已经做到了啊。
May 18, 2011 12:24:33 PM
我在里面发言没问题啊。vim_use 邮件太多,我不敢订了。
May 18, 2011 06:52:58 PM
好的我回头研究下
May 18, 2011 06:53:20 PM
嘿嘿嘿 。。。
May 18, 2011 06:58:15 PM
我的错。xml.vim 我看了,是有办法的。NND,文盲!
必须要曲线救国,先退出 v 模式再进入:
" map 的时候先退出
vnoremap \\ <Esc>:call <SID>VmodeMapping()<CR>
" 在函数里再进入
function! s:VmodeMapping()
normal V
call cursor(1, 1)
endfunction
May 19, 2011 10:26:52 AM
一直在用SSH,最近也不稳定了。