VIM - 小技巧

VIM - 小技巧
1. 已经在编辑状态(insert mode)了,如何快速执行 normal mode 的命令?
在编辑文本时,需要快速定位到某个位置,如下一个 d 的位置,难道要
<ESC>、fd、i 这般繁琐吗?
其实,使用 Ctrl-O 就可以临时切换到 normal mode, 执行一个命令后自动返回 insert mode。
于是上述命令序列可以改为:
Ctrl-O、fd 即可。
Ctrl-O 要按两个键呢,很麻烦,于是来个 keymap
" make ` functions <C-O> in insert mode
inoremap ` <C-O>
nnoremap ` i`<ESC>

在 normal mode 下按 ` (左上角那个),会正常插入 `,
而在 insert mode 下则相当于按 Ctrl-O,
于是上述命令序列又可简化为
`fd 即可。
在 insert mode 想粘贴剪贴板内容时,可以输入 `P,爽吧?
这样就可以在 insert mode 下天马行空,不用再按 <ESC>和a 切来切去了。

2. vim 的剪贴板怎么怪怪的?
用 y 命令拷贝的文本怎么不能在 X/Windows 的其它应用中使用呢?
事实上,vim 有多个所谓寄存器来寄存剪切的内容。
平时是不是只用 y <motion> 和 p 命令呢?
其实这时使用的是 unamed 寄存器(对应寄存器*,不知对否?),即没有给定名称的,
而给定名称的,可以加前缀 "r 使用。
例如,将当前行放到寄存器a中,输入: "aY
将另一行(先移到其它行)放到寄存器b中,输入: "bY
粘贴寄存器a,输入:"aP
粘贴寄存器b,输入:"bP

好了,扯远了,X/Windows 的剪贴板的内容是存在寄存器+中,不信,自己试试:"+P
能不能将简单的 y 和 p命令与系统剪贴板联系起来呢?
就这句,浪费了我许多口水:)
set clipboard+=unnamed " set clipboard

3. 我不要每次都输入 this_object.set_...
呵,在 C 的结构或 C++ 的对象设置时,那个结构名或对象名总是重复 n 次要输入,挺烦的:(
添加这两句到配置文件中吧:
" Ctrl-F to yank line upstairs
inoremap <silent> <C-F> <C-O>:exe "norm! kly0jPD"<CR>

这是在编辑模式中使用的,怎么个用法?举个例子吧(括号内是我的注释):


(在编辑模式下,先输入这句:)
     this_object.set_height(1.80);
(                    ^)
(                    |)
(用<tab>啊,空格啊移到箭头所示处,即h处,然后按Ctrl-F)
(自动补全成:)
     this_object.set_
(于是你可以继续输入"weight(100);" 了)


不知大家明白没有,不明白的先试试:)

4. 我想注释一堆 C++ 代码
当然,这有许多种我不知道的方法,我的通用方法为,先在配置文件里添加:
vnoremap . :normal .<CR>

呵,一句就够了,示例如下:

假设你有如下几行代码需要注释:
this_object.set_height(1.60);
this_object.set_weight(100);
this_object.run();

你先移到第一行,输入 I//<ESC> (<ESC>就是ESC键),将第一行注释。
然后移到第二行,按 V 进行 line visual mode,按 j
或其它方向移动键选好要注释的所有代码行,
最后按: .
是不是很神奇?

呵,说白了,这只是在 visual mode 里使用 redo 的功能而已,有点跑题了。
当然,殊途是同归的,只是路的长远而已。
这是条通用的路,可以用在很多地方。
回到主题,谁有更直接的办法注释一堆 C++ 代码?一堆 C 代码呢(用/* */ 风格) ?

5. vi 的自动完成有什么新奇的东东?
不就是根据 buffer 的内容来自动完成吗?
有些插件是可以动态地读取头文件或模块来提供自动完成的,例如 python 的
pydict。(此列表待补全:)
我想介绍的是 vi 基于字典的自动完成:
1. 增加基于字典的自动完成
set complete+=k "add dictionary complete
2. 设定字典文件,字典文件其实是个文件文件,每个单词占一行
(以下字典文件可能并不存在)
set dictionary=/usr/share/dict/words "set dictionary
3. 呵,因此我是不用什么英文字典来自动完成的,很少写英文文章,使用字典后反应很慢。
我用基于字典完成的原因是,使用编辑语言的关键字自动完成,见:
" complete from filetype syntax file
autocmd Syntax * execute "setlocal
dictionary=".$VIMRUNTIME."/syntax/".getbufvar("%","current_syntax").".vim"
对应的语言语法文件必须存在才可使用,于是写新的 C 文件时,可以直接 inc<Ctrl>-N,
cont<Ctrl>-N

 
6. 如何打开 C 源文件所包含的头文件?
可以用 a.vim,这是比较快速的方法。但我还是介绍种通用的方法:
在 normal mode 方式下,光标移至文件名处,按 gf。
就这么简单?
YES!

 

7. 介绍一下 vim 的 command mode 的某些技巧吧?
好啊,command mode 里可以使用 tab 进行命令行或选项的补充和完成。
例如,在 command mode 下输入: color
按<tab>,vim 会补充为 colorscheme
ok,这就是我们所要的,于是按空格,但我们不知道颜色方案的具体名称,
你可以
a.直接按<tab>,反复按,看到了吗,每一种可用的方案逐一列出。
b.按 ctrl-d,呵,出现什么了吗?卖个关子,自己先试一下。

这就是 <tab> 和 ctrl-d 的秘密。如果你想浏览某些文件,你可以利用
这个技巧,输入 "e "(command mode下,不含引号),然后按 ctrl-d,
列出相关文件。如果文件比较多,也可以先输入文件名的前几个字母,再
按 <tab> 补全或 ctrl-d 列出。

附:路径相关操作


pwd       列出当前目录
cd <路径>  cd 到某目录


8. 剪贴操作补充(一)
强烈建议大家先看看 doc/change.txt 里关于寄存器部分的内容,
我只是简单提及一下,英文不太好的朋友请找 vim 的中文文档。
我要介绍的超强武器是 ctrl-r,在 insert mode
和 command mode 均可使用,功能就是插入寄存器相关内容。
大家可以试试先 copy 或 delete 一些文本,然后在
normal mode 或 command mode 输入 ctrl-r ",看到了吗,
你粘贴了寄存器"的内容。

 

寄存器的主要有以下几种:
a. The unnamed register ""
   "d", "c", "s", "x" 和 "y" 等涉及删除或拷贝的命令
   都会将内容存放于此(有例外)。

b. 10 numbered registers "0 to "9                      
   0 为最近拷贝的内容,1-9 为最近删除的内容。
   指定 named register 时不会存放于此。

c. The small delete register "-
   删除不多于一行的内容会存在于此。

d. 26 named registers "a to "z or "A to "Z
   小写与大写的区别是,小写是覆盖方式,大写是添加方式。

e. four read-only registers ":, "., "% and "#
   ". 存放上次插入的文本
      有什么用?呵,例如,你输入了一段文本,在另一个地方也
      要有相同的内容,你输完后,一般要选择并复制一下吧?
      而用这个,直接移到需要插入的地方,i<ctrl-r>. 即可。
   "% 是当前编辑文件全名
      呵,vim 中,% 就是代表当前编辑文件名的变量,好记吧?
      不过,一般直接用 % 就行,例如":!cat %",vim 会自动
      扩展。
   "# 是alternate file 名称 (这个我不知道)
   ": 上次执行的命令
      记起来比较容易,冒号就是命令行提示符嘛。这个有些什么用呢?
      在测试配置文件时十分有用,先在命令行输入命令,调试好后,
      在 insert mode 里按Ctrl-R : 就可将该命令插到文件中。

f. the expression register "=
      呵,表达式寄存器,可以输入一个表达式,并插入结果。

g. The selection and drop registers "*, "+ and "~
      跟 gui 即 X/Windows 剪贴板有关的变量。
      在 X 中,鼠标中键与系统剪贴板不一样,至于区别,大家自己
      试验一下,这里给个提示,在命令行下输入 reg 可以列出所有
      寄存器的内容。
h. The black hole register "_
      黑洞

i. Last search pattern register "/
      上次搜索的内容。例如,我要搜索一个单词 linuxforum,但我
      比较懒,先输入 /linux,发现出现很多个 linux,多次按 n 无果,
      难道要重新输入 /linuxforum ? 不用,只需要 /<ctrl-r>/forum 即可。
      呵,聪明的你一定想到了,用命令行历史也可以调来,按 ctrl-p 或 ctrl-n
      即可上下翻阅。这样也可以嘛,也比较快捷,但要查找 forumlinux 呢?
      用 ctrl-r 的话只需 /forum<ctrl-r>/ 。


"# 是alternate file 名称

在编辑多文件的时候,例如:
vi a.h a.cpp
如果你在buffer之间切换(:bn 或:bN 或 :n)之后,然后输入:buffers 或 :ls, 就会看到切换到当前buffer之前的那个buffer名字之前有了一个# 号,而当前buffer名字是%号标识。这个#标识的文件名字就是 alternate file 的名字了


设置 gf 的搜索路径


可以使用 'path' 选项来搜索路径列表,试试以下命令:
列出 path 内容:
:set path
设置 path 列表:
:set path=.,/usr/include
添加 path 列表:
:set path+=/usr/*/include
:set path+=/projects/invent/**/include

这样,我们可以将常用的头文件或文档路径放在 path 中,
建立一书签文件,对每个文件作注释,要编辑文件时直接 gf 即可。

详情见帮助:help gf


:help ctags

仔细看看帮助文档,你将大有裨益。

若觉得看英文较累的话,可以看看 vim 的中文帮助,见
http://doc.linuxpk.com/doc/vim/

安装这些中文文档后,help 出来的就是舒服的中文了。


>inoremap <silent> <C-F> <C-O>:exe "norm! kly0jPD"<CR>
>能解释一下这个命令吗?

这个是 insert mode 的 key map, 在insert mode里按 Ctrl-F ,相当于:
<C-O> - 临时切换至 normal mode,执行完后会返回 insert mode
:exe "..." - 执行引号里的命令。
norm! ... - norm! 后内容是 normal mode 下的命令。
<CR> - 回车

这样 kly0jPD 就好理解了:
k (光标上移一行) -> l(光标左移一列) -> y0(复制至行首)
-> j(光标下移一行) -> P(粘贴) -> D(删除多余内容)

呵,要理解的话,最好是将<C-O>:exe "norm! kly0jPD"在 insert mode 下手动输入一次。

posted @ 2009-01-12 23:51  shipfi  阅读(334)  评论(0)    收藏  举报