vim简介及入门指南

我经常试图去学习Emac编辑器/IDE/OS. 我最后一次尝试时,我花了一些时间去适应,直到我想去配置一个自己的.emacs文件

在我用vi打开.emacs文件那一刻,我意识到我做了什么,vim早已经赢得了我的青睐.

所以,我将vim作为我的首选编辑器[注1]

另一个动机是,我发现我最喜欢的shell(ZSH)有很酷的 vi-mode 包含命令模式(使得,你可以在命令和插入模式之间切换)

Vim有一系列给力的特性,并且学习它们需要花费一些时间.当然,现在有很多在线指南和技巧文章,但是帮助文档同样很优秀!有概览页面,总结页面和一些注释

我开始使用官网的指南和帮助系统学习(输入 :help 可以从命令模式获取帮助), 我喜欢在测试文件中测试命令,并且对重要的命令写下简短的说明

另一个我使用Vim的原因是,使用Vim比Emacs更加健康(使用默认键映射).健康?很多命令可以简单地通过一次敲击完成 - 模式编辑器的优点,不需要使用由很多修改关键字组成的长命令串.即使你有一个正常的键盘,敲击Ctrl,Alt等键很显然不是那么正常

只需要记住:Vim的命令都非常简单,但是简单命令组合起来将变得十分强大

模式

Vim有3种模式:

1.命令行模式:所有键盘输入都是命令

2.插入模式:大部分键盘输入作为文本插入(出了少部分特殊键)

3.可视模式:用于帮助选中文本,可以看做是命令行模式的子模式

模式转换图

从插入模式或可视模式切换到命令模式,按

从命令模式切换到插入模式:

  1. * i 在当前位置之前插入
  2. * a 在当前位置之后插入(追加)
  3. * I 调到当前行第一个非空白字符之前插入
  4. * A 调到当前行最后一个字符之后插入

从命令模式到可视模式:

  1. * v 切换到可视模式(字符级别)
  2. * V 切换到可视模式(行级别)
  3. * ctrl-v 切换到块可视模式(块级别的)

所有操作,比如替换,删除,拷贝或排版,在可视模式下同样适用

移动

简单的移动命令

  1. * h 左移
  2. * l 右移
  3. * k 上移
  4. * j 下移

很显然,这几个命令只在命令模式下可用,当然,你可以用方向键(在所有模式下适用)

Vim有很多移动命令,我只是学习了一部分,但是如果你需要一些特殊的移动方式,可以看看帮助,我确定你会找到有用的方法

移动说明图

Vim distinguishes between screen-lines (those shown on the monitor) and real lines (those ended with a new-line). Vim区分逻辑行(频幕上展示的)和物理行(实际以\n结尾的)

以下是一些重要的命令

  1. 0 当前行第一列
  2. ^ 当前行第一个非空白字符
  3. w 移到下一个单词
  4. W 移到下一个单词,忽略标点
  5. e 移动到单词尾部
  6. E 移动到单词尾部,忽略标点
  7. b 移动到单词开头
  8. B 移动到单词开头,忽略标点
  9. ge 移动到前一个词尾部
  10. gE 移动到前一个词尾部,忽略标点
  11. g_ 移动到最后一个非空白字符
  12. $ 移动到最后一列

如果你记住一部分,你将学会如何快速从A移动到B!另一个重要的事实是,这些命令说明了基本命令的定义方式

编辑

在Vim中,插入文本是很简单的事情,只需要敲i并且开始输入.但是vim提供了相当丰富的文本编辑命令

  1. d 删除当前光标位置到下一个命令哪个提供位置之间的字符(例如: d$删除当前行光标位置到最后一列的所有字符)
  2. c 修改
  3. x 删除光标位置字符
  4. X 删除光标之前的字符(相当于回退)
  5. y 拷贝
  6. p 在当前光标之后黏贴拷贝的内容
  7. P 在当前光标之前黏贴拷贝的内容
  8. r 替换当前字符
  9. s 用输入替换当前位置到下一个命令给出位置的字符
  10. . 重复上一个命令

dd, cc 或yy 将操作整行,例如yy拷贝当前行

需要注意的是,很多命令比我在这里描述的额更为强大.例如你可以 输入”ayy 拷贝当前行道一个寄存器a,可以使用 “ap 黏贴a中的内容. Vim自动保存最后几个复制或删除的内容,要查看寄存器的内容,输入:registers, 你可以使用它们去黏贴一些老的文本

可视块

可视块使得能够在选中文本每一行某个位置插入一个字符

假设你选中了一块代码(Ctrl-v),你可以键入I,在代码块之前插入文本(切换到插入模式).当你离开插入模式时,输入的文本将作用于选中的每一行.使用A在代码块之后进行插入

