Skip to content

Commit

Permalink
加入常用操作
Browse files Browse the repository at this point in the history
  • Loading branch information
izhengfan committed Apr 14, 2018
1 parent 33f3875 commit 4e07f98
Showing 1 changed file with 124 additions and 1 deletion.
125 changes: 124 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Vim 的教程相对比较零散,系统的教程比较少,我也阅读过不
- [基本概念](#基本概念)
- [基本操作](#基本操作)
- [移动命令](#移动命令)
- [操作命令](#操作命令)


<!-- vim-markdown-toc -->

Expand Down Expand Up @@ -51,6 +53,8 @@ Vim 打开是默认的模式是 Normal 模式,在这一模式下,按键不
| `a` | 在当前光标字符后插入 | append |
| `I` | 在当前行首插入 | Insert |
| `A` | 在当前行尾插入 | Append |
| `o` | 在下方开一新行,插入 | open |
| `O` | 在上方开一新行,插入 | Open |

普通模式切换到可视模式,按键就比较单一了,比较常用的是:

Expand Down Expand Up @@ -108,7 +112,7 @@ h、j、k、l 按键。
| n+`j`| 光标下移 n 个位置 ,n(umber) 指数字 |
| n+`k`| 光标上移 n 个位置 ,n(umber) 指数字 |
| n+`l`| 光标右移 n 个位置 ,n(umber) 指数字 |

带上了数字后,你发现光标健步如飞,仿佛穿上了跑鞋:)

开放思想,当你编辑一个小文件时,正好光标在一行中部,你想跳到行首,你可以`99h`
Expand All @@ -131,3 +135,122 @@ h、j、k、l 按键。
| `b` | 跳到上一个词首 | back-word |
| `e` | 跳到下一个词尾 | end |
| `ge` | 跳到上一个词尾 | |

词间跳转中,“上一个词首”的精确断句为“上一个/词首”,即如果当前光标不在词首,则跳到本词词首;
如果当前光标已经在词首,才跳到上一个词的词首。
“下一个词尾”与此类似。

词间跳转也是支持“数字+移动命令”的,比如输入 `5w` 可以向后移动 5 个词。

除了 Normal 模式,移动命令也可以在可视模式下使用。
在可视模式下移动光标时,从**进入可视模式时的光标位置****移动后的光标位置**之间的文本将会被选中。

### 操作命令

编辑文档的过程,实际上就是不断操作特定文本的过程:删除、修改、复制,等等。
Vim 下的操作命令(Operator Commands)即特指一系列针对特定文本的操作。
常用的操作命令包括:

| 按键 | 描述 | 助记 |
|------|----------------------|--------|
| `c` | 删除,并进入插入模式 | change |
| `d` | 删除 | delete |
| `y` | 复制 | yank |
| `gu` | 变为小写字母 | |
| `gU` | 变为大写字母 | |
| `g~` | 颠倒字母的大小写 | |
| `>` | 右缩进 | |
| `<` | 左缩进 | |
| `=` | 自动缩进 | |

你可能会问,那怎么指定这些操作命令作用的文本对象呢?

#### 操作命令+移动命令

记住我们刚开始所说的,Vim 的各种命令都是可以灵活组合变通的!
操作特定文本,Vim 的解决方案是"**操作命令+移动命令**",
即操作命令的对象由移动命令来指定,举例:

- `dl`:向右删除一个字符(删除当下字符,右侧字符不会被删);
- `dh`:向左删除一个字符(删除左侧字符,当下字符不会被删);
- `d3l`:向右删除 3 个字符(`3dl` 亦有相同效果,下同);
- `d3w`:删除文本至右侧第三个词首之前;
- `de`:删除当下字符至下一个词尾;
- `y2w`:复制当下位置至右侧第二个词首之间的文本;
- `gUe`:将当下字符至下一个词尾变成大写;

其他请以此类推。你会发现,由于操作命令和移动命令的多种多样,能够组合出来的文本操作也是多种多样。
再结合数字,可以实现的功能就更强大了。

需要注意的是,一个操作命令只会对紧随其后的一个移动命令有效。所以 `dll` 的作用是
“向右删除一个字符后再右移一位”,而不是“向右删除两个字符”。
如果要实现“向右删除两个字符”,应使用 `d2l`
`2l` 虽然相当于移动两次,当应视为单个移动命令(因为单独一个数字不构成一个完整命令)。

#### 操作命令二连击 = 行操作

针对一整行的操作是很常见的。
比如,如果要删除一整行,应该如何操作呢?
根据上面的讲解,你可能会回答:先用 `0` 回到行首,再用 `d$` 删至行尾。
这未免显得繁琐了些。而且,这只是删除了行内字符,并没有将整行删掉。

Vim 提供了“操作命令二连击”的方式来实现真正的行操作:

| 按键 | 描述 |
|--------------|----------------------|
| `cc` | 删除整行 |
| `dd` | 删除整行 |
| `yy` | 复制整行 |
| `guu`/`gugu` | 整行变为小写字母 |
| `gUU`/`gUgU` | 整行变为大写字母 |
| `g~~`/`g~g~` | 颠倒整行字母的大小写 |
| `>>` | 行右缩进 |
| `<<` | 行左缩进 |
| `==` | 行自动缩进 |

#### 可视模式下操作命令

可视模式下使用操作命令则直观得多。
进入可视模式,用移动命令选择文本,再键入操作命令,指定的操作就会作用在选中文本上。
操作完成后,会自动退回 Normal 模式。

可视模式下“移动指令+操作指令”,和 Normal 模式下“操作指令+移动指令”,各有利弊。

Normal 模式的好处显而易见,不用切换模式,更快捷。

可视模式的好处是操作对象更精准可控,因为选中的文本会被高亮;
相比之下,Normal 模式下就有点“黑灯瞎火”的感觉,如果移动指令稍微有点复杂,就易出错
(比如 `d7w`,词数太多很可能数错)。
此外,Normal 模式下,操作命令对光标移动的起始和终末字符是否生效,容易产生混淆,比如
`de` 会连包括词尾在内的字符一起删掉,而 `dw` 却是删到下一个词首之前的字符为止。

总之,完成一种操作,在 Vim 下往往有多种解决方案,应在实践中找到适合自己的最佳方案。

#### 更多常用命令

上述操作命令在 Normal 模式都无法单独生效,需要二连击或者配合移动指令之类才能起作用。

Normal 模式下“一击即中”的常用命令则包括:

| 按键 | 描述 | 助记 |
|------------|---------------------------------------------------|-----------|
| `p` | 粘贴于当前光标之后 | paste/put |
| `P` | 粘贴于当前光标之前 | Paste/Put |
| `x` | 删除当前字符,相当于 `dl` | |
| `s` | 删除当前字符并插入,相当于 `cl` | |
| `C` | 删除至行尾并插入,相当于 `c$` | |
| `S` | 从当前行首个非空字符删除至行尾并插入,相当于 `^C` | |
| `u` | 撤销上一次修改 | undo |
| `<Ctrl-r>` | 重做上一次修改,`u` 的逆过程 | redo |
| `.` | 在当前光标处重复上一次修改 | |

一个小思考题:`d2w``dw.` 都可以实现相同的效果,它们本质上一样吗?
如果它们之后跟着一个 `u``.`,效果有什么不同?
考虑一下,如果你要删除接连几个词,大概会使用怎样的键入组合。

对了,重做命令是 `<Ctrl-r>` 而非 `r`,因为 `r` 被另一个常用命令占用了,即替代命令:

| 按键 | 描述 | 助记 |
|------|---------------------------------------------------------------------------------------------|---------|
| `r` | 替代字符,将当前字符替代为紧跟着输入的字符 | replace |
| `R` | 进入替代模式,将当前及之后的字符都替代为紧跟着输入的字符串,直到按 `<Esc>` 返回 Normal 模式 | Replace |

0 comments on commit 4e07f98

Please sign in to comment.