mirror of
https://gitlab.com/wsdjeg/vim-galore-zh_cn.git
synced 2025-01-31 13:39:29 +08:00
Done through ## Locality
This commit is contained in:
parent
ec241322d1
commit
a274146c56
228
README.md
228
README.md
@ -599,8 +599,234 @@ Vim 中的跳转命令,包括 `'`、`` ` ``、`G`、`/`、`?`、`n`、`N`、`%
|
||||
:h jumplist
|
||||
```
|
||||
|
||||
## 加入我们
|
||||
## 内容变更历史记录
|
||||
|
||||
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))。你的每次改动都会成为存储为树的节点。而且,除了第一次改动(根节点),之后的每次改动都可以找到一个对应的父节点。每一个节点都会记录改动的内容和时间。其中,"分支" 代表从任一节点到根节点的路径。当你进行了撤销操作,然后又输入了新的内容,这时候就相当于创建了分支。
|
||||
|
||||
考虑以下这一系列按键操作:
|
||||
|
||||
```vim
|
||||
ifoo<esc>
|
||||
obar<esc>
|
||||
obaz<esc>
|
||||
u
|
||||
oquux<exc>
|
||||
```
|
||||
|
||||
那么现在,Vim 中会显示三行文本,分别是 "foo"、"bar" 和 "quux"。这时候,存储的树形结构如下:
|
||||
|
||||
```
|
||||
foo(1)
|
||||
/
|
||||
bar(2)
|
||||
/ \
|
||||
baz(3) quux(4)
|
||||
```
|
||||
|
||||
这个树形结构共包含四次改动,括号中的数字就代表时间顺序。
|
||||
|
||||
现在,我们有两种方式遍历这个树结构。一种叫"按分支遍历",一种叫"按时间遍历"。
|
||||
|
||||
撤销 <kbd>u</kbd> 与重做 <kbd>Ctrl + r</kbd> 操作是按分支遍历。对于上面的例子,现在我们有三行字符。这时候按 <kbd>u</kbd> 会回退到 "bar" 节点,如果再按一次 <kbd>u</kbd> 则会回退到 "foo" 节点。这时,如果我们按下 <kbd>Ctrl + r</kbd> 就会前进至 "bar" 节点,再按一次就回前进至 "quux" 节点。在这种方式下,我们无法访问到兄弟节点(即 "baz" 节点)。
|
||||
|
||||
与之对应的是按时间遍历,对应的按键是 `g-` 和 `g+`。对于上面的例子,按下 `g-` 会首先回退到 "baz" 节点。再次按下 `g-` 会回退到 "bar" 节点。
|
||||
|
||||
| 命令/按键 | 执行效果 |
|
||||
| --------- | -------- |
|
||||
| `[count]u` 或 `:undo [count]` | 回退到 `[count]` 次改动之前 |
|
||||
| `[count]<c-r>` 或 `:redo [count]` | 重做 `[count]` 次改动 |
|
||||
| `U` | 回退至最新的改动 |
|
||||
| `[count]g-` 或 `:earlier [count]?` | 根据时间回退到 `[count]` 次改动之前。"?" 为 "s"、"m"、"h"、"d" 或 "f"之一。例如,`:earlier 2d` 会回退到两天之前。`:earlier 1f` 则会回退到最近一次文件保存时的内容 |
|
||||
| `[count]g+` 或 `:later [count]?` | 类似 `g-`,但方向相反 |
|
||||
|
||||
内容变更记录会储存在内存中,当 Vim 退出时就会清空。详情请参阅本文[备份文件,交换文件,撤销文件以及viminfo文件的处理](#备份文件交换文件撤销文件以及viminfo文件的处理)章节的内容。
|
||||
|
||||
如果你觉得这一部分的内容难以理解,请参阅 [undotree](https://github.com/mbbill/undotree)。链接中的内容是这个树形结构的可视化版本。
|
||||
|
||||
请参阅以下链接获取更多帮助:
|
||||
|
||||
```vim
|
||||
:h undo.txt
|
||||
:h usr_32
|
||||
```
|
||||
|
||||
## 全局位置信息表,局部位置信息表
|
||||
|
||||
在某一个动作返回"位置"的时候,我们可以利用"全局位置信息表"和"局部位置信息表"来获取位置。位置可以是一个文件,一个行号或者是一个列。
|
||||
|
||||
比如,编译代码是出现错误,这时候我们就可以把错误的位置直接显示在全局位置信息表,或者通过外部抓取工具使位置显示在局部位置信息表中。
|
||||
|
||||
尽管我们也可以把这些信息显示到一个空格缓冲区中,但用这两个信息表显示的好处在于接口调用很方便,而且也便于浏览输出。
|
||||
|
||||
Vim 中,全局位置信息表只能有一个,但每一个窗口都可以有自己的局部位置信息表。这两个信息表的外观看上去很类似,但在操作上会稍有不同。
|
||||
|
||||
以下为两者的操作比较:
|
||||
|
||||
| 动作 | 全局位置信息表 | 局部位置信息表 |
|
||||
| ---- | -------------- | -------------- |
|
||||
| 打开窗口 | `:copen` | `:lopen` |
|
||||
| 关闭窗口 | `:cclose` | `:lclose` |
|
||||
| 下一个条目 | `:cnext` | `:lnext` |
|
||||
| 上一个条目 | `:cprevious` | `:lprevious` |
|
||||
| 第一个条目 | `:cfirst` | `:lfirst` |
|
||||
| 最后一个条目 | `:clast` | `:llast` |
|
||||
|
||||
请参阅 `:h :cc` 以及底下的内容,来获取更多命令的帮助。
|
||||
|
||||
**应用实例**:
|
||||
如果我们想用 `grep` 递归地在当前文件夹中寻找某个关键词,然后把输出结果放到全局位置信息表中,只需要这样:
|
||||
|
||||
```vim
|
||||
:let &grepprg = 'grep -Rn $* .'
|
||||
:grep! foo
|
||||
<grep output - hit enter>
|
||||
:copen
|
||||
```
|
||||
|
||||
执行了上面的代码,你就能看到所有包含字符串 "foo" 的文件名以及匹配到的相关字段都会显示在全局位置信息表中。
|
||||
|
||||
## 宏
|
||||
|
||||
你可以在 Vim 中录制一系列按键,并把他们存储到[寄存器](#寄存器)中。对于一些需要临时使用多次的一系列操作,把它们作为宏保存起来会显著地提升效率。对于一些复杂的操作,建议使用 Vim 脚本来实现。
|
||||
|
||||
- 首先,按下 <kbd>q</kbd>,然后按下你想要保存的寄存器,任何小写字母都可以。比如我们来把它保存到 `q` 这个寄存器中。按下 `qq`,你会发现命令行里已经显示了 "recording @q"。
|
||||
- 如果你已经录制完成,那么只需要再按一次 <kbd>q</kbd> 就可以结束录制。
|
||||
- 如果你想调用刚才录制的宏,只需要 `[count]@q`
|
||||
- 如果你想调用上一次使用的宏,只需要 `[count]@@`
|
||||
|
||||
**实例1**:
|
||||
|
||||
一个插入字符串 "abc" 后换行的宏,重复调用十次:
|
||||
|
||||
```vim
|
||||
qq
|
||||
iabc<cr><esc>
|
||||
q
|
||||
10@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**:
|
||||
|
||||
一个在每行前都加上行号的宏。从第一行开始,行号为 1,后面依次递增。我们可以通过 <kbd>Ctrl</kbd> + <kbd>a</kbd> 来实现递增的行号,在定义宏的时候,它会显示成 `^A`。
|
||||
|
||||
```vim
|
||||
qq
|
||||
0yf jP0^A
|
||||
q
|
||||
1000 @q
|
||||
```
|
||||
|
||||
这里能实现功能,是因为我们假定了文件最多只有 1000 行。但更好的方式是使用"递归"宏,它会一直执行,知道不能执行为止:
|
||||
|
||||
```vim
|
||||
qq
|
||||
0yf jP0^A@q
|
||||
q
|
||||
@q
|
||||
```
|
||||
|
||||
(对于上面这个插入行号的功能,如果你不愿意使用宏,同样可以通过这段按键操作来实现:`:%s/^/\=line('.') . '. '`)。
|
||||
|
||||
这里向大家展示了如何不用宏来达到相应的效果,但要注意,这些不用宏的实现方式只适用于这些简单的示例。对于一些比较复杂的自动化操作,你确实应该考虑使用宏。
|
||||
|
||||
请参阅以下文档获取更多帮助:
|
||||
|
||||
```vim
|
||||
:h recording
|
||||
:h 'lazyredraw'
|
||||
```
|
||||
|
||||
## 颜色主题
|
||||
|
||||
颜色主题可以把你的 Vim 变得更漂亮。Vim 是由多个组件构成的,我们可以给每一个组件都设置不同的文字颜色、背景颜色以及文字加粗等等。比如,我们可以通过这个命令来设置背景颜色:
|
||||
|
||||
```vim
|
||||
:highlight Normal ctermbg=1 guibg=red
|
||||
```
|
||||
|
||||
执行后你会发现,现在背景颜色变成红色了。请参阅 `:h :highlight` 来获取更多帮助。
|
||||
|
||||
其实,颜色主题就是一系列的 `:highlight` 命令的集合。
|
||||
|
||||
事实上,大部分颜色主题都包含两套配置。一套适用于例如 xterm 和 iTerm 这样的终端环境(使用前缀 `cterm`),另一套适用于例如 gvim 和 MacVim 的图形界面环境(使用前缀 `gui`)。对于上面的例子,`ctermbg` 就是针对终端环境的,而 `guibg` 就是针对图形界面环境的。
|
||||
|
||||
如果你下载了一个颜色主题,并且在终端环境中打开了 Vim,然后发现显示的颜色与主题截图中差别很大,那很可能是配置文件只设置了图形界面环境的颜色。反之同理,如果你使用的是图形界面环境,发现显示颜色有问题,那就很可能是配置文件只设置了终端环境的颜色。
|
||||
|
||||
第二种情况(图形界面环境的显示问题)其实不难解决。如果你使用的是 Neovim 或者 Vim 7.4.1830 的后续版本,可以通过打开 "true colors" 设置来解决显示问题。这就可以让终端环境的 Vim 使用 GUI 的颜色定义,但首先,你要确认一下你的终端环境和环境内的组件(比如 tmux)是否都支持 "true colors"。可以看一下[这篇文档](https://gist.github.com/XVilka/8346728),描述的十分详细。
|
||||
|
||||
请参阅以下文档或链接来获取更多帮助:
|
||||
|
||||
- `:h 'termguicolors'`
|
||||
- [主题列表](#主题列表)
|
||||
- [自定义主题中的颜色](#自定义主题中的颜色)
|
||||
|
||||
## 折叠
|
||||
|
||||
每一部分文字(或者代码)都会有特定的结构。对于存在结构的文字和代码,也就意味着它们可以按照一定的逻辑分割成不同区域。Vim 中的折叠功能,就是按照特定的逻辑把文字和代码折叠成一行,并显示一些简短的描述。折叠功能涉及到很多操作,而且折叠功能可以嵌套使用。
|
||||
|
||||
在 Vim 中,有以下 6 中折叠类型:
|
||||
|
||||
| 折叠方式 | 概述 |
|
||||
| -------- | ---- |
|
||||
| diff | 在"比较窗口"中折叠未改变的文本 |
|
||||
| expr | 使用 `'foldexpr'` 来创建新的折叠逻辑 |
|
||||
| indent | 基于缩进折叠 |
|
||||
| manual | 使用 `zf`、`zF` 或 `:fold` 来自定义折叠 |
|
||||
| marker | 根据特定的文本标记折叠(通常用于代码注释) |
|
||||
| syntax | 根据语法折叠,比如折叠 `if` 代码块 |
|
||||
|
||||
**注意**:折叠功能可能会显著地影响性能。如果你在使用折叠功能的时候出现了打字卡顿之类的问题,请考虑使用 [FastFold 插件](https://github.com/Konfekt/FastFold)。这个插件可以让 Vim 按需更新折叠内容,而不是一直调用。
|
||||
|
||||
请参阅以下文档获取更多帮助:
|
||||
|
||||
```vim
|
||||
:h usr_28
|
||||
:h folds
|
||||
```
|
||||
|
||||
## 会话
|
||||
|
||||
如果你保存了当前的"视图"(请参阅 `:h :mkview`),那么当前窗口、配置和按键映射都会被保存下来(请参阅 `:h :loadview`)。
|
||||
|
||||
"会话"就是存储所有窗口的相关设置,以及全局设置。简单来说,就是给当前的 Vim 运行实例拍个照,然后把相关信息存储到会话文件中。存储之后的改动就不会在会话文件中显示,你只需要在改动后更新一下会话文件就可以了。
|
||||
|
||||
你可以把当前工作的"项目"存储起来,然后可以在不同的"项目"之间切换。
|
||||
|
||||
现在就来试试吧。打开几个窗口和标签,然后执行 `:mksession Foo.vim`。如果你没有指定文件名,那就会默认保存为 `Session.vim`。这个文件会保存在当前的目录下,你可以通过 `:pwd` 来显示当前路径。重启 Vim 之后,你只需要执行 `:source Foo.vim`,就可以恢复刚才的会话了。所有的缓冲区、窗口布局、按键映射以及工作路径都会恢复到保存时的状态。
|
||||
|
||||
其实 Vim 的会话文件就只是 Vim 命令的集合。你可以通过命令 `:vs Foo.vim` 来看看会话文件中究竟有什么。
|
||||
|
||||
你可以决定 Vim 会话中究竟要保存哪些配置,只需要设置一下 `'sessionoptions'` 就可以了。
|
||||
|
||||
为了方便开发,Vim 把最后一次调用或写入的会话赋值给了一个内部变量 `v:this_session`。
|
||||
|
||||
请参阅以下文档来获取更多帮助:
|
||||
|
||||
```vim
|
||||
:h Session
|
||||
:h 'sessionoptions'
|
||||
:h v:this_session
|
||||
```
|
||||
|
||||
## 局部化
|
||||
|
||||
以上提到的很多概念,都有一个局部化(非全局)的版本:
|
||||
|
||||
| 全局 | 局部 | 作用域 | 帮助文档 |
|
||||
| ---- | ---- | ------ | -------- |
|
||||
| `:set` | `:setlocal` | 缓冲区或窗口 | `:h local-options` |
|
||||
| `:map` | `:map <buffer>` | 缓冲区 | `:h :map-local` |
|
||||
| `:autocmd` | `:autocmd * <buffer>` | 缓冲区 | `:h autocmd-buflocal` |
|
||||
| `:cd` | `:lcd` | 窗口 | `:h :lcd` |
|
||||
| `:<leader>` | `:<localleader>` | 缓冲区 | `:h maploacalleader` |
|
||||
|
||||
变量也有不同的作用域,详细内容请参考 [Vim scripting 的文档](http://vimdoc.sourceforge.net/htmldoc/usr_41.html)。
|
||||
|
||||
## 加入我们
|
||||
可以协助我们核对翻译,或者从[章节列表](CONTRIBUTING.md)中认领章节进行翻译。
|
||||
|
||||
## 致谢:
|
||||
|
Loading…
x
Reference in New Issue
Block a user