另一个有用的特性是,你可以用新文本替换整个代码块.选中代码块,输入s,vim进入插入模式,然后输入内容.离开插入模式时,vim将输入的内容插入到剩余行

如果你想追加文本到某些行后边,使用Ctrl-v$选中需要修改的行选中需要修改的行. 这个和上一个命令不同的是,$表示”行尾”,ctrl-v选中行的行尾,忽略文本

使用 Ctrl-v:

  1. This is a testNEWLY INSERTED
  2. This is a NEWLY INSERTED
  3. This is NEWLY INSERTED

使用 Ctrl-v$:

  1. This is a testNEWLY INSERTED
  2. This is aNEWLY INSERTED
  3. This isNEWLY INSERTED

文本对象

Vim命令操作文本对象(字符,单词,括号分割的字符,句子等等)

对我来说,最重要的一个是 在单词中: iw. 要选中当前的单词,只需要键入 viw (v可视模式,iw选中光标所在词),同样的,删除: diw

inner-word/block和a-word/block的区别在于,前者只选中单词的字符(不包括空白字符) 或者括号中的内容(不包括括号本身).后者包括括号本身或者单词后的空白字符

  1. iw 单词
  2. aw 单词+后面空白
  3. iW inner WORD
  4. aW a WORD
  5. is 句子
  6. as 句子+后面空白
  7. ip 段落
  8. ap 段落+段落后空白
  9. i( or i) 括号中
  10. a( or a) 括号中+括号
  11. i< or i>
  12. a< or i>
  13. i{ or i}
  14. a{ or a}
  15. i" 引号中
  16. a" 引号中+引号
  17. i`
  18. a`

下面是命令命令的展示,[]表示选中的文本:

  1. iw This is a [test] sentence.
  2. aw This is a [test ]sentence.
  3. iW This is a […test…] sentence.
  4. aW This is a […test ]sentence.
  5. is sentence. [This is a sentence.] This
  6. as sentence. [This is a sentence. ]This
  7. ip End of previous paragraph.
  8. [This is a paragraph. It has two sentences.]
  9. The next.
  10. ap End of previous paragraph.
  11. [This is a paragraph. It has two sentences.
  12. ]The next.
  13. i( or i) 1 * ([2 + 3])
  14. a( or a) 1 * [(2 + 3)]
  15. i< or i> The <[tag]>
  16. a< or i> The [<tag>]
  17. i{ or i} some {[ code block ]}
  18. a{ or a} some [{ code block }]
  19. i" The "[best]"
  20. a" The[ best”]
  21. i` The `[best]`
  22. a` The[ `best`]

可以尝试使用,熟悉并记住(对我而言,iw和i() 真正地节省了时间)

Undo和Redo

不要害怕使用一系列命令,你可以在命令模式下撤销,用u - 甚至用ctrl-r撤销刚才的撤销操作

Vim7.0 介绍了撤销分支,但我没有时间去深入了解

外部命令

Vim很容易加入外部命令的输出,或者通过外部过滤器过滤整行或部分

使用外部命令 :!command 输出将会展现出来

通过外部命令过滤文本,可以使用 :!sort %

将外部命令的输出插入到当前文件 :r!command (例如 :r!which ls)

查看更多关于filter的信息 :h filter

搜索和替换

在Vim中搜索非常简单,在命令模式下输入 / ,然后填入你要搜索的词,然后vim会搜索这个文件(当前位置向前)

使用? 进行向后搜索

在搜索结果中,使用n或N进行重复搜索(和前一个搜索同一个方向)

如果设置了”incsearch”, Vim会立刻跳到匹配文本位置,如果设置了”hlsearch”, 将会高亮所有匹配文本. 要去除高亮,:nohl

替换同样不是很难,但是你需要对正则表达式有所了解

使用正则替换某些文本,输入 :%s/old/new/gc 这个命令将会遍历整个文件%, 用单词”new”替换所有”old”. g代表替换行中所有匹配文本,c代表替换前询问

如果只需要替换选中区域中的某些文本,选中区域,输入 :s/old/new/g.

这个就像

  1. :'<,'>s/old/new/g

在标签一节之后,你将会知道 ‘<’和’>’的意思

补全

在你输入时,反复输入同一个词是很正常的事情. 使用Ctrl-p,vim会反向搜索最近输入过的拥有相同开头的词, ctrl-x ctrl-l补全整个词

如果你不确定如何拼写某个词,并且你设置了拼写检查(:set spell),你可以使用 Ctrl-x Ctrl-k 到字典中查询已经输入的词.Vim自动补全系统在7.0后得到了很大的改善.

注意,自动补全命令仅在插入模式下有效,在命令模式有其他的作用

