隐约记得对于Vim的使用,起始于2015年12月份底。当时,是处于Eclipse到Vim的过渡时期。所以,对于Vim的使用基本上是“婴幼儿”级别。

偶然间,我看到了一位同事正在编码的屏幕。不需要触摸板或鼠标的操作,看起来是那么的自然,更是让我看得有些“眼花缭乱”。从那时起,才知道原来Vim可以这么cool(是不是很无知的赶脚?)。

这十个月,经历了从小白到能够把Vim作为主“IDE”的过程。故在此和大家分享下本人在Vim的心得。从最基本的概念、快捷键到一些实用的插件的管理与使用。

在此之前,曾在部门的例会上有做过分享(分享了一个多小时,估计大家都困了),PPT托管在了github.com/genialx/vimer 上,本文的内容也将基本按照着PPT的顺序。Vim的指令集之丰富、功能之强大真,以至于我这种“小白”来在会议上分享Vim可谓多么忐忑,: P

为什么要分享Vim?

这个问题很简单,但更重要。对于Vim,会有两种态度:

1. 我用Vim我怕谁,我用键盘debug和refactoring,虽然有时蛋疼,但是心中自有情怀,我呼吸的是geek的空气,享受在Bram Moolenaar 圣光加持中,你们IDE党都是low逼。
2. 傻X Vim党,窝IDE党轻轻一点强虏灰飞烟灭,乃们还是活在90年代的历史余孽?

本人作为一个对于Vim使用有着“憧憬”的人,固然会毫不犹豫的选择Vim。然而,此文的目的不仅于此,更重要的是对Vim使用与技巧的分享,因为不管你属于哪一类人,Vim都值得你拥有~

为什么要使用VIm?

笔者心得有五:

  • 随时随地,摆脱环境的束缚,你只需要一个终端。
  • 你不必在键盘和鼠标之前来回切换(我压根就觉得鼠标是不服务于“编码工作”的产品),所有的操作都在指尖下
  • 高程度的自定义,所以不要来拷贝他人的配置文件,很伤(如果你是一个不喜欢和别人一样的人的话,这是痛点)。
  • 其他IDE中的功能在Vim里基本能找到替代品,幸福指数飙升~
  • 重复上面四点10000年

Vim的基础概念与使用技巧

“据不完全统计”,该章节《三天三夜》也讲不完(况且,笔者实力不够)。所以,拿出笔者在工作使用中最为实用的一些点来逐一讲解。

方向键

朋友们,你是否还在使用“上下左右”键来移动光标呢?可不幸的是,在vim下这么做看起来会让人觉得很蠢。在Vim下却是使用hjkl键来分别替代左下上右按键,这是为什么呢?

关于这个问题,以前网络上有一种说法,手指放在键盘上输入时,HJKL 比方向键距离手指更近,自然输入效率就更高。听起来似乎很有道理哦,其实并不完全这样,来看看 Peteris Krumins 找到的答案吧。

有一天我在看一些有关 Vim 的东东时,发现了它为什么用 HJKL 键作为方向键的原因了。当 Bill Joy 创建 Vi 文本编辑器时,他使用的机器是 ADM-3A 终端机,这机器就是把 HJKL 键作为方向键。自然而然,Bill Joy 也就用了相同的按键了。

HJKL 键 就是下面这个样子的:

ADM-3A 终端机键盘上的 HJKL 键同时带有箭头
ADM-3A 终端机键盘上的 HJKL 键同时带有箭头

既然 Vim 是源自 Vi,所以也就使用了相同的 HJKL 键。

如果你想了解为什么esc键是用来切换vim模式,home目录为什么是“~”和为什么Vim党习惯将Caps Lock键改成Ctrl键,看下图(秒懂)~

ADM-3A 终端机键盘电路板
ADM-3A 终端机键盘电路板

模式

Vim的几种重要的模式有:normal(正常)模式、command(命令)模式、insert(插入)模式、visual(可视)模式等等

  • normal 正常模式 – 在你打开Vim后所处的模式,在该模式下你可以自由的移动光标的位置
  • command 命令模式 – 在你输入“:”符号后所处的模式,在该模式下你可以输入无限“美好”的指令集,比如edit .、find、new(后面会讲到这些命令呦)等等
  • insert 插入模式 – 在你输入“i”符号后所处的模式,在该模式下可以尽情的《为你写诗
  • visual 可视模式 – 在你输入“v”符号后所处的模式,在该模式下可以《选择》任意代码块

动作

