Formate content

This commit is contained in:
Shidong Wang 2018-12-31 12:55:32 +08:00
parent b3a51b2cc2
commit 4903728828

201
README.md
View File

@ -1,6 +1,7 @@
# Vim 从入门到精通
> 本文主要在翻译 [mhinz/vim-galore](https://github.com/mhinz/vim-galore) 的基础添加了一些我在使用 Vim 及开发 Vim 插件的过程中积累的一些细节。
> 本文主要在翻译 [mhinz/vim-galore](https://github.com/mhinz/vim-galore)
的基础添加了一些我在使用 Vim 及开发 Vim 插件的过程中积累的一些细节。
<!-- vim-markdown-toc GFM -->
@ -85,7 +86,7 @@
- [调整日志等级](#调整日志等级)
- [查看启动日志](#查看启动日志)
- [查看运行时日志](#查看运行时日志)
- [Vim脚本调试](#vim脚本调试)
- [Vim 脚本调试](#vim-脚本调试)
- [语法文件调试](#语法文件调试)
- [杂项](#杂项)
- [附加资源](#附加资源)
@ -109,20 +110,29 @@
## 什么是 Vim
[Vim](https://github.com/vim/vim) 是一个历史悠久的文本编辑器,可以追溯到 [qed](https://en.wikipedia.org/wiki/QED_(text_editor))。[Bram
Moolenaar](https://en.wikipedia.org/wiki/Bram_Moolenaar) 于 1991 年发布初始版本。
[Vim](https://github.com/vim/vim) 是一个历史悠久的文本编辑器,可以追溯到
[qed](<https://en.wikipedia.org/wiki/QED_(text_editor)>)。
[Bram Moolenaar](https://en.wikipedia.org/wiki/Bram_Moolenaar) 于
1991 年发布初始版本。
Linux、Mac 用户,可以使用包管理器安装 Vim对于 Windows 用户,可以从 [我的网盘](https://share.weiyun.com/da2be5937ac0e2bd3abc26355fad1204) 下载。
该版本可轻易添加 `python``python3``lua` 等支持,只需要安装 python、lua 即可。
Linux、Mac 用户,可以使用包管理器安装 Vim对于 Windows 用户,可以从
[我的网盘](https://share.weiyun.com/da2be5937ac0e2bd3abc26355fad1204) 下载。
该版本可轻易添加 `python``python3``lua` 等支持,只需要安装 python、lua
即可。
项目在 [Github](https://github.com/vim/vim) 上开发,项目讨论请订阅
[vim_dev](https://groups.google.com/forum/#!forum/vim_dev) 邮件列表。
[`vim_dev`](https://groups.google.com/forum/#!forum/vim_dev) 邮件列表。
通过阅读 [Why, oh WHY, do those #?@! nutheads use vi?](http://www.viemu.com/a-why-vi-vim.html) 来对 Vim 进行大致的了解。
通过阅读 [Why, oh WHY, do those #?@! nutheads use vi?](http://www.viemu.com/a-why-vi-vim.html)
来对 Vim 进行大致的了解。
## Vim 哲学
Vim 采用模式编辑的理念,即它提供了多种模式,按键在不同的模式下作用不同。你可以在 _普通模式_ 下浏览文件,在 _插入模式_ 下插入文本,在 _可视模式_ 下选择行,在 _命令模式_ 下执行命令等等。起初这听起来可能很复杂,但是这有一个很大的优点:不需要通过同时按住多个键来完成操作,大多数时候你只需要依次按下这些按键即可。越常用的操作,所需要的按键数量越少。
Vim 采用模式编辑的理念,即它提供了多种模式,按键在不同的模式下作用不同。
你可以在**普通模式** 下浏览文件,在**插入模式**下插入文本,
在**可视模式**下选择行,在**命令模式**下执行命令等等。起初这听起来可能很复杂,
但是这有一个很大的优点:不需要通过同时按住多个键来完成操作,
大多数时候你只需要依次按下这些按键即可。越常用的操作,所需要的按键数量越少。
和模式编辑紧密相连的概念是“操作符”和“动作”。_操作符_ 开始一些行为,例如:修改,删除,或者选择文本。之后你要用一个 _动作_ 来指定需要操作的文本区域。比如,要改变括号内的文本,需要执行 `ci(` (读做 _change inner parentheses_);删除整个段落的内容,需要执行 `dap` 读做_delete
around paragraph_
@ -137,7 +147,7 @@ Vim 自带一个交互式的教程,内含你需要了解的最基础的信息
不要因为这个看上去很无聊而跳过,按照此教程多练习。你以前用的 IDE 或者其他编辑器很少是有“模式”概念的,因此一开始你会很难适应模式切换。但是你 Vim 使用的越多,[肌肉记忆](https://en.wikipedia.org/wiki/Muscle_memory) 将越容易形成。
Vim 基于一个 [vi](https://en.wikipedia.org/wiki/Vi) 克隆,叫做 [Stevie](https://en.wikipedia.org/wiki/Stevie_(text_editor)),支持两种运行模式:"compatible" 和 "nocompatible"。在兼容模式下运行 Vim 意味着使用 vi 的默认设置,而不是 Vim 的默认设置。除非你新建一个用户的 `vimrc` 或者使用 `vim -N` 命令启动 Vim否则就是在兼容模式下运行 Vim请大家不要在兼容模式下运行 Vim。
Vim 基于一个 [vi](https://en.wikipedia.org/wiki/Vi) 克隆,叫做 [Stevie](<https://en.wikipedia.org/wiki/Stevie_(text_editor)>),支持两种运行模式:"compatible" 和 "nocompatible"。在兼容模式下运行 Vim 意味着使用 vi 的默认设置,而不是 Vim 的默认设置。除非你新建一个用户的 `vimrc` 或者使用 `vim -N` 命令启动 Vim否则就是在兼容模式下运行 Vim请大家不要在兼容模式下运行 Vim。
下一步
@ -171,7 +181,7 @@ Vim 基于一个 [vi](https://en.wikipedia.org/wiki/Vi) 克隆,叫做 [Stevie]
使用 `:version` 命令将向你展示当前正在运行的 Vim 的所有相关信息,包括它是如何编译的。
第一行告诉你这个二进制文件的编译时间和版本号比如7.4。接下来的一行呈现 `Included patches: 1-1051`,这是补丁版本包。因此你 Vim 确切的版本号是 7.4.1051。
第一行告诉你这个二进制文件的编译时间和版本号比如7.4。接下来的一行呈现 `Included patches: 1-1051`,这是补丁版本包。因此你 Vim 确切的版本号是 7.4.1051。
另一行显示着一些像 `Tiny version without GUI` 或者 `Huge version with GUI` 的信息。很显然这些信息告诉你当前的 Vim 是否支持 GUI例如从终端中运行 `gvim` 或者从终端模拟器中的 Vim 内运行 `:gui` 命令。另一个重要的信息是 `Tiny``Huge`。Vim 的特性集区分被叫做 `tiny``small``normal``big` and `huge`,所有的都实现不同的功能子集。
@ -275,14 +285,14 @@ Vim 是一个文本编辑器。每次文本都是作为**缓冲区**的一部分
使用 `:map` 命令家族你可以定义属于你自己的快捷键。该家族的每一个命令都限定在特定的模式下。从技术上来说 Vim 自带高达 12 中模式,其中 6 种可以被映射。另外一些命令作用于多种模式:
|   递归   |   非递归     | 模式                           |
| --------- | ------------ | -------------------------------- |
| `:map` | `:noremap` | normal, visual, operator-pending |
| `:nmap` | `:nnoremap` | normal |
| `:xmap` | `:xnoremap` | visual |
| `:cmap` | `:cnoremap` | command-line |
| `:omap` | `:onoremap` | operator-pending |
| `:imap` | `:inoremap` | insert |
|   递归   |   非递归     | 模式                           |
| -------- | ------------ | -------------------------------- |
| `:map` | `:noremap` | normal, visual, operator-pending |
| `:nmap` | `:nnoremap` | normal |
| `:xmap` | `:xnoremap` | visual |
| `:cmap` | `:cnoremap` | command-line |
| `:omap` | `:onoremap` | operator-pending |
| `:imap` | `:inoremap` | insert |
例如:这个自定义的快捷键只在普通模式下工作。
@ -361,19 +371,19 @@ nnoremap <leader>h :helpgrep<space>
Vim 为我们提供了如下的寄存器:
| 类型 | 标识 | 读写者 | 是否为只读 | 包含的字符来源 |
| ------------------- | ------------------ | ------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Unnamed | `"` | vim | 否 | 最近一次的复制或删除操作 (`d`, `c`, `s`, `x`, `y`) |
| Numbered | `0``9` | vim | 否 | 寄存器 `0`: 最近一次复制。寄存器 `1`: 最近一次删除。寄存器 `2`: 倒数第二次删除,以此类推。对于寄存器 `1``9`,他们其实是只读的最多包含 9 个元素的队列。这里的队列即为数据类型 [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) |
| Small delete | `-` | vim | 否 | 最近一次行内删除 |
| Named | `a``z`, `A``Z` | 用户 | 否 | 如果你通过复制操作存储文本至寄存器 `a`,那么 `a` 中的文本就会被完全覆盖。如果你存储至 `A`,那么会将文本添加给寄存器 `a`,不会覆盖之前已有的文本 |
| Read-only | `:``.``%` | vim | 是 | `:`: 最近一次使用的命令,`.`: 最近一次添加的文本,`%`: 当前的文件名 |
| Alternate buffer | `#` | vim | 否 | 大部分情况下,这个寄存器是当前窗口中,上一次访问的缓冲区。请参阅 `:h alternate-file` 来获取更多帮助 |
| Expression | `=` | 用户 | 否 | 复制 VimL 代码时,这个寄存器用于存储代码片段的执行结果。比如,在插入模式下复制 `<c-r>=5+5<cr>`,那么这个寄存器就会存入 10 |
| Selection | `+``*` | vim | 否 | `*``+` 是 [剪贴板](#剪贴板) 寄存器 |
| Drop | `~` | vim | 是 | 最后一次拖拽添加至 Vim 的文本(需要 "+dnd" 支持,暂时只支持 GTK GUI。请参阅 `:help dnd``:help quote~` |
| Black hole | `_` | vim | 否 | 一般称为黑洞寄存器。对于当前操作,如果你不希望在其他寄存器中保留文本,那就在命令前加上 `_`。比如,`"_dd` 命令不会将文本放到寄存器 `"``1``+``*` 中 |
| Last search pattern | `/` | vim | 否 | 最近一次通过 `/``?``:global` 等命令调用的匹配条件 |
| 类型 | 标识 | 读写者 | 是否为只读 | 包含的字符来源 |
| ------------------- | ------------------ | ------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Unnamed | `"` | vim | 否 | 最近一次的复制或删除操作 (`d`, `c`, `s`, `x`, `y`) |
| Numbered | `0``9` | vim | 否 | 寄存器 `0`: 最近一次复制。寄存器 `1`: 最近一次删除。寄存器 `2`: 倒数第二次删除,以此类推。对于寄存器 `1``9`,他们其实是只读的最多包含 9 个元素的队列。这里的队列即为数据类型 [queue](<https://en.wikipedia.org/wiki/Queue_(abstract_data_type)>) |
| Small delete | `-` | vim | 否 | 最近一次行内删除 |
| Named | `a``z`, `A``Z` | 用户 | 否 | 如果你通过复制操作存储文本至寄存器 `a`,那么 `a` 中的文本就会被完全覆盖。如果你存储至 `A`,那么会将文本添加给寄存器 `a`,不会覆盖之前已有的文本 |
| Read-only | `:``.``%` | vim | 是 | `:`: 最近一次使用的命令,`.`: 最近一次添加的文本,`%`: 当前的文件名 |
| Alternate buffer | `#` | vim | 否 | 大部分情况下,这个寄存器是当前窗口中,上一次访问的缓冲区。请参阅 `:h alternate-file` 来获取更多帮助 |
| Expression | `=` | 用户 | 否 | 复制 VimL 代码时,这个寄存器用于存储代码片段的执行结果。比如,在插入模式下复制 `<c-r>=5+5<cr>`,那么这个寄存器就会存入 10 |
| Selection | `+``*` | vim | 否 | `*``+` 是 [剪贴板](#剪贴板) 寄存器 |
| Drop | `~` | vim | 是 | 最后一次拖拽添加至 Vim 的文本(需要 "+dnd" 支持,暂时只支持 GTK GUI。请参阅 `:help dnd``:help quote~` |
| Black hole | `_` | vim | 否 | 一般称为黑洞寄存器。对于当前操作,如果你不希望在其他寄存器中保留文本,那就在命令前加上 `_`。比如,`"_dd` 命令不会将文本放到寄存器 `"``1``+``*` |
| Last search pattern | `/` | vim | 否 | 最近一次通过 `/``?``:global` 等命令调用的匹配条件 |
只要不是只读的寄存器,用户都有权限修改它的内容,比如:
@ -465,7 +475,7 @@ Vim 为我们提供了如下的寄存器:
| `A`-`Z` | 用户 | 全局标注,可以作用于不同文件。大写标注也称为「文件标注」。跳转时有可能会切换到另一个缓冲区 |
| `0`-`9` | viminfo | `0` 代表 viminfo 最后一次被写入的位置。实际使用中,就代表 Vim 进程最后一次结束的位置。`1` 代表 Vim 进程倒数第二次结束的位置,以此类推 |
如果想跳转到指定的标注,你可以先按下 `'` / `g'` 或者 `` ` `` / ``g` `` 然后按下标注名。
如果想跳转到指定的标注,你可以先按下 `'` / `g'` 或者 `` ` `` / `` g` `` 然后按下标注名。
如果你想定义当前文件中的标注,可以先按下 `m` 再按下标注名。比如,按下 `mm` 就可以把当前位置标注为 `m`。在这之后,如果你的光标切换到了文件的其他位置,只需要通过 `'m` 或者 `\`m`即可回到刚才标注的行。区别在于,`'m`会跳转回被标记行的第一个非空字符,而`\`m`会跳转回被标记行的被标记列。根据 viminfo 的设置,你可以在退出 Vim 的时候保留小写字符标注。请参阅`:h viminfo-'\` 来获取更多帮助。
@ -473,20 +483,20 @@ Vim 为我们提供了如下的寄存器:
关于跳转,还有以下的方式:
| 按键 | 跳转至 |
| --------------- | ---------------------------------------------- |
| `'[` 与 `` `[`` | 上一次修改或复制的第一行或第一个字符 |
| `']` 与 `` `]`` | 上一次修改或复制的最后一行或最后一个字符 |
| `'<` 与 `` `<`` | 上一次在可视模式下选取的第一行或第一个字符 |
| `'>` 与 `` `>`` | 上一次在可视模式下选取的最后一行或最后一个字符 |
| `''` 与 `` `'`` | 上一次跳转之前的光标位置 |
| `'"` 与 `` `"`` | 上一次关闭当前缓冲区时的光标位置 |
| `'^` 与 `` `^`` | 上一次插入字符后的光标位置 |
| `'.` 与 `` `.`` | 上一次修改文本后的光标位置 |
| `'(` 与 `` `(`` | 当前句子的开头 |
| `')` 与 `` `)`` | 当前句子的结尾 |
| `'{` 与 `` `{`` | 当前段落的开头 |
| `'}` 与 `` `}`` | 当前段落的结尾 |
| 按键 | 跳转至 |
| ---------------- | ---------------------------------------------- |
| `'[` 与 `` `[ `` | 上一次修改或复制的第一行或第一个字符 |
| `']` 与 `` `] `` | 上一次修改或复制的最后一行或最后一个字符 |
| `'<` 与 `` `< `` | 上一次在可视模式下选取的第一行或第一个字符 |
| `'>` 与 `` `> `` | 上一次在可视模式下选取的最后一行或最后一个字符 |
| `''` 与 `` `' `` | 上一次跳转之前的光标位置 |
| `'"` 与 `` `" `` | 上一次关闭当前缓冲区时的光标位置 |
| `'^` 与 `` `^ `` | 上一次插入字符后的光标位置 |
| `'.` 与 `` `. `` | 上一次修改文本后的光标位置 |
| `'(` 与 `` `( `` | 当前句子的开头 |
| `')` 与 `` `) `` | 当前句子的结尾 |
| `'{` 与 `` `{ `` | 当前段落的开头 |
| `'}` 与 `` `} `` | 当前段落的结尾 |
标注也可以搭配 [范围](#范围) 一起使用。前面提到过,如果你在可视模式下选取一些文本,然后按下 `:`,这时候你会发现命令行已经被填充了 `:'<,'>`。对照上面的表格,现在你应该明白了,这段代表的就是可视模式下选取的范围。
@ -551,7 +561,7 @@ Vim 在插入模式中为我们提供了多种补全方案。如果有多个补
文本对象操作一般用 `i``a` 加上对象标识符操作,其中 `i` 表示在对象内(英文 inner操作`a` 表示对整个对象(英文 around操作这时开头和结尾的空格都会被考虑进来。举个例子`diw` 可以删除当前单词,`ci(` 可以改变括号中的内容。
文本对象同样可以与数字搭配使用。比如,像 `((( )))` 这样的文本,假如光标位于最内层的括号上或最内层的括号内,那么 `d2a(` 将会删除从最内层开始的两对括号,以及他们之间的所有内容。其实,`d2a(` 这个操作等同于 `2da(`。在 Vim 的命令中,如果有两处都可以接收数字作为参数,那么最终结果就等同于两个数字相乘。在这里,`d``a(` 都是可以接收参数的,一个参数是 1另一个是 2我们可以把它们相乘然后放到最前面。
文本对象同样可以与数字搭配使用。比如,像 `((( )))` 这样的文本,假如光标位于最内层的括号上或最内层的括号内,那么 `d2a(` 将会删除从最内层开始的两对括号,以及他们之间的所有内容。其实,`d2a(` 这个操作等同于 `2da(`。在 Vim 的命令中,如果有两处都可以接收数字作为参数,那么最终结果就等同于两个数字相乘。在这里,`d``a(` 都是可以接收参数的,一个参数是 1另一个是 2我们可以把它们相乘然后放到最前面。
请参阅 `:h text-objects` 来获取更多关于文本对象的帮助。
@ -623,7 +633,7 @@ Vim 中的跳转命令,包括 `'`、`` ` ``、`G`、`/`、`?`、`n`、`N`、`%
Vim 会记录文本改变之前的状态。因此,你可以使用「撤销」操作 <kbd>u</kbd> 来取消更改,也可以通过「重做」操作 <kbd>Ctrl + r</kbd> 来恢复更改。
值得注意的是Vim 采用 [tree](https://en.wikipedia.org/wiki/Tree_(data_structure)) 数据结构来存储内容变更的历史记录,而不是采用 [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type))。你的每次改动都会成为存储为树的节点。而且,除了第一次改动(根节点),之后的每次改动都可以找到一个对应的父节点。每一个节点都会记录改动的内容和时间。其中,「分支」代表从任一节点到根节点的路径。当你进行了撤销操作,然后又输入了新的内容,这时候就相当于创建了分支。这个原理和 git 中的 branch分支十分类似。
值得注意的是Vim 采用 [tree](<https://en.wikipedia.org/wiki/Tree_(data_structure)>) 数据结构来存储内容变更的历史记录,而不是采用 [queue](<https://en.wikipedia.org/wiki/Queue_(abstract_data_type)>)。你的每次改动都会成为存储为树的节点。而且,除了第一次改动(根节点),之后的每次改动都可以找到一个对应的父节点。每一个节点都会记录改动的内容和时间。其中,「分支」代表从任一节点到根节点的路径。当你进行了撤销操作,然后又输入了新的内容,这时候就相当于创建了分支。这个原理和 git 中的 branch分支十分类似。
考虑以下这一系列按键操作:
@ -659,7 +669,7 @@ oquux<exc>
| `[count]g-``:earlier [count]?` | 根据时间回退到 `[count]` 次改动之前。"?" 为 "s"、"m"、"h"、"d" 或 "f"之一。例如,`:earlier 2d` 会回退到两天之前。`:earlier 1f` 则会回退到最近一次文件保存时的内容 |
| `[count]g+``:later [count]?` | 类似 `g-`,但方向相反 |
内容变更记录会储存在内存中,当 Vim 退出时就会清空。如果需要持久化存储内容变更记录,请参阅[备份文件,交换文件,撤销文件以及viminfo文件的处理](#备份文件交换文件撤销文件以及viminfo文件的处理)章节的内容。
内容变更记录会储存在内存中,当 Vim 退出时就会清空。如果需要持久化存储内容变更记录,请参阅[备份文件,交换文件,撤销文件以及 viminfo 文件的处理](#备份文件交换文件撤销文件以及viminfo文件的处理)章节的内容。
如果你觉得这一部分的内容难以理解,请参阅 [undotree](https://github.com/mbbill/undotree),这是一个可视化管理内容变更历史记录的插件。类似的还有 [vim-mundo](https://github.com/simnalamburt/vim-mundo)。
@ -718,7 +728,7 @@ Vim 中,全局位置信息表只能有一个,但每一个窗口都可以有
- 如果你想调用刚才录制的宏,只需要 `[count]@q`
- 如果你想调用上一次使用的宏,只需要 `[count]@@`
**实例1**
**实例 1**
一个插入字符串 "abc" 后换行的宏,重复调用十次:
@ -731,7 +741,7 @@ q
(对于上面这个功能,你同样可以通过如下的按键: <kbd>o</kbd><kbd>a</kbd><kbd>b</kbd><kbd>c</kbd> 然后 <kbd>ESC</kbd> 然后 <kbd>1</kbd><kbd>0</kbd><kbd>.</kbd> 来实现)。
**实例2**
**实例 2**
一个在每行前都加上行号的宏。从第一行开始,行号为 1后面依次递增。我们可以通过 <kbd>Ctrl</kbd> + <kbd>a</kbd> 来实现递增的行号,在定义宏的时候,它会显示成 `^A`
@ -884,7 +894,7 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版
经过一些微小的改动后,重新发布到了这里。
* * *
---
如果你知道你想要找什么,使用帮助系统的搜索会更简单一些,因为搜索出的主题都带有固定的格式。
@ -900,13 +910,13 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版
3. 正则表达式以“/”开头,所以 `:h /\+` 会带你到正则表达式中量词“+”的帮助页面。
4. 组合键经常以一个字母开头表示它们可以在哪些模式中使用。如:`:h i_CTRL-X` 会带你到插入模式下的 CTRL-X 命令的用法帮助页面这是一个自动完成类的组合键。需要注意的是某些键是有固定写法的如Control键写成CTRL。还有查找普通模式下的组合键帮助时可以省略开头的字母“n”`:h CTRL-A`。而 `:h c_CTRL-A`(译者注:原文为 `:h c_CRTL-R`,感觉改为 A 更符合上下文语境)会解释 CTRL-A 在命令模式下输入命令时的作用;`:h v_CTRL-A` 说的是在可见模式下把光标所在处的数字加 1`:h g_CTRL-A` 则说的是 g 命令(你需要先按 "g" 的命令)。这里的 "g" 代表一个普通的命令,这个命令总是与其它的按键组合使用才生效,与 "z" 开始的命令相似。
4. 组合键经常以一个字母开头表示它们可以在哪些模式中使用。如:`:h i_CTRL-X` 会带你到插入模式下的 CTRL-X 命令的用法帮助页面,这是一个自动完成类的组合键。需要注意的是某些键是有固定写法的,如 Control 键写成 CTRL。还有查找普通模式下的组合键帮助时可以省略开头的字母“n”`:h CTRL-A`。而 `:h c_CTRL-A`(译者注:原文为 `:h c_CRTL-R`,感觉改为 A 更符合上下文语境)会解释 CTRL-A 在命令模式下输入命令时的作用;`:h v_CTRL-A` 说的是在可见模式下把光标所在处的数字加 1`:h g_CTRL-A` 则说的是 g 命令(你需要先按 "g" 的命令)。这里的 "g" 代表一个普通的命令,这个命令总是与其它的按键组合使用才生效,与 "z" 开始的命令相似。
5. 寄存器是以 "quote" 开头的。如:`:h quote:` (译者注:原文为`:h quote`,感觉作者想以":"来举例)来查看关于":"寄存器的说明。
6. 关于 Vim 脚本VimL的帮助都在 `:h eval.txt` 里。而某些方面的语言可以使用 `:h expr-X` 获取帮助,其中的 'X' 是一个特定的字符,如:`:h expr-!` 会跳转到描述 VimL 中'!'(非)的章节。另外一个重要提示,可以使用 `:h function-list` 来查看所有函数的简要描述,列表中包括函数名和一句话描述。
7. 关于映射都可以在 `:h map.txt` 中找到。通过 `:h mapmode-i` 来查找 `:imap` 命令的相关信息;通过 `:h map-topic` 来查找专门针对映射的帮助译者注topic 为一个占位符,正如上面的字符 'X' 一样,在实际使用中需要替换成相应的单词)(如:`:h :map-local` 查询本地buffer的映射`:h map-bar` 查询如何在映射中处理'|')。
7. 关于映射都可以在 `:h map.txt` 中找到。通过 `:h mapmode-i` 来查找 `:imap` 命令的相关信息;通过 `:h map-topic` 来查找专门针对映射的帮助译者注topic 为一个占位符,正如上面的字符 'X' 一样,在实际使用中需要替换成相应的单词)(如:`:h :map-local` 查询本地 buffer 的映射,`:h map-bar` 查询如何在映射中处理'|')。
8. 命令定义用 "command-" 开头,如用 `:h command-bar` 来查看自定义命令中'!'的作用。
@ -920,7 +930,7 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版
13. `:h helphelp` 里介绍了如何使用帮助系统。
14. 用户手册。它采用了一种对初学者更加友好的方式来展示帮助话题。用 `:h usr_toc.txt` 打开目录你可能已经猜到这个命令的用处了。浏览用户手册能帮助你找出某些你想了解的话题如你可以在第24章看到关于“复合字符”以及“输入特殊字符”的讲解`:h usr_24.txt` 可以快速打开相关章节)。
14. 用户手册。它采用了一种对初学者更加友好的方式来展示帮助话题。用 `:h usr_toc.txt` 打开目录(你可能已经猜到这个命令的用处了)。浏览用户手册能帮助你找出某些你想了解的话题,如你可以在第 24 章看到关于“复合字符”以及“输入特殊字符”的讲解(用 `:h usr_24.txt` 可以快速打开相关章节)。
15. 高亮分组的帮助以 `hl-` 开头。如:`:h hl-WarningMsg` 说的是警告信息分组的高亮。
@ -936,7 +946,7 @@ Vim 自带了一套很完善的帮助文档,它们是一个个有固定排版
21. 错误代码可以在帮助系统中直接查到。`:h E297` 会带你到关于这一错误的详细解释。但是有时并没有转到错误描述,而是列出了经常导出这一错误的 Vim 命令,如 `:h E128` (译者注:原文为`:h hE128`,但是并没有该帮助)会直接跳转到 `:function` 命令。
22. 关于包含的语法文件的文档的帮助话题格式是 `:h ft-*-syntax`。如:`:h ft-c-syntax` 说的就是C语言语法文件以及它所提供的选项。有的语法文件还会带有自动完成`:h ft-php-omni`)或文件类型插件(`:h ft-tex-plugin`)相关的章节可以查看。
22. 关于包含的语法文件的文档的帮助话题格式是 `:h ft-*-syntax`。如:`:h ft-c-syntax` 说的就是 C 语言语法文件以及它所提供的选项。有的语法文件还会带有自动完成(`:h ft-php-omni`)或文件类型插件(`:h ft-tex-plugin`)相关的章节可以查看。
另外在每个帮助页的顶端通常会包含一个用户文档链接(更多的从从用户的角度出发来主角命令的功能和用法,不涉及那么多细节)。如:`:h pattern.txt` 里包含了 `:h 03.9``:h usr_27` 两个章节的链接。
@ -962,7 +972,7 @@ function! Chibby()
endfunction
```
现在你插件的用户可以在Chibby执行完成之后做任何他想做的事情
现在你插件的用户可以在 Chibby 执行完成之后做任何他想做的事情:
```vim
autocmd User ChibbyExit call ChibbyCleanup()
@ -1002,7 +1012,7 @@ autocmd VimEnter * nested edit $MYVIMRC
## 剪切板
如果你想在没有GUI支持的Unix系统中使用 Vim 的 `'clipboard'` 选项,则需要 `+clipboard` 以及可选的 `+xterm_clipboard` 两个[特性](#what-kind-of-vim-am-i-running)支持。
如果你想在没有 GUI 支持的 Unix 系统中使用 Vim 的 `'clipboard'` 选项,则需要 `+clipboard` 以及可选的 `+xterm_clipboard` 两个[特性](#what-kind-of-vim-am-i-running)支持。
帮助文档:
@ -1016,7 +1026,7 @@ autocmd VimEnter * nested edit $MYVIMRC
### 剪贴板的使用Windows, OSX
Windows 自带了[剪贴板](https://msdn.microsoft.com/en-us/library/windows/desktop/ms649012(v=vs.85).aspx)OSX 则带了一个[粘贴板](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/PasteboardGuide106/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008100-SW1)
Windows 自带了[剪贴板](<https://msdn.microsoft.com/en-us/library/windows/desktop/ms649012(v=vs.85).aspx>)OSX 则带了一个[粘贴板](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/PasteboardGuide106/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008100-SW1)
在这两个系统中都可以用大家习惯用的 `ctrl+c / cmd+c` 复制选择的文本,然后在另外一个应用中用 `ctrl+v / cmd+v` 进行粘贴。
@ -1051,7 +1061,7 @@ set guioptions+=a
### 剪贴板的使用Linux, BSD, ...
如果你的系统使用了 [X 图形界面](http://www.x.org/wiki)事情会变得有一点不同。X 图形界面实现了 [X 窗口系统协议](http://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html), 这个协议在1987年发布的主版本11因此 X 也通常被称为 X11。
如果你的系统使用了 [X 图形界面](http://www.x.org/wiki)事情会变得有一点不同。X 图形界面实现了 [X 窗口系统协议](http://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html), 这个协议在 1987 年发布的主版本 11因此 X 也通常被称为 X11。
在 X10 版本中,[剪贴缓冲区](http://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.html#Peer_to_Peer_Communication_by_Means_of_Cut_Buffers)被用来实现像 _clipboard_ 一样由 X 来复制文本,并且可以被所有的程序访问。现在这个机制在 X 中还存在,但是已经过时了,很多程序都不再使用这一机制。
@ -1086,7 +1096,7 @@ set clipboard^=unnamedplus " + 寄存器
`^=` 用来将设置的值加到默认值之前,详见:`:h :set^=`
这会使得所有复制/删除/放入操作使用 `*``+` 寄存器代替默认的未命令寄存器 `"`。之后你就可以直接使用 `y``p` 访问你的X选择了。
这会使得所有复制/删除/放入操作使用 `*``+` 寄存器代替默认的未命令寄存器 `"`。之后你就可以直接使用 `y``p` 访问你的 X 选择了。
帮助文档:
@ -1108,13 +1118,13 @@ autocmd BufReadPost *
\ endif
```
这是通过判断之前的光标位置是否存在(文件可能被其它程序修改而导致所记录的位置已经不存在了),如果存在的话就执行 ``g`"`` (转到你离开时的光标位置但是不更改跳转列表)。
这是通过判断之前的光标位置是否存在(文件可能被其它程序修改而导致所记录的位置已经不存在了),如果存在的话就执行 `` g`" `` (转到你离开时的光标位置但是不更改跳转列表)。
这需要使用 viminfo 文件:`:h viminfo-`
## 临时文件
根据选项的不同, Vim 最多会创建4种工作文件。
根据选项的不同, Vim 最多会创建 4 种工作文件。
### 备份文件
@ -1181,7 +1191,7 @@ set undodir =$HOME/.vim/files/undo/
set viminfo ='100,n$HOME/.vim/files/info/viminfo
```
注意:如果你在一个多用户系统中编辑某个文件时, Vim 提示你交换文件已经存在的话可能是因为有其他的用户此时正在编辑这个文件。而如果将交换文件放到自己的home目录的话这个功能就失效了。因此服务器非常不建议将这些文件修改到HOME目录避免多人同时编辑一个文件却没有任何警告。
注意:如果你在一个多用户系统中编辑某个文件时, Vim 提示你交换文件已经存在的话,可能是因为有其他的用户此时正在编辑这个文件。而如果将交换文件放到自己的 home 目录的话,这个功能就失效了。因此服务器非常不建议将这些文件修改到 HOME 目录,避免多人同时编辑一个文件,却没有任何警告。
## 编辑远程文件
@ -1249,23 +1259,23 @@ set virtualedit=all
## 使用外部程序和过滤器
免责声明Vim 是单线程的,因此在 Vim 中以前端进程执行其它的程序时会阻止其它的一切。当然你可以使用 Vim 程序接口如Lua并且使用它的多线程支持但是在那期间 Vim 的处理还是被阻止了。Neovim 添加了任务 API 解决了此问题。
免责声明Vim 是单线程的,因此在 Vim 中以前端进程执行其它的程序时会阻止其它的一切。当然你可以使用 Vim 程序接口,如 Lua并且使用它的多线程支持但是在那期间 Vim 的处理还是被阻止了。Neovim 添加了任务 API 解决了此问题。
(据说 Bram 正在考虑在 Vim 中也添加任务控制。如果你使用了较新版本的的 Vim ,可以看一下 `:helpgrep startjob`。)
使用 `:!` 启动一个新任务。如果你想列出当前工作目录下的所有文件,可以使用 `:!ls`。 用 `|` 来将结果通过管道重定向,如:`:!ls -l | sort | tail -n5`
没有使用范围时(译者注:范围就是 `:``!` 之间的内容,`.` 表示当前行,`+4` 表示向下偏移4行`$` 表示最末行等,多行时用 `,` 将它们分开,如 `.,$` 表示从当前行到末行),`:!` 会显示在一个可滚动的窗口中(译者注:在 GVim 和在终端里运行的结果稍有不同)。相反的,如果指定了范围,这些行会被[过滤](https://en.wikipedia.org/wiki/Filter_(software))。这意味着它们会通过管道被重定向到过滤程序的 [stdin](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29),在处理后再通过过滤程序的 [stdout](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_.28stdout.29) 输出用输出结果替换范围内的文本。例如为接下来的5行文本添加行号可以使用
没有使用范围时(译者注:范围就是 `:``!` 之间的内容,`.` 表示当前行,`+4` 表示向下偏移 4 行,`$` 表示最末行等,多行时用 `,` 将它们分开,如 `.,$` 表示从当前行到末行),`:!` 会显示在一个可滚动的窗口中(译者注:在 GVim 和在终端里运行的结果稍有不同)。相反的,如果指定了范围,这些行会被[过滤](<https://en.wikipedia.org/wiki/Filter_(software)>)。这意味着它们会通过管道被重定向到过滤程序的 [stdin](https://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29),在处理后再通过过滤程序的 [stdout](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_.28stdout.29) 输出,用输出结果替换范围内的文本。例如:为接下来的 5 行文本添加行号,可以使用:
```vim
:.,+4!nl -ba -w1 -s' '
```
由于手动添加范围很麻烦, Vim 提供了一些辅助方法以方便的添加范围。如果需要经常带着范围的话,你可以在可见模式中先选择,然后再按 `:` (译者注:选中后再按 `!` 更方便)。还可以使用 `!` 来取用一个motion的范围`!ipsort` (译者注:原文为 `!ip!sort` ,但经过实验发现该命令执行报错,可能是因为 Vim 版本的原因造成的,新版本使用 `ip` 选择当前段落后自动在命令后添加了 `!` ,按照作者的写法来看,可能之前的版本没有自动添加 `!` )可以将当前段落的所有行按字母表顺序进行排序。
由于手动添加范围很麻烦, Vim 提供了一些辅助方法以方便的添加范围。如果需要经常带着范围的话,你可以在可见模式中先选择,然后再按 `:` (译者注:选中后再按 `!` 更方便)。还可以使用 `!` 来取用一个 motion 的范围,如 `!ipsort` (译者注:原文为 `!ip!sort` ,但经过实验发现该命令执行报错,可能是因为 Vim 版本的原因造成的,新版本使用 `ip` 选择当前段落后自动在命令后添加了 `!` ,按照作者的写法来看,可能之前的版本没有自动添加 `!` )可以将当前段落的所有行按字母表顺序进行排序。
一个使用过滤器比较好的案例是[Go语言](https://golang.org/)。它的缩进语法非常个性,甚至还专门提供了一个名为 `gofmt` 的过滤器来对Go语言的源文件进行正确的缩进。Go语言的插件通常会提供一个名为 `:Fmt` 的函数,这个函数就是执行了 `:%!gofmt` 来对整个文件进行缩进。
一个使用过滤器比较好的案例是[Go 语言](https://golang.org/)。它的缩进语法非常个性,甚至还专门提供了一个名为 `gofmt` 的过滤器来对 Go 语言的源文件进行正确的缩进。Go 语言的插件通常会提供一个名为 `:Fmt` 的函数,这个函数就是执行了 `:%!gofmt` 来对整个文件进行缩进。
人们常用 `:r !prog` 将prog程序的插入放到当前行的下面这对于脚本来说是很不错的选择但是在使用的过程中我发现 `!!ls` 更加方便,它会用输出结果替换当前行的内容。(译者注:前面命令中的 `prog` 只是个占位符,在实际使用中需要替换成其它的程序,如 `:r !ls`,这就与后面的 `!!ls` 相对应了,两者唯一的不同是第一个命令不会覆盖当前行内容,但是第二个命令会)
人们常用 `:r !prog` prog 程序的插入放到当前行的下面,这对于脚本来说是很不错的选择,但是在使用的过程中我发现 `!!ls` 更加方便,它会用输出结果替换当前行的内容。(译者注:前面命令中的 `prog` 只是个占位符,在实际使用中需要替换成其它的程序,如 `:r !ls`,这就与后面的 `!!ls` 相对应了,两者唯一的不同是第一个命令不会覆盖当前行内容,但是第二个命令会)
帮助文档:
@ -1276,9 +1286,9 @@ set virtualedit=all
## Cscope
[Cscope](http://cscope.sourceforge.net/) 的功能比 [ctags](http://ctags.sourceforge.net/) 要完善但是只支持C通过设置cscope.files后同样支持C++以及Java
[Cscope](http://cscope.sourceforge.net/) 的功能比 [ctags](http://ctags.sourceforge.net/) 要完善,但是只支持 C通过设置 cscope.files 后同样支持 C++以及 Java
鉴于Tag文件只是知道某个符号是在哪里定义的cscope的数据库里的数据信息就多的多了
鉴于 Tag 文件只是知道某个符号是在哪里定义的cscope 的数据库里的数据信息就多的多了:
- 符号是在哪里定义的?
- 符号是在哪里被使用的?
@ -1301,7 +1311,7 @@ $ cscope -bqR
这条命令会在当前目录下创建三个文件:`cscope{,.in,.po}.out` 。把它们想象成你的数据库。
不幸的时 `cscope` 默认只分析 `*.[c|h|y|l]` 文件。如果你想在Java项目中使用 cscope ,需要这样做:
不幸的时 `cscope` 默认只分析 `*.[c|h|y|l]` 文件。如果你想在 Java 项目中使用 cscope ,需要这样做:
```sh
$ find . -name "*.java" > cscope.files
@ -1364,7 +1374,7 @@ nnoremap <buffer> <leader>cd :cscope find d <c-r>=expand('<cword>')<cr><cr>
由于 Vim 是用 C 语言编写的,因此许多功能都假设使用类似 C 语言的语法。默认情况下,如果你的光标在 `{``#endif` , 就可以使用 `%` 跳转到与之匹配的 `}``#ifdef`
Vim 自带了一个名为 matchit.vim 的插件,但是默认没有启用。启用后可以用 `%` 在HTML相匹配的标签或 VimL 的 if/else/endif 块之间进行跳转,它还带来了一些新的命令。
Vim 自带了一个名为 matchit.vim 的插件,但是默认没有启用。启用后可以用 `%` HTML 相匹配的标签或 VimL 的 if/else/endif 块之间进行跳转,它还带来了一些新的命令。
### 在 Vim 8 中安装
@ -1380,7 +1390,7 @@ packadd! matchit
runtime macros/matchit.vim
```
由于matchit的文档很全面我建议安装以后执行一次下面的命令
由于 matchit 的文档很全面,我建议安装以后执行一次下面的命令:
```vim
:!mkdir -p ~/.vim/doc
@ -1659,9 +1669,9 @@ autocmd ColorScheme lucius highlight StatusLine ctermbg=darkgray cterm=NONE guib
vim -u NONE -N
这样会在不引用vimrc默认设置的情况下重启vim并且在 **nocompatible** 模式下使用vim默认设置而不是vi的搜索 `:h --noplugin` 命令了解更多启动加载方式)
这样会在不引用 vimrc默认设置的情况下重启 vim并且在 **nocompatible** 模式下(使用 vim 默认设置而不是 vi 的)。(搜索 `:h --noplugin` 命令了解更多启动加载方式)
如果仍旧能够出现该错误那么这极有可能是vim本身的bug请给 [vim_dev]("https://groups.google.com/forum/#!forum/vim_dev") 发送邮件反馈错误,多数情况下问题不会立刻解决,你还需要进一步研究
如果仍旧能够出现该错误,那么这极有可能是 vim 本身的 bug请给 [vim_dev]("https://groups.google.com/forum/#!forum/vim_dev") 发送邮件反馈错误,多数情况下问题不会立刻解决,你还需要进一步研究
许多插件经常会提供新的(默认的/自动的)操作。如果在保存的时候发生了,那么请用 `:verb au BufWritePost` 命令检查潜在的问题
@ -1671,11 +1681,11 @@ autocmd ColorScheme lucius highlight StatusLine ctermbg=darkgray cterm=NONE guib
到了一行行代码检查的时候了,不断地排除缩小检查范围知道你找出错误,根据二分法的原理你不会花费太多时间的。
在实践过程中,可能就是这样,把 `:finish` 放在你的 **vimrc** 文件中间Vim会跳过它之后的设置。如果问题还在那么问题就出在`:finish`之前的设置中,再把`:finish`放到前一部分设置的中间位置。否则问题就出现在它后面的半部分设置,那么就把`:finish`放到后半部分的中间位置。不断的重复即可找到。
在实践过程中,可能就是这样,把 `:finish` 放在你的 **vimrc** 文件中间Vim 会跳过它之后的设置。如果问题还在,那么问题就出在`:finish`之前的设置中,再把`:finish`放到前一部分设置的中间位置。否则问题就出现在它后面的半部分设置,那么就把`:finish`放到后半部分的中间位置。不断的重复即可找到。
## 调整日志等级
Vim现在正在使用的另一个比较有用的方法是增加debug信息输出详细等级。现在Vim支持9个等级可以用`:h 'verbose'`命令查看。
Vim 现在正在使用的另一个比较有用的方法是增加 debug 信息输出详细等级。现在 Vim 支持 9 个等级,可以用`:h 'verbose'`命令查看。
```vim
:e /tmp/foo
@ -1686,7 +1696,7 @@ Vim现在正在使用的另一个比较有用的方法是增加debug信息输出
这可以显示出所有引用的文件、没有变化的文件或者各种各样的作用于保存的插件。
如果你只是想用简单的命令来提高等级,也是用 `:verbose` 放在其他命令之前通过计数来指明等级默认是1.
如果你只是想用简单的命令来提高等级,也是用 `:verbose` ,放在其他命令之前,通过计数来指明等级,默认是 1.
```vim
:verb set verbose
@ -1695,7 +1705,7 @@ Vim现在正在使用的另一个比较有用的方法是增加debug信息输出
" verbose=10
```
通常用等级1来显示上次从哪里设置的选项
通常用等级 1 来显示上次从哪里设置的选项
```vim
:verb set ai?
@ -1708,21 +1718,21 @@ Vim现在正在使用的另一个比较有用的方法是增加debug信息输出
:set verbosefile=/tmp/foo | 15verbose echo "foo" | vsplit /tmp/foo
```
你可以一开始的时候就打开verbosity`-V` 选项它默认设置调试等级为10。 例如:`vim -V5`
你可以一开始的时候就打开 verbosity`-V` 选项,它默认设置调试等级为 10。 例如:`vim -V5`
## 查看启动日志
## 查看运行时日志
## Vim脚本调试
## Vim 脚本调试
如果你以前使用过命令行调试器的话,对于`:debug`命令你很快就会感到熟悉。
只需要在任何其他命令之前加上`:debug`就会让你进入调试模式。也就是被调试的Vim脚本会在第一行停止运行同时该行会被显示出来。
只需要在任何其他命令之前加上`:debug`就会让你进入调试模式。也就是,被调试的 Vim 脚本会在第一行停止运行,同时该行会被显示出来。
想了解可用的6个调试命令可以查阅`:h >cont`和阅读下面内容。需要指出的是类似gdb和其他相似调试器调试命令可以使用它们的简短形式`c``q``n``s``i``f`
想了解可用的 6 个调试命令,可以查阅`:h >cont`和阅读下面内容。需要指出的是,类似 gdb 和其他相似调试器,调试命令可以使用它们的简短形式:`c``q``n``s``i``f`
除了上面的之外你还可以自由地使用任何Vim的命令。比如`:echo myvar`,该命令会在当前的脚本代码位置和上下文上被执行。
除了上面的之外,你还可以自由地使用任何 Vim 的命令。比如,`:echo myvar`,该命令会在当前的脚本代码位置和上下文上被执行。
只需要简单使用`:debug 1`,你就获得了[REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)调试特性。
@ -1754,10 +1764,9 @@ Vim现在正在使用的另一个比较有用的方法是增加debug信息输出
`:debug`命令可以和[verbose](#verbosity)选项一起使用。
## 语法文件调试
语法文件由于包含错误的或者复制的正则表达式常常会使得Vim的运行较慢。如果Vim在编译的时候包含了`+profile` [feature](#what-kind-of-vim-am-i-running)特性,就可以给用户提供一个超级好用的`:syntime`命令。
语法文件由于包含错误的或者复制的正则表达式,常常会使得 Vim 的运行较慢。如果 Vim 在编译的时候包含了`+profile` [feature](#what-kind-of-vim-am-i-running)特性,就可以给用户提供一个超级好用的`:syntime`命令。
```vim
:syntime on
@ -1765,12 +1774,11 @@ Vim现在正在使用的另一个比较有用的方法是增加debug信息输出
:syntime off
:syntime report
```
输出结果包含了很多的度量维度。比如,你可以通过结果知道哪些正则表达式耗时太久需要被优化;哪些正则表达式一直在别使用但重来没有一次成功匹配。
请查阅`:h :syntime`
# 杂项
## 附加资源
@ -1778,11 +1786,11 @@ Vim现在正在使用的另一个比较有用的方法是增加debug信息输出
| 资源名称 | 简介 |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| [七个高效的文本编辑习惯](http://www.moolenaar.net/habits.html) | 作者Bram Moolenaar即 Vim 的作者) |
| [七个高效的文本编辑习惯2.0PDF版](http://www.moolenaar.net/habits_2007.pdf) | 同上 |
| [七个高效的文本编辑习惯 2.0PDF 版)](http://www.moolenaar.net/habits_2007.pdf) | 同上 |
| [IBM DeveloperWorks: 使用脚本编写 Vim 编辑器](http://www.ibm.com/developerworks/views/linux/libraryview.jsp?sort_order=asc&sort_by=Title&search_by=scripting+the+vim+editor) | Vim 脚本编写五辑 |
| [《漫漫 Vim 路》](http://learnvimscriptthehardway.stevelosh.com) | 使用魔抓定制 Vim 插件 |
| [《 Vim 实践 (第2版)》](http://www.amazon.com/Practical-Vim-Edit-Speed-Thought/dp/1680501275/) | 轻取 Vim 最佳书籍 |
| [Vimcasts.org](http://vimcasts.org/episodes/archive) | Vim录屏演示 |
| [《 Vim 实践 (第 2 版)》](http://www.amazon.com/Practical-Vim-Edit-Speed-Thought/dp/1680501275/) | 轻取 Vim 最佳书籍 |
| [Vimcasts.org](http://vimcasts.org/episodes/archive) | Vim 录屏演示 |
| [为什么是个脚本都用 vi](http://www.viemu.com/a-why-vi-vim.html) | 常见误区释疑 |
| [你不爱 vi所以你不懂 Vim ](http://stackoverflow.com/a/1220118) | 简明,扼要,准确的干货 |
@ -1843,7 +1851,10 @@ $ vim -n -u NONE -i NONE -N
你有没有遇到过往 Vim 里粘贴代码之后被搞的一团糟?
这在你使用 `cmd+v``shirt-insert``middle-click` 等进行粘贴的时候才会发生。因为那样的话你只是向终端模拟器扔了一大堆的文本。 Vim 并不知道你刚刚是粘贴的文本,它以为你在飞速的输入。于是它想缩进这些行但是失败了。
这在你使用 `cmd+v``shirt-insert``middle-click` 等进行粘贴的时候才会发生。
因为那样的话你只是向终端模拟器扔了一大堆的文本。
Vim 并不知道你刚刚是粘贴的文本,它以为你在飞速的输入。
于是它想缩进这些行但是失败了。
这明显不是个问题,如果你用 Vim 的寄存器粘贴,如:`"+p` ,这时 Vim 就知道了你在粘贴,就不会导致格式错乱了。
@ -1868,7 +1879,7 @@ Neovim 尝试把这些变得更顺畅,如果终端支持的话,它会自动
:nnoremap ,ab :echo 'bar'<cr>
```
上面的例子中两个映射都能正常工作,但是当输入 `,a` 之后Vim 会延时1秒因为它要确认用户是否还要输入那个 `b`
上面的例子中两个映射都能正常工作,但是当输入 `,a` 之后Vim 会延时 1 秒,因为它要确认用户是否还要输入那个 `b`
转义序列会产生同样的问题: