From 44aa8aed1b568395d58dc19dfde96256cfda51fb Mon Sep 17 00:00:00 2001 From: S1ngS1ng Date: Fri, 24 Mar 2017 03:25:43 -0500 Subject: [PATCH] WIP ##Ranges --- README.md | 166 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 93 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index fe0346f..f4f2827 100644 --- a/README.md +++ b/README.md @@ -332,88 +332,108 @@ Vim 是一个文本编辑器。每次文本都是作为**缓冲区**的一部分 :h 05.3 ## 快捷键前缀 -## 范围 +"Leader" 键是一个触发器,默认为 `\\`。我们可以通过在 `map` 中调用 `` 来为 `` 键设置映射 + +```vim +nnoremap h :helpgrep +``` + +这样,我们只需要先按 \\ 然后按 h 就可以执行 `:helpgrep` 了。如果你想通过先按 空格 键来触发,只需要这样做: + +```vim +let mapleader = ' ' +nnoremap h :helpgrep +``` + +另外,还有一个叫 `` 的,可以把它理解为局部环境中的 ``,默认值依然为 \\。当我们需要只对某一个条件下(比如,特定文件类型的插件)的缓冲区设置特别的 `` 键,那么我们就可以通过修改当前环境下的 `` 来实现 + +**注意**:如果你打算设置 Leader 键,请确保在设置按键映射之前,先设置好 Leader 键。如果你先设置了含有 Leader 键的映射,然后又修改了 Leader 键,那么之前映射的 Leader 键是不会因此而改变的。你可以通过执行 `:nmap ` 来查看普通模式中已绑定给 Leader 键的所有映射 + +请参阅 `:h mapleader` 与 `:h maploacalleader` 来获取更多帮助 + ## 寄存器 -## 标注 -## 补全 -## 动作,操作符,文本对象 -## 自动命令 -## 变更历史,跳转历史 -## 内容变更历史记录 -## 全局位置信息表,局部位置信息表 -## 宏 -## 颜色主题 -## 折叠 -## 会话 -## 局部化 -# 用法 -## 获取离线帮助 -## 获取离线帮助(备选) -## 获取在线帮助 -## 执行自动命令 -### 用户自定义事件 -### 内部自带事件 -## 剪贴板 -## 剪贴板使用 (Windows, OSX) -## 剪贴板使用 (Linux, BSD, ...) -## 打开文件时恢复光标位置 -## 备份文件,交换文件,撤销文件以及 viminfo 文件的处理 -## 编辑远程文件 -## 插件管理 -## 片段插入 -## 使用外部程序和过滤器 -## MatchIt -# 技巧 +寄存器就是存储文本的地方。我们常用的"复制"操作就是把文本存储到寄存器,"粘贴"操作就是把文本从寄存器中读出来。顺便,在 Vim 中复制的快捷键是 y,粘贴的快捷键是 p -## 聪明的使用 n 和 N -## 聪明的使用命令行历史 -## 智能 Ctrl-l -## 禁用错误报警声音和图标 -## 快速移动当前行 -## 快速添加空行 -## 快速编辑自定义宏 -## 快速跳转到源(头)文件 -## 在 GUI 中快速改变字体大小 -## 根据模式改变光标类型 -## 防止水平滑动的时候失去选择 -## 重新载入保存文件 -## 智能当前行 -## 更快的关键字补全 -# 命令 +Vim 为我们提供了如下的寄存器: +| 类型 | 字符 | 读写者 | 是否为只读 | 包含的字符来源 | +|---------------------|------------------------|------------|-------------|---------------------| +| Unnamed | `"` | vim | [ ] | 最近一次的复制或删除操作 (`d`, `c`, `s`, `x`, `y`) | +| Numbered | `0` to `9` | vim | [ ] | 寄存器 `0`: 最近一次复制。寄存器 `1`: 最近一次删除。寄存器 `2`: 倒数第二次删除,以此类推。对于寄存器 `1` 至 `9`,他们其实是只读的最多包含 9 个元素的队列。这里的队列即为数据类型 [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) | +| Small delete | `-` | vim | [ ] | 最近一次,内容在一行以内的删除 | +| Named | `a` to `z`, `A` to `Z` | user | [ ] | 如果你通过复制操作存储文本至寄存器 `a`,那么 `a` 中的文本就会被完全覆盖。如果你存储至 `A`,那么会将文本添加给寄存器 `a`,不会覆盖之前已有的文本 | +| Read-only | `:`, `.`, `%` | vim | [x] | `:`: 最近一次使用的命令,`.`: 最近一次添加的文本,`%`: 当前的文件名 | +| Alternate buffer | `#` | vim | [ ] | 大部分情况下,这个寄存器是当前窗口中,上一次访问的缓冲区。请参阅 `:h alternate-file` 来获取更多帮助 | +| Expression | `=` | user | [ ] | 复制 VimL 代码时,这个寄存器用于存储代码片段的执行结果。比如,在插入模式下复制 `=5+5`,那么这个寄存器就会存入 10 | +| Selection | `+`, `*` | vim | [ ] | `*` 和 `+` 是 [剪贴板](#剪贴板) 寄存器 | +| Drop | `~` | vim | [x] | 存储最近一次添加进 Vim 中的文本 | +| Black hole | `_` | vim | [ ] | 对于当前操作,如果你不希望在其他寄存器中保留文本,那就在命令前加上 `_`。比如,`"_dd` 命令不会将文本放到寄存器 `"`、`1`、`+` 或 `*` 中 | +| Last search pattern | `/` | vim | [ ] | 最近一次通过 `/`、`?` 或 `:global` 等命令调用的正则表达式 | -## :global - 在所有匹配行执行命令 -## :normal and :execute - 脚本梦之队 -## :redir - 重定向消息 -# 调试 +只要不是只读的寄存器,用户都有权限修改它的内容,比如: -## 常规建议 -## 查看启动日志 -## 查看运行时日志 -## 调整日志等级 -## vim 脚本调试 -## 语法文件调试 -# 杂项 +```vim +:let @/ = 'register' +``` -## 附加资源 -## Vim 配置集合 -## 内置插件 -## 将 Control 映射到 CapsLock -## 复活节彩蛋 -## 为何使用 hjkl -# 怪癖 +这样,我们按 n 的时候就会跳转到单词 "register" 出现的地方 -## 编辑小文件很慢 -## 编辑大文件很慢 -## 新行用于 NUL -## 相同部分粘贴 (要不为什么我总要设置‘粘贴’?) -## 在终端使用 Esc 延时 -## 无法重复函数中执行的搜索 -## 主题列表 +有些时候,你的操作可能已经修改了寄存器,而你没有察觉到。请参考 `:h registers` 获取更多帮助 -# 插件列表 +上面提到过,复制的命令是 y,粘贴的命令是 p 或者 P。但请注意,Vim 会区分"字符选取"与"行选取"。请参考 `:h linewise` 获取更多帮助 + +**行选取**: +命令 `yy` 或 `Y` 都是复制当前行。这时移动光标至其他位置,按下 `p` 就可以在光标下方粘贴复制的行,按下 `P` 就可以在光标上方粘贴至复制的行 + +**字符选取**: +命令 `0yw` 可以复制第一个单词。这时移动光标至其他位置,按下 `p` 就可以在当前行、光标后的位置粘贴单词,按下 `P` 就可以在当前行、光标前的位置粘贴单词 + +**将文本存到指定的寄存器中**: +命令 `"aY` 可以将当前行复制,并存储到寄存器 `a` 中。这时移动光标至其他位置,通过命令 `"AY` 就可以把这一行的内容扩展到寄存器 `a` 中,而之前存储的内容也不会丢失 + +为了便于理解和记忆,建议大家现在就试一试上面提到的这些操作。操作过程中,你可以随时通过 `:reg` 来查看寄存器的变化 + +**有趣的是**: +在 Vim 中,`y` 是复制命令,源于单词 "yanking"。而在 Emacs 中,"yanking" 代表的是粘贴(或者说,重新插入刚才删掉的内容),而并不是复制 + +## 范围 +范围 (Ranges) 其实很好理解,但很多 Vim 用户的理解不到位 + +- 很多命令都可以加一个数字,用于指明操作范围 +- 可以是一个 "地址",用于指定某一行 +- 可以是一个 "地址" 或者一对通过 `,` 或 `;` 分割的一对 "地址" +- 大部分命令,默认只作用于当前行 +- 只有 `:white` 和 `:global` 是默认作用于所有行的 + +范围的使用是十分直观的。以下为一些例子(其中,`:d` 为 `:delete` 的缩写: + +| 命令 | 操作的行 | +|---------|----------------| +| `:d` | 当前行 | +| `:.d` | 当前行 | +| `:1d` | 第一行 | +| `:$d` | 最后一行 | +| `:1,$d` | 所有行 | +| `:%d` | 所有行(这是 `1,$` 的语法糖) | +| `:.,5d` | 当前行至第 5 行 | +| `:,5d` | 当前行至第 5 行 | +| `:,+3d` | 当前行及接下来的 3 行 | +| `:1,+3d` | 第一行至当前行再加 3 行 | +| `:,-3d` | 当前行及向上的 3 行(Vim 会弹出提示信息,因为这是一个保留的范围) | +| `:3,'xdelete` | 第三行至[标记](#标记) 为 x 的那一行 | +| `:/^foo/,$delete` | 当前行以下,以字符 "foo" 开头的那一行至结尾 | +| `:/^foo/+1,$delete` | 当前行以下,以字符 "foo" 开头的那一行的下一行至结尾 | + +需要注意的是,`;` 也可以用于表示范围。区别在于,`a,b` 的 `b` 是以当前行作为参考的。而 `a;b` 的 `b` 是以 `a` 行作为参考的。举个例子,现在你的光标在第 5 行。这时 `:1,+1d` 会删除第 1 行至第 6 行,而 `:1;+1d` 会删除第 1 行和第 2 行 + +你可以在通过在地址前加上 `/` 来设置多个地址,比如: + +```vim +:/foo//bar//quux/d +``` + +这就会删除当前行之后的某一行。定位方式是,现在当前行之后寻找第一个包含 "foo" 字符的那一行,然后在找到的这一行之后寻找第一个包含 "bar" 字符的那一行,然后再在找到的这一行之后寻找第一个包含 "quux" 的那一行。删除的就是最后找到的这一行 -# Neovim ## 加入我们