Vim的动作主要含有:

  • c(ut)剪切 – 对!你没有看错,c指的是cut而非copy,为什么这么反人类的思维我并不清楚。
  • d(elete)删除 – 使用该操作或cut操作后,都会将当前的内容放在剪切板的缓冲区中,所以,可以接着使用下面的p来粘贴。
  • y(copy)复制 – 你可能会知道了为什么c是cut而y是copy了
  • p(paste)粘贴 – 这个没什么好说的,只是为了对称罢了

元素

  • w 代表单词
  • s 代表句子(以英文字符“.”识别,含有一个“.”为一句子)
  • p 代表段乱(以“\n”字符识别,含有一个空行为一段落)

运动

Vim的几种运动含有:i(n)、a(ll)和t(ill)

这个东西厉害了,她可以配合上面的动作来做很多组操作。

  • in 在什么什么内(不包含边界)
  • all 在什么什么内(包含边界)
  • till 直到什么什么(不包含边界)

举个例子:

[code lang=”cpp” collapse=”true”]

[/code]

#include <phpcpp.h>

/**
 * Native function that is callable from PHP.
 *
 * This function gets one parameter that holds a callable anonynous
 * PHP function.
 *
 * @param params The parameters passed to the function
 */
void other_function(Php::Parameters & params) {
  // make sure the function was really called with at least one parameter
  if (params.size() == 0) return nullptr;

  // this function is called from PHP user space, and it is called
  // with a anonymous function as its first parameter
  Php::Value func = params[0];

  // the Php::Value class has implemented the operator (), which allows
  // us to use the object just as if it is a real function
  Php::Value result = func(3, 4);

  // @todo do something with the result
}

/**
 * Switch to C context, because the Zend engine expects the get_module()
 * to have a C style function signature
 */
extern "C" {
  /**
   * Startup function that is automatically called by the Zend engine
   * when PHP starts, and that should return the extension details
   * @return void*
   */
  PHPCPP_EXPORT void * get_module() {
    // the extension object
    static Php::Extension extension("my_extension", "1.0");

    // add the example function so that it can be called from PHP scripts
    extension.add("other_function", other_function);

    // return the extension details
    return extension;
  }
}

代码来自《PHP扩展利器 PHP-CPP文档中文版

  • c+i+w 在normal模式下,光标放在第三行的Native单词任意字母上执行,看看会有啥效果(Native被干掉了)?
  • c+i+s 在normal模式下,光标放在第三行任意位置上执行,看看会有啥效果(前三行被干掉了)?
  • c+i+< 在normal模式下,光标放在第一行<>符号内任意字符上执行,看看会有啥效果(<>里面的东西被干掉了)?
  • c+a+< 在normal模式下,光标放在第一行<>符号内任意字符上执行,看看会有啥效果(<>及其里面的东西被干掉了)?
  • y+t+; 在normal模式下,光标放在第十三行任意位置执行后,在敲击粘贴(p)字符,看看会有啥效果(粘贴了光标位置到“;”字符之间的内容)?
  • d+i+p 在normal模式下,光标放在任意位置执行,看看会有啥效果(整个代码被干掉了)?

所以,你可以任意组合以达到不同的效果,有木有很爽?

缩进

在进入可视模式下,进行选择代码后,连续敲击两次“=”符号,即可进行代码排版缩进功能。

同学问:“为什么排版后的格式看起来并不对?”

笔者答:“这是因为vim默认的配置下缩进字符个数和字符类型也许和你当前代码中的缩进情况不一致,导致看起来异常。请参阅《深入IDE利器VIM:tab键的配置》,会解决你的问题。”

所谓宏就是一系列指令操作的集成,利用宏可以实现很多重复的劳动。命令非常简单,共三步:

  • qa在正常模式下连续输入qa – 开启录制,并将录制的内容存到寄存器a中
  • q 在正常模式下输入q – 再次按下q会停止录制
  • 10@a 在正常模式下连续输入10@a – 执行10次存放在寄存器a中的指令集

比如,我们想将http://huati.weibo.cn/Discovery/super网页中的超级话题格式化成数组的形式,如”张艺兴“。首先,打开网页拖动指针进行复制;再将剪切板中的内容粘贴到vim中。就在此时,宏闪亮登场了。

回溯

回溯的功能是让你的代码回到之前某个时间点的状态,类似撤销的效果,只不过以时间为准。

  • :earlier {count}        转到 {count} 次较早的文本状态。
  • :earlier {N}s           转到大约 {N} 秒钟之前的较早的文本状态。
  • :earlier {N}m           转到大约 {N} 分钟之前的较早的文本状态。
  • :earlier {N}h           转到大约 {N} 小时之前的较早的文本状态。

