Vim 系列教程目录:vim
本节会讲一些 Vim 中的高级概念和进阶用法, 了解了这些以后, 能够解开不少疑惑, 使用起来也会更驾轻就熟.windows
CWD(Current Working Directory), 当前工做目录, 这是 Vim 中一个挺重要, 可是却又常常被忽略的概念. 简单来讲, CWD 是 Vim 和操做系统的文件系统进行交互时的上下文环境.缓存
要查看 Vim 的 CWD, 你可使用 :pwd
命令来查看. 正常来讲, 当你点击桌面上的 gVim 图标打开 Vim 时, Vim 的 CWD 是用户目录, 当你在文件上右键->用 Vim 编辑打开 Vim 时, Vim 的 CWD 是文件所在路径.bash
CWD 有什么用呢? 如今请你打开 Vim, 而后在命令模式下执行 :e test_vim_cwd.txt
, 你会看到打开了一个名为 test_vim_cwd.txt 的新文件, 你随便添加一些文本, 而后保存, 你会发现此次 Vim 再也不提示你没有文件名, 你能够直接保存了. 那么问题来了, 这个文件被存到哪里了呢?session
我想你应该已经猜到了, 没错, 在 Vim 里新建的文件, 若是不指定路径, 会被保存到 CWD 里. 因此说 CWD 是 Vim 和文件系统交互时的上下文环境.编辑器
除此以外, Vim 的不少插件工做时也依赖 CWD, 好比 NERDTree, CtrlP 等等.关于插件咱们之后再讲, 如今你先记住, CWD 是会影响一些插件的表现的.布局
在现阶段, 你不须要关心 CWD, 由于咱们如今仍是单文件操做, CWD 是哪都无所谓. 但若是你确实想改一下 CWD, 可以使用 :cd
命令修改 CWD:post
cd d:/xxx/yyy
复制代码
这和命令行里切换目录的方式是同样.学习
OK, 关于 CWD, 先说到这, 后面还会再说. 另外, 如今你又学会一个新命令: :e
, 这个命令能够新建一个新文件. 其实, :e
这个命令后面能够路径/文件名, 若是给定的路径文件存在, 则是打开, 若是不存在, 则是新建.测试
好, 咱们再回到 Vim 的操做中, 请打开一个英文文本文件或输入一些英文, 以便接下来的学习.
以前的复制和删除都是以字符, 行为单位, 而 w, e, b的做用是从光标处到下个单词开头或本单词结尾, 因此要想删除整个单词, 你得这么作: bdw
, 这表示先将光标移动到单词开头, 而后 dw. 这很麻烦, 有时候不当心看错了, 光标就移动错了. 要解决这个问题, 可使用 文本对象.
如今请移动到一个单词的任意一个字母上, 而后执行指令 daw
, 你会发现整个单词被删除了, 神奇吧. 这个指令中的 aw
在 Vim 中表明一个文本对象: a word, 即一个单词, 执行 daw
就表示删掉一个单词, 并且, 不管你在这个单词的哪一个字母上, 均可以执行此命令删掉整个单词.
除了 aw, Vim 还支持下列文本对象:
[]
块, a[, a] 包括两边的 "[]", i[, i] 不包括两边的 []a<, a> / i<, i>
: 一个尖括号块, 细节同上上述文本对象大均可以使用计数器, 例如:
这样一来, 一次性可操做的文本就大大增长了, 并且不用关心光标的位置, 很是便捷.
咱们以前说过, 剪切(删除)的文本会进入到 Vim 中的寄存器里, 那什么是寄存器呢?
所谓寄存器, 就是存放文本和指令/命令的地方, 例如使用 y, d, c 等命令复制或剪切的文本都会被自动存放在 Vim 的寄存器中, 用户能够将文本和指令放在寄存器中, 也能够从寄存器中读出来.
Vim 中共有9类寄存器, 具体以下:
类型 | 标识 | 读写者 | 是否只读 | 包含的字符来源 |
---|---|---|---|---|
Unnamed | " | Vim | 否 | 最近一次的复制或删除操做 (d, c, s, x, y) |
Numbered | 0 到 9 | Vim | 否 | 寄存器 0: 最近一次复制. 寄存器 1: 最近一次删除. 寄存器 2: 倒数第二次删除, 以此类推. 每来一次新的删除和修改, Vim 就把前一次的寄存器 1 的内容复制到寄存器 2, 2 到 3, 依此类推. 而寄存器 9 的内容就丢失了 |
Small delete | 中横线 - | Vim | 否 | 最近一次行内删除 |
Named | a 到 z 或 A 到 Z | 用户 | 否 | 由用户指定时使用, 用户可将文本存储到这些寄存器中. 若是存储至寄存器 a, 那么 a 中的文本就会被覆盖. 若是你存储至 A, 那么会将文本添加给寄存器 a,不会覆盖以前已有的文本 |
Read-only | : 与 . 与 % 和 # | Vim | 是 | : 为最近一次使用的命令, . 为最近一次添加的文本, % 为当前的文件名, # 为轮换文件名 |
Expression | = | 用户 | 是 | Vim 存储表达式的地方, 用户只可读 |
Selection/Drop | + 与 * 和 ~ | Vim | 否 | + 和 * 为 GUI 选择寄存器, 你能够理解为它们就是系统的剪切板, - 为鼠标拖放的寄存器 |
Black hole | 下划线 _ | Vim | 否 | 通常称为黑洞寄存器, 当把文本写到这个寄存器中时, 什么都不会发生, 且不可读, 这个寄存器可用来删除文本而不影响其余寄存器 |
Last search pattern | / | Vim | 否 | 最近一次经过 / 、? 或 :global 等命令调用的匹配条件 |
要查看这些寄存器中到底有什么, 可使用以下命令:
须要注意的是, 有些寄存器名字为特殊字符, 须要使用 \ 转义.
如今你能够先复制一段文本, 而后执行命令 :reg "
, 查看一下 Unnamed 寄存器中的值.
要访问寄存器, 须要使用 "
做为前缀, 例如: "0
, "a
.
接下来咱们作一个测试, 例如将 'hello' 这个单词存储到寄存器 a, 先将光标移动到 'hello' 这个单词上, 而后执行:
"ayiw 复制代码
上述指令表示: 使用寄存器 a, 而后复制一个单词. 此时使用命令 :reg a
查看寄存器 a 中的内容, 就能看到 'hello' 了. 须要注意的是, 当使用复制剪切等命令向指定寄存器中写入内容时, 内容同时也会被写入到 Unnamed 寄存器.
每次向寄存器中写入内容, 会将寄存器中已有的内容覆盖, 若是想要往寄存器中追加内容, 则需使用大写字母防卫寄存器, 如: "Ayiw
, 这表示将当前单词追加到 寄存器 a 中.
要读取寄存器 a 中的内容, 则可以使用以下命令:
"ap 复制代码
这表示先启用 寄存器 a, 而后进行粘贴操做, 你就能够看到, 寄存器 a 中的内容被粘贴出来了.
另外, 在插入模式下也能够访问寄存器, 在 插入模式中按 Ctrl-r, 而后再输入寄存器标识(不用输入", 直接输入标识), 就能够将对应寄存器中的内容输出.
上面说了, y, d, c, x, s
等命令都是将内容存进了 Unnamed 寄存器中("), Unnamed 寄存器是 Vim 本身的寄存器, 操做系统是访问不到的, 因此你到别的软件了使用 Ctrl-v
是是没法粘贴出来的.
可是 Vim 中有另外两个寄存器: +
和 *
, 这两个寄存器能够理解为操做系统的剪切板, 因此咱们能够经过这两个寄存器对系统的剪切板进行读写, 方式以下:
"+y
/ "+d
/ "+c
将内容复制/剪切到系统剪切板"+p
将系统剪切板内容粘贴出来PS. 使用 "+ 和 "* 效果同样
上节咱们讲过 .
这个指令, 能够重复上次的操做, 咱们也说了, .
本质上是一个"宏", 那么什么"宏"呢?
所谓"宏", 其实就是能够反复播放的一系列操做的集合. 前面说了, 寄存器不仅是能够存储数据, 还能够存储指令/命令, Vim 中的宏就是将指令存储到寄存器中, 而后再读取出来. 宏的使用步骤以下:
qm
, 表示将宏录制到 m 寄存器中.@m
播放m寄存器中的宏, 前面能够加数字表示播放次数@@
表示播放以前播放过那个个宏录制好宏以后, 能够经过 reg
查看宏中的内容. 另外, 一样能够经过使用大写字母访问寄存器, 追加宏命令.
在 Vim 中打开的文件都会被存放在 Vim 的缓冲区中. 缓冲区在内存里, 当修改了文件还未保存时, 改动就在缓冲区中, 当保存时, Vim 会将缓冲区中的内容写到文件. 要查看缓冲区中有哪些文件, 可以使用 :buffers
命令, :ls
, :files
命令能够起到一样的效果.
运行这个命令后, 你会看到相似的输出:
1 "Android\AFeed\02_项目基本配置.md" 第 39 行
3 a "[未命名]" 第 0 行
5 "Develop\Editor\Vim_1_基本使用.md" 第 177 行
6 %a "Develop\Editor\Vim_2_高级用法.md" 第 203 行
7 a "\Program Files (x86)\Vim\_vimrc" 第 0 行
8 "Develop\Editor\Vim_3_vimrc.md" 第 86 行
9 "Develop\Editor\Vim_5_经常使用插件(通用).md" 第 117 行
复制代码
缓冲区列表第一列是其序号, 第二列是标记, 标记的含义以下:
如何操做这些 Buffer 呢? 可以使用以下命令:
:buffer <buffer no>
经过 Buffer 编号切换到指定 Buffer, 简写 :b <buffer no>
:buffer <file name>
经过文件名切换到指定 Buffer, 简写 :b <file name>
:bnext
, :bprevious
切换到下一个/上一个 Buffer, 简写 :bn
, :bp
:bfirst
, :blast
切换到第一个/最后一个 Buffer, 简写 :bf
, :bl
:bdelete <buffer no>
删除指定缓冲区, 简写 :bd <buffer no>
关于 Buffer 要注意:
Vim 中一个编辑区域中能够有多个窗口. 所谓窗口, 其实就是把编辑区分割成不一样区域, 每一个区域被称为一个窗口. 窗口是用来显示 Buffer 的, 当你打开 Vim 时, 其实同时也打开了一个窗口, 只是这个窗口占满了整个编辑区域.
使用以下命令, 能够把当前分割窗口:
:split
: 在当前窗口上边打开新窗口, 新窗口中依然是当前文件, 简写为 :sp
:split filenpath
: 在当前文件上边打开新窗口, 新窗口中为指定文件, 简写为 :sp filepath
:vsplit
: 在当前文件左边打开新窗口, 新窗口中依然是当前文件, 简写为 :vsp
, 一样可指定文件名:new
: 在当前文件上边打开新的空白窗口, 不可指定文件名:vnew
: 在当前文件左边打开新的空白窗口, 不可指定文件名注意:上述命令均可以在前面加一个数字, 表示新窗口的大小(行数), 如 :3sp a.txt
, 则打开 a.txt 的窗口只有三行. 另外, 能够反复使用上述命令, 把窗口分割成更小的窗口.
关于窗口的几个快捷键:
关于窗口的几个命令:
:close
关闭当前窗口, 其实 q 命令和 ZZ 也是能够关闭当前窗口的, 只不过 :close
命令能够保证不会关闭最后一个窗口:only
只保留当前窗口, 关闭其余窗口, 若是其余窗口中的文件没保存, 会有警告:wall
保存全部窗口:qall
退出全部窗口:wqall
保存并退出全部窗口除了窗口功能, Vim 还支持多标签页功能. 标签页是窗口的合集, 即一个标签页中有多个窗口, 而:wall
, :qall
等窗口功能其实只对当前标签页中的窗口有效. 使用下列命令, 能够开启新的标签页:
:tabedit
: 打开新的空白标签页, 简写: tabe
:tabedit filepath
: 在新的标签页中打开指定文件, 简写: tabe filepath
:tab split
: 打开新的标签页, 其内容是当前标签页:tab help
: 在新的标签页中打开帮助文档关于标签页的几个指令/命令:
:tabn
切换到下一个标签页:tabp
切换到上一个标签页:tabn
数字: 切换到指定位置的标签页, 从1开始:tabc
关闭当前标签页( tabclose 的简写):tabo
只保留当前标签页, 关闭其余标签页(tabonly 的简写)先引用文档中的原话(help window):
Summary: SummaryA buffer is the in-memory text of a file. A window is a viewport on a buffer. A tab page is a collection of windows.
个人理解:
一些奇怪现象的解释:
能够再看看这些文章:
不少软件都具备这样一种功能: 在你下一次启动该软件时,它会自动为你恢复到你上次退出的环境, 恢复窗口布局, 所打开的文件等等. Vim 也有相似的功能, 只是用起来比较麻烦...
当你要退出 Vim 时, 能够保存一个 Vim Session(会话), Vim 会话存放着所 有跟你的编辑相关的信息. 这包括诸如文件列表, 窗口布局, 全局变量, 选 项, 以及其它信息.
要保存会话信息, 可以使用命令 :mksession sessionname
, 简写为 :mks sessionname
, sessionname 由你指定, 会话信息会保存到名为 sessionname 的文件中, 默认状况下, Session 文件是存在用户目录下的, 固然你也能够指定 Session 文件的路径, 例如: :mksession d:/vim/session1
. 若是 Session 文件已存在, 你须要使用 :mksession! d:/vim/session1
来保存 Session.
下次你打开 Vim, 能够载入这个 Session 文件, 就能恢复以前的会话信息了, 要载入会话, 可以使用命令 :source sessionname
.
比起其余编辑器, Vim 的 Session 稍显难用一些.
折叠... 怎么解释呢, 就是把一段文本显示为一行, 就像一张纸, 要把它缩短些, 就折叠起来. 被折叠的文本其实还在, 只是显示方式变了. 折叠的好处 是, 经过把多行的文本折叠成带有折叠提示的一行, 会使你更好地了解对文 本的宏观结构.
要建立一个折叠, 可以使用 zf
指令, 你能够把光标移动到某一个段落内, 而后使用指令 zfap
, 你会发现, 这段文字被折叠了. 这个指令的含义是: zf
是折叠指令, ap
是文本对象, 表示一段, zfap
就表示折叠一段文字.
要展开折叠的文本, 可将光标移动到折叠行上, 使用 zo
指令, 折叠的文字就会展开. 要想再次折叠, 使用 zc
指令, 此次为啥不用 zf
了? 由于 zf
是建立折叠的.
经常使用折叠指令:
总的来讲, 折叠用的很少, 这里就很少介绍了.
:r! <cmd>
或者 :r !<cmd>
便可, 注意 <cmd>
指的是你要输入的系统命令:redir > a.txt
, 此命令意为将命令输出到 a.txt 中, 默认会在 pwd 目录下新建文件, 你也能够指定文件路径, 若是文件已存在, 可以使用 redir!
进行覆盖, 或使用 redir >> a.txt
进行追加.redir END
, 此命令意为重置命令输出位置.本节讲了一些 Vim 中的进阶用法, 可让你处理文本时更加方面快捷. 另外, 对于 Vim 中的寄存器, Buffer, Window, Tab等概念也有详细的介绍, 了解这些会让你理解 Vim 的一些行为. 仍是那句话, 多练习, 在用的过程当中学习, 感悟.