Learn Vim
vim 帮助
移动命令
:h motion.txt
退出Vim
:quit :q
- 如果
:
以普通模式键入,则光标将移至屏幕底部,您可以在其中键入一些命令。 - 如果处于插入模式,键入
:
将在屏幕上逐字产生字符“:”。在这种情况下,您需要切换回普通模式。 - 命令式模式 ==>
<Esc>
返回正常模式
保存文件
保存更改:
:write
保存新文件
:w new_file.txt
保存并退出
:wq
退出但不保存任何更改
:q!
插入
i insert 当前光标前插入
I insert before line 光标移动到当前行 起始位置
a append 当前光标后插入
A append after line 光标移动到当前行 末尾
o open a line below 往后另起一行
O append a line above 往前另起一行
Vim
模式
普通模式
为什么进入
vim
不能插入-normal
模式
- 进入
Vim
默认是normal
(普通)模式。使用Esc
从插入回到普通模式- 普通模式下可以进行各种命令操作和移动
- 大部分情况下你是在浏览而不是编辑,所以
Vim
默认是normal
插入模式
- i (insert) a(append) o (open a line below) 进入插入模式
- 使用
Esc
退出插入模式到normal
模式
命令模式
Normal
模式下输入:之后执行命令,比如保存退出:wq
- 保存
:w
, 退出:q
保存退出:wq
退出但不保存:q!
- 分屏
:vs(vertical split)
:sp(split)
- 设置行号
:set nu
- 全局替换
:% s/java/js
/g [注] java 将会被替换为 js, /g 为全局替换
可视化模式
一般用来块状选择文本
Normal
模式下使用v
进入visual
选择- 使用
V
选择行- 使用
ctrl + v
进行方块选择
Vim
移动
上下左右移动
h 左
j 下
k 上
l 右
在单词之间【切换】
-
w / W
移到下一个word / WORD
开始,e / E
移动到下一个word / WORD
末尾 -
b / B
回到上一个word / WORD
开头 ,也可以理解为backword
word
指的是以非空白符分割得单词,WORD
以空白符分割得单词
行间搜索移动
同一行快速移动得方式其实是搜索一个在字符并且移动到该字符
- 使用
f{char}
可以移动到char
字符上,t
移动到cahr
的前一个字符 - 如果第一次没搜到,可以i用分号
(;)
or(,)` 继续搜索该行下一个 / 上一个 - 大写的
F
表示反过来搜前面的字符
如何快速移动到一行的行首或者行尾呢?
- 0 移动到行首第一个字符,
^
移动到第一个非空白字符 - $ 移动到行尾,
g_
移动到行尾非空白字符 - 记住 常用 的 0 和
$
就可以满足日常需求了
Vim
垂直移动
我们还可以在句子(sentence
)和段落(paragraph
)间移动(不常用)
- 使用括号()在句子间移动,你可以用
:help (
来查看帮助 - 使用 { } 在段落之间移动
-
easy-motion
插件移动,这些命令就都不用记忆了
Vim
页面移动
-
gg / G
移动到文件开头和结尾,你可以使用ctrl + o
快速返回 -
H / M / L
跳转到屏幕的开头(Head),中间(Middle) 和 结尾 (Lower) -
ctrl + u
ctrl + f
上下翻页 (upword / forward
)zz
把屏幕置为中间
Vim
快速增删改查
Vim
增加字符
- 进入插入模式编辑文本
- 使用
a / i / o
进入插入模式
Vim
快速删除
-
Vim
在normal
模式下使用x
快速删除一个字符 - 使用
d (delete)
配合文本对象快速删除一个单词daw (d around word)
-
d
和x
都可以搭配数字来执行多次
Vim
快速修改
- 常用的有三个
r(replace) , c (change) , s (substitute)
-
normal
模式下使用r
可以替换一个字符。s
替换并进入插入模式 - 使用
c
配合文本对象,我们可以快速进行修改
Vim
查询
- 使用
/
或者?
进行前向或者反向搜索 - 使用
n / N
跳转到下一个 或者上一个匹配 - 使用
*
或者#
进行当前单词的前向和后向匹配
语法规则
verb(动词) + noun(名词) 也就是 动词 加 名词 的规则
词汇表
名词(动作Motion)
我们这里将动作作为名词,动作用来在Vim中到处移动,他们也是Vim中的名词。下面列出了一些常见的动作的例子:
h 左
j 下
k 上
l 右
w 向前移动到下一个单词的开头
e 下一个 字符的首位字母
} 跳转到下一个段落
^ 跳转到当前行的首位
$ 跳转到当前行的末尾s
动词(操作符 operator
)
y yank (复制)
d delete (删除)
c change (删除文本,将删除的文本存到寄存器中,进入插入模式)
p paste (粘贴)
const learn = "vim"
- 复制当前位置带行尾的所有内容
y$
- 删除当前位置到下一个单词的开头
dw
- 删除当前位置到这个段落的位置
c}
动作也接受数字作为参数,如果你需要向上移动3行,你可以用 3k
代替按3此K
- 想做拷贝俩个字符
y2h
- 删除后俩个单词
d2w
- 修改后俩行
c2j
更多名词(文本对象)
想象一下你现在正在某个被括号包围的文本中例如(hello Vim)
,你现在想要删掉括号中的所有内容,你会怎样快速的完成它?是否有一种方法能够把括号中内容作为整体删除呢?
答案是有的。文本通常是结构化的,特别是代码经常被放置在小括号、中括号、大括号、引号等当中。Vim提供了一种处理这种结构的文本对象的方法。
文本对象可以被操作符使用,这里有两类文本对象:
i + object 内部文本对象
a + object 外部文本对象
内部文本对象选中的部分不包含包围文本对象的空白或括号等,外部文本对象则包括了包围内容的空白或括号等对象。外部对象总是比内部对象选中的内容更多,因此如果你的光标位于一对括号内部,例如(hello Vim)
中:
- 删除括号内部的内容但保留括号:
di(
- 删除括号以及内部的内容 :
da(
const hello = function() {
console.log("Hello Vim");
return true;
}
- 删除 括号内内容:
di(
- 删除
hello
:dw
- 删除 整个函数(被{}包含):
di{
文本对象很强大因为你可以在一个位置指向不同的对象,能够删除一对括号、函数体或整个单词的文本对象中的内容。此外,当你看到di(
,di{
和diw
时,你也可以很好的意识到他们表示的是什么。
让我们来看最后一个例子。假设你有这样一些html
的标签的文本:
<div>
<h1>Header1</h1>
<p>Paragraph1</p>
<p>Paragraph2</p>
</div>
如果你的光标位于"Header1
"文本上:
- 删除
Header1
:dit
- 删除
: \Header1
dat
如果你的光标在"div"文本上:
- 删除
h1
和所有的p
标签的行 :dit
- 删除所有文本 :
dat
- 删除
div
:di<
下面列举的一些通常见到的文本对象:
w 一个单词
p 一个段落
s 一个句子
(或) 一对()
{或} 一对{}
[或] 一对[]
<或> 一对<>
t XML标签
" 一对""
' 一对''
` 一对``
换句话说,假设你只知道四个动作:w, $, }, G
和删除操作符(d
),你可以做8件事:按四种方式移动(w, $, }, G
)和删除4种文本对象(dw, d$, d}, dG
)。如果有一天你学习了小写变大写的操作符(gU
),你的Vim工具箱中多的不是1种工具,而是4种:gUw, gU$, gU}, gUG
。现在你的Vim工具箱中就有12种工具了。如果你知道10个动作和5个操作符,那么你就有60种工具(50个操作+10个移动)。另外,行号动作(nG
)给你了n
种动作,其中n
是你文件中的行数(例如前往第5行,5G
)。搜索动作(/
)实际上给你带来无限数量的动作因为你可以搜索任何内容。你知道多少终端命令,外部命令操作符(!
)就给你了多少种过滤工具。使用Vim这种能够组合的工具,所有你知道的东西都可以被串起来完成更复杂的操作。你知道的越多,你就越强大。