拖动

总是看到同学使用方向键来进行屏幕的滚动操作,其实实现屏幕滚动有很多快捷键:

  • ctrl + e 向上滚动一行
  • ctrl + y 向下滚动一行
  • ctrl + u 向上滚动半屏
  • ctrl + d 向下滚动半屏
  • ctrl + b 向上滚动一瓶
  • ctrl + f 向下滚动一瓶

差不多该小结就说这么多吧,是不是已经很困倦了呢?是的话就休息会吧,笔者写到这也是太累了,也该歇歇了,不可能所有事一天做完。如果您想了解更多,那么快到碗里来呀《Vim快捷键整理》。

当然,我这里有找到一张Vim键位图,非常的全面,希望能够帮助到你。高清矢量图下载:http://pan.baidu.com/s/1jInu7X0

vim键位图
vim键位图

文件在哪里(模糊文件搜索)?

在你打开vim后,看到的却是这种画面?

vim打开的初始界面
vim打开的初始界面

内心是否飘过这种声音“这尼玛怎么搞,岂不是打开另一个文件就得退出vim再打开?”。但是,笔者《后来》总算是学会了如何去爱,不对,是如何打开文件。。。

所以,介绍几个简单却实用的命令:

  • :find 打开文件
  • :ls 查看当前缓存区文件列表
  • :b 打开当前缓存区文件列表(模糊)
  • :edit . 查看当前文件树
  • :new 创建文件

在此之前请先在你的~/.vimrc文件中增加如下几行:

set path+=** “递归目录查找

set wildmenu ” 敲击tab键显示可选项菜单

当然,你还觉得很是麻烦,如果查找起来可以直接的模糊查找,无论是对文件还是路径都可以,那该多好。

So,插件闪亮登场:

Source Code at Github: http://github.com/kien/ctrlp.vim

使用起来很简单,Ctrl+p激活搜索框,之后进行文件模糊搜索。

  • ctrl+j 向下移动
  • ctrl+k 向上移动
  • ctrl+b 搜索缓存区文件模式
  • ctrl+f 搜索磁盘文件模式

那么,这个插件怎么装呢?这个我们后面会讲到,莫及~当然,你也可以安装github上的描述来尝试安装。

代码穿梭机(CTags标签跳转)

首先我们来了解下什么事CTags吧,顾名思义C的标签。所以,你也许猜到了她最先是用来生成C代码的tags文件,后来扩展成可以生成各类语言的tags。旨在可以帮助程序员很容易地浏览源代码。

在你的项目根目录下执行

yum install ctags // 工欲善其事 必先利其器

ctags -R -f tags –fields=+aimS –c-kinds=cdefgnmptuv –extra=+q /your/absolute/project/path // C++语言

ctags -R -f tags –fields=+aimS –languages=PHP /your/absolute/project/path // PHP语言(供参考)

前面的参数就不说了,自行–help。后面最后的路径代表标签的绝对路径。在执行命令后,会在根目录生成一个tags文件,打开她你可以看到为什么要填写/your/absolute/project/path了。

ctags绝对路径
ctags绝对路径

接着打开~/.vimrc文件,加下面一行代码

set tags+=/Users/GenialX/playground/C++/nginx/src/tags

这意味着告诉vim,在搜索标签时包含该tags文件。同时,由于是绝对路径,所以,你可以再不同的项目之间来回穿梭。不至于只能在当前的项目中穿梭(因为vim默认加载当前项目的根目录的tags文件)。

在生成ctags文件后,我们来打开vim。

  • ctrl + ] 跳转到标签
  • ctrl + o 跳出到上一个历史标签位置
  • ctrl + i 跳进到下一个历史标签位置
  • g + ] 查看当前多个匹配标签

代码只写一遍 (自动补全)

诸多IDE的代码自动提示语补全功能很实用,那么在Vim中是不是就无能为力啦?

youcompleteme 插件
youcompleteme 插件

上图是YouCompleteMe插件的Demo,源码托管在了Github上:https://github.com/Valloric/YouCompleteMe

但是,我们这里并不会讨论这个。尽管如此,但是已经足以满足目前笔者的需求。

  • ctrl + N 本地补全 (包含当前tags文件和缓存区)
  • ctrl + x + o Omni 补全(全功能补全)
  • ctrl + n 菜单中选择下一个
  • ctrl + p 菜单中选择上一个