标签

你可以在文档中设置标签,实现在文档中不同位置的快速跳转

vim自动设置的标签

  1. {0-9} 关闭文件的最近10个位置(0 最后一个, 1 倒数第二个)
  2. < and > 标记文本左边/右边的位置
  3. ( and ) 当前句子的开始/结束
  4. { and } 当前段落的开始/结束
  5. [ and ] 拷贝或修改文本的第一/最后一个字符的位置
  6. . 最后修改点位置
  7. ' or ` 上次跳转点位置
  8. " 退出文件前的最后一个位置
  9. ^ 最后插入/修改位置

要设置自定义标签,使用 m{a-zA-Z} (例如 ma ), 如果要跳转到某个标签(自定义或预定义),可以使用 ‘ 和 `

  1. ' 将光标移到标记行首个非空字符位置
  2. ` 移到设置标签时得准确位置

大写和小写标记之间有些区别

  1. {a-z} 文件维度
  2. {A-Z} 会话维度,和文件关联,可以跨文件跳转

例如,可以使用 L 标记work-log 使用T标记time-table ,然后进行快速跳转

例如,你可以键入 ‘“ 跳转到文件关闭前光标所在位置(Vim可以通过配置实现)

  1. 列出标签列表 :marks
  2. 删除 :delmarks a b c
  3. 删除所有 :delmarks!

标签页(tab) ,缓冲(buffer) 和 窗口(window)

Vim 7.0介绍过tabs. 我们都知道并喜欢tabs,所以这里不多提. (注意: vim中的tabs和其他程序中的tabs略有不同.不同点在于,每个tab页可以拥有自己的布局, 例如我可以在第一个tab中切分窗口,在第二个tab中不切分)

命令行中用vim一次性打开多个tab vim -p *.txt

切换tab, 可以使用鼠标(gVim) 或者输入 gt

创建一个新的空tab,输入 :tabnew

或者在一个新tab中打开文件 :tabe xyz

buffer和window有些不好理解,window是打开vim时你看到的,当你打开帮助(:help bufers), 你将会得到两个window.并非真正的窗口,是vim提供的展示视图

你可以打开一个window,切分成水平两个 :sp 或者竖直两个 :vsp. 通过这个方法,vim将同一个buffer放在两个不同的window. 你可以打开文件, :sp filea 或者 :vsp fileb. 在窗口之间跳转,命令模式下使用 Ctrl-w {hjkl}

buffer大多数情况下是一个文件,但是不要求可见. 所以通常一个window中有多个buffer, 要在当前window中展现不同的buffer , 使用 :b NUMBER, 可以使用 :buffers查看对应buffer的编号,通常情况下,vim要求你在切换到另一个buffer之前,保存当前buffer, 所以切换报错时不要太过惊讶(可以 :set hidden 使未保存buffer生效,但需谨慎使用)

下面是我的笔记:

  1. :b N 切换到buffer N
  2. :buffers 展示buffer列表, 字符含义
  3. % 当前window
  4. # 替换buffer (使用 :e# or :b#切换)
  5. a 活动的(加载并可见)
  6. h 隐藏的(加载但不可见)
  7. + 修改的
  8. :bd 关闭buffer并从buffer列表移除(不关闭vim,即使最后一个buffer关闭)
  9. :bun 关闭buffer但留存在bufferlist
  10. :sp #N 分屏并编辑buffer N
  11. :w 保存当前buffer
  12. :e 重新加载当前文件
  13. :q 退出
  14. :new 新的空window
  15. :on 关闭除当前活动window之外的所有window(Ctrl-W o)
  16. Ctrl-W {h,j,k,l} 窗口之间切换

设置’hidden’后,允许修改未保存的buffer隐藏,buffer会自动保存如果未设置’hidden’,设置了’autowrite’

Vim允许使用点. 重复某些命令,当存在多个命令时,使用宏

你可以开始 录制宏, 使用 q和{0-9a-zA-Z}, 例如 qq 录制用于buffer”q”的宏,完成录制后,键入q退出

现在你可以使用 @q 在任何时候调用宏

最后

我希望可以帮助你开始学习vim. 我可以做的最后一件事是,提供我的vim配置文件. 使用 :help … 去学习vim更强大的功能并在后续写一篇指南

可以将vimrc文件放入你的home目录(~/.vimrc),但是要先确定这个目录下还没有这个文件

注解1: Vim是一个编辑器,不是IDE 或者操作系统. 不要通过其试图创建一个IDE,如果你喜欢IDE,挑一个来用!当然,vim可以将很多任务自动化,例如编译,跳转到编译错误处,要实现这些,关注下vim的插件

Emacs is a good operating system, but it lacks a good editor. — Old saying.