为什么要多个显示器?(多窗口管理)

笔者写到这,已经累得不要不要的了,目前字数已经突破6000。

这个小节来说说Vim的多窗口化和tmux终端多窗口管理器。

Vim的多窗口操作

  • :split / :vsplit 窗口分割(这里可以配置map来进行快捷操作)
  • :res(ize) +/- N 调整高度
  • :vertical res(ize) +/- N 调整宽度
  • <C-w> H/J/K/L 移动窗口
  • <C-w> h/j/k/l 切换窗口

Tmux多终端管理器

这款软件是笔者的刚需,我用它主要有两点原因:

  • 可以在一个窗口内打开多个终端并快速切换
  • 可以保留上一次会话状态(只要Linux不重启)

还记得小的时候完红白机,一个超级马里奥想玩通关需要多久的时间?中间又不能断,不知道烧坏了多少个变压器。然而,后台来有钱买了个能存档的卡带,从此就哇塞了。

Tmux中的命令都是以Ctrl+b来激活的,无论敲击什么命令都需要以ctrl + b开头,也许这个是为了不予终端内容命令冲突吧。

  • tmux new -t session-name 打开终端指定会话(session)
  • tmux new -s session-name 打开新终端并指定会话(session)
  • tmux list-sessions 查看已经有的终端
  • <C-b> 进入tmux命令模式的口令
  • <C-b>d 脱离当前会话
  • <C-b>c 创建tmux窗口
  • <C-b>& 退出当前窗口
  • <C-b>n/p 切换tmux窗口
  • <C-b>:split -v/h -p 水平/垂直分屏
  • <C-b>z 最大化当前窗口
  • http://kumu-linux.github.io/blog/2013/08/06/tmux/

携程在手,想走就走(Vundle插件管家)

在说Vundle之前,先来看看笔者常用的插件吧~

" plugin from vim-scripts.org 
" such as http://vim-scripts.org/vim/scripts.html
Plugin 'taglist.vim'
" plugin on GitHub repo
Plugin 'vim-scripts/winmanager'
Plugin 'GenialX/phpcheck'
Plugin 'The-NERD-tree'
Plugin 'The-NERD-Commenter'
Plugin 'bufexplorer.zip'
Plugin 'rking/ag.vim'
Plugin 'kien/ctrlp.vim'
"Plugin 'vim-scripts/highlight_current_line.vim'
Plugin 'powerline/powerline'
Plugin 'vim-scripts/togglenumber'
"Plugin 'vim-scripts/phpfolding.vim'

简单说下分别的作用吧:

  • taglist 生成文件的结构体、宏、函数等标签树
  • winmanager 窗口管家
  • phpcheck PHP语法检查脚本
  • The-NERD-tree / The-NERD-Commenter 文件浏览器
  • bufexplorer 缓存区文件浏览器
  • ag 代码模糊搜索
  • ctrlp 文件模糊搜索
  • highlight_current_line 当前行高亮
  • powerline 状态栏插件,这块安装相对来说比较麻烦,可以参阅《powerline插件安装之vim篇(Mac)》
  • togglenumber 相对行数
  • phpfolding PHP代码块自动闭合

关于Vundle

Vundle, Vim bundle(捆)的简称,一个管理vim插件的大管家。

Github: https://github.com/VundleVim/Vundle.vim

这里不多说了,下面是常用的命令,如何使用看看Github的官网吧。

 :PluginList - lists configured plugins
 :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate
 :PluginSearch foo - searches for foo; append `!` to refresh local cache
 :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal

笔者的.vim/* 及 .vimrc

百度云盘:http://pan.baidu.com/s/1dFvCbL3

下载后执行如下命令

cp ./vim.tar.bz2 ~

cd ~

tar -xf vim.tar.bz2

cp ~/.vim/.vimrc .

yum install ctags

vim

重要的事情说三遍(建议)

  • 永远不要直接复用其他人的配置
  • 尽量多使用help
  • 视频
    • vim+tmux: http://www.tudou.com/programs/view/WqYvxcISogQ
    • tmux: http://www.tudou.com/listplay/eLwVUsV5A-M/3irTcoFS19k.html
  • 相关文章
    • http://www.ihuxu.com/blog/tag/vim/

参考资料(不分先后顺序):

文章来源:胡旭博客 => 作为10个月的Vim使用者心得总结

转载请注明出处,违者必究!

Share:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.