【Vim】常用总结
简介
什么是vim?
Linux下两大编辑神器之一 vim
- Linux/Unix下使用最多的编辑器
- vi的改进版
- 可能是最难上手的编辑器之一
为什么要学习vim?
都21世纪了,为什么还需要学习vim?
- 只要你用服务器,vim就是个必备技能
- 后端和运维工程师必须掌握的编辑器,不然服务器上操作很尴尬
- 可以纯键盘编辑,提升编辑效率
初识vim
据说Stackoverflow帮助过上百万开发者退出过vim!
- 输入
vim
命令进入vim - 进去之后似乎没法输入东西,起始默认进去是normal模式
- 使用
:q
可以退出vim
开始编辑
进入编辑模式就可以像其他编辑器一样编辑了
- 使用
i
(insert)进入编辑模式,开始输入文字 i
表示(insert),a
(append),o
(open a line below)- 使用Esc可以退出编辑模式,又回到normal模式。
- 使用
:wq
保存退出
w(write),q(quit)
insert -> normal:使用Esc
normal -> insert:(小写是操作字符,大写是操作行)
-
i
:(insert)表示进入insert编辑模式后,在当前字符的前面插入insert
-
a
:(append)表示进入insert编辑模式后,在当前字符后附加插入append
-
o
:(open a line below)表示进入insert编辑模式后,在当前行下新启一行插入open a line below
-
I
:(insert before line)表示在当前行的最前面插入insert before line
-
A
:(append after line)表示在当前行的最后附加插入append after line
-
O
:(open a line above)表示在当前行上新启一行插入append a line above
保存:
-
:w
:(write)写入,保存write
-
:q
:(quit)退出quit
-
:wq
:(write and quit)保存并退出write and quit
vim,为什么你有这么多模式
怪异的vim模式
vim和其他很多编辑器的区别在于多种模式
- 进入vim默认是normal(普通)模式?为什么不是编辑模式呢?
- 使用
a
(append)、i
(insert)等进入编辑模式 - 还有cmd命令模式和
v
(visual)可视化模式
为什么进入vim不能插入-normal模式
奇怪的是,为什么vim进入之后不像其他编辑器一样直接插入?
-
进入Vim默认是normal(普通)模式。使用
Esc
从插入回到普通模式 -
普通模式下可以进行各种命令操作和移动
-
大部分情况下你是在浏览而不是编辑,所以Vim默认是normal
Insert(插入)模式
插入模式下Vim可以直接编辑,和其他编辑器一样
-
使用
i
(insert) 、a
(append) 、o
(open a line below)进入插入模式 -
使用Esc退出插入模式到normal模式
Command(命令)模式
Normal模式下输入:
之后执行命令,比如保存退出:wq
一气呵成
- 顾名思义,执行Vim命令,比如保存
:w
,退出:q
- 比如分屏:
:vs
(vertical split),:sp
(split) - 比如使用:
:% s/foo/bar/g
全局替换
%:表示本文件全部文本
g:表示全局替换
Visual(可视)模式
Visual模式一般用来块状选择文本(类比使用Alt+鼠标拖动)
- Normal模式下使用
v
进入visual选择 - 使用
V
选择行 - 使用
ctrl+v
进行方块选择
vim编辑小技巧
如何快速纠错(insert模式下)
代码就像人生,总是经常出错,需要我们快速修正
- 进入Vim之后首先使用
a
/i
/o
之一进入插入模式 ctrl+h
删除上一个字符,ctrl+w
删除上一个单词,ctrl+u
删除当前行
快速切换insert和normal模式
很多键盘的键位设置, Esc
按起来不方便,不方便切换到normal
- 使用
Ctrl+c
代替Esc
(但是可能会中断某些插件)或者ctrl+[
gi
快速跳转到你最后一次编辑的地方并进入插入模式- 在配置章节我们会讲解如何映射方便的快捷键来替代Esc
vim快速移动大法
h # 光标左移,同 <Left> 方向键
j # 光标下移,同 <Down> 方向键
k # 光标上移,同 <Up> 方向键
l # 光标右移,同 <Right> 方向键
Ctrl+e # 向上滚动一行
Ctrl+y # 向下滚动一行
Ctrl+u # 向上滚动半屏 --> Move up 1/2 a screen
Ctrl+d # 向下滚动半屏 --> Move down 1/2 a screen
Ctrl+f # 向下滚动一屏 --> Move forward one full screen
Ctrl+b # 向上滚动一屏 --> Move back one full screen
0 # 跳到行首,数字 0,效用等同于 <Home> 键
^ # 跳到从行首开始第一个非空白字符
$ # 跳到行尾,效用等同于 <End> 键
gg # 跳到第一行,效用等同于 Ctrl+<Home>
G # 跳到最后一行,效用等同于 Ctrl+<End>
NG # 跳到第 N 行,比如 10G 是移动到第 10 行
:N # 跳到第 N 行,比如 :10<Enter> 是移动到第 10 行
10% # 移动到文件 10% 处
N| # 移动到当前行的 N 列
w # 跳到下一个单词开头(word:标点或空格分隔的单词)
W # 跳到下一个单词开头(Word:空格分隔的单词)
e # 跳到下一个单词尾部(word:标点或空格分隔的单词)
E # 跳到下一个单词尾部(Word:空格分隔的单词)
b # 跳到上一个单词开头(word:标点或空格分隔的单词)
B # 跳到上一个单词开头(Word:空格分隔的单词)
ge # 跳到前一个单词结尾
) # 向前移动一个句子(句号分隔)
( # 向后移动一个句子(句号分隔)
} # 向前移动一个段落(空行分隔)
{ # 向后移动一个段落(空行分隔)
<Enter> # 移动到下一行首个非空字符
N<Enter> # 光标向下移动 N 行
+ # 移动到下一行首个非空字符(同回车键)
- # 移动到上一行首个非空字符
H # 移动到屏幕上部(H: High)
M # 移动到屏幕中部(M: Middle)
L # 移动到屏幕下部(L: Low)
<S+Left> # 按住 Shift 按左键,向左移动一个单词
<S+Right> # 按住 Shift 按右键,向右移动一个单词
<S+Up> # 按住 Shift 按上键,向上翻页
<S+Down> # 按住 Shift 按下键,向下翻页
gm # 移动到的行中间
gj # 光标向下移动一个屏幕行(忽略自动换行)
gk # 光标向上移动一个屏幕行(忽略自动换行)
zz # 调整光标所在行到屏幕中央
zt # 调整光标所在行到屏幕上部
zb # 调整光标所在行到屏幕下部
反人类的hjkl
众所周知,vim normal模式使用了反人类的hjkl来移动
- 据说编辑器作者在编写vim的时候键盘还没流行上下左右按键
h
(左) ,j
(下) ,k
(上) ,l
(右) ,移动也不会让手指脱离主键盘区- 相信我,逼着自己使用hjkl一段时间之后,你会体会到它非常有效率
使用hjkl
只需要几天的适应,你就可以熟练使用hjkl来移动
在单词之间“飞舞”(normal模式下)
在单词之间移动是我们浏览操作中最常使用的命令
w/W
移到下一个word/WORD开头。e/E
下一个word/WORD尾b/B
回到上一个word/WORD开头,可以理解为backword- word指的是以非空白符分割的单词, WORD以空白符分割的单词
行间搜索移动
同一行快速移动的方式其实是搜索一个字符并且移动到该字符
- 使用
f{char}
可以移动到char字符上,t{char}
移动到char的前一个字符
f
:(find)
t
:(until)可以配合删除使用,如
dt)
从当前字符开始删除直到)。
- 如果第一次没搜到,可以用分号(
;
)/逗号(,
)继续搜该行下一个/上一个 - 大写的
F{char}
表示反过来搜前面的字符
vim水平移动
如何快速移动到一行的行首或者行尾呢?
0
移动到行首第一个字符,^
移动到第一个非空白字符
^
:在正则表达式中,表示行的开头
$
移动到行尾,g_
移动到行尾非空白字符
$
:在正则表达式中,表示行的结尾
- 记住常用的
0
和$
就可以满足日常需求了
Vim垂直移动
我们还可以在句子(sentence)和段落(paragraph)间移动(不常用)
- 使用括号
()
在句子间移动,你可以用:help (
来查看帮助 - 使用
{}
在段落之间移动 - 插件章节我们会讲如何用easy-motion插件移动,这些命令就都不用记忆啦
Vim页面移动
翻页命令太多, 2/8定律,记住常见的就能满足需求
gg/G
移动到文件开头和结尾,你可以使用ctrl+o
快速返回nG
移动到文件第n行,可以配合命令使用,如dnG
表示删除到第n行H/M/L
跳转到屏幕的开头(Head),中间(Middle)和结尾(Lower)Ctrl+u
,ctrl+f
上下翻页(upword/forward)。zz
把屏幕置为中间
什么是vim的text object
0 # 到行首,数字 0
^ # 到行首非空字符,可以使用 0w 代替 ^,按键更方便
$ # 到行尾
iw # 整个单词 Word(不包括分隔符)
aw # 整个单词 Word(包括分隔符)
iW # 整个 Word(不包括分隔符)
aW # 整个 Word(包括分隔符)
is # 整个句子 (s: sentence)(不包括分隔符)
ib # 小括号内(b: brackets)
ab # 小括号内(包含小括号本身)
iB # 大括号内
aB # 大括号内(包含大括号本身)
i) # 小括号内
a) # 小括号内(包含小括号本身)
i] # 中括号内
a] # 中括号内(包含中括号本身)
i} # 大括号内
a} # 大括号内(包含大括号本身)
i' # 单引号内
a' # 单引号内(包含单引号本身)
i" # 双引号内
a" # 双引号内(包含双引号本身)
2i) # 往外两层小括号内
2a) # 往外两层小括号内(包含小括号本身)
2f) # 到第二个小括号处
2t) # 到第二个小括号前
Text Object(文本对象)
如果你学过主流的编程语言,一定知道面向对象编程
- Vim里文本也有对象的概念,比如一个单词,一段句子,一个段落
- 很多其他编辑器经常只能操作单个字符来修改文本,比较低效
- 通过操作文本对象来修改要比只操作单个字符高效
文本对象:
- 单词
w
(word) - 句子
s
(sentence) - 段落
p
(paragraph) - 标签
t
(tag) - 小括号
b
(bracket)、大括号B
文本对象操作方式
之前我们已经使用过文本对象了,回忆下dw
(删除一个单词)
[number] <command> [text object]
- 或者
<command> [number] [text object]
- number表示次数,command是命令,
d
(delete),c
(change),y
(yank) - text object是要操作的文本对象
通过示例来学习
iw
表示inner word,如果键入viw
命令,那么首先v
将进入选择模式,然后iw
将选中当前单词。aw
表示around word,它不但会选中当前单词,还会包含当前单词之后的空格。
以下实例中的[]表示作用范围:
-
iw
This is a [test] sentence. -
aw
This is a [test ]sentence. -
iw
This is a [...test...] sentence. -
aw
This is a [...test... ]sentence. -
is
...sentence. [This is a sentence.] This... -
as
...sentence. [This is a sentence. ]This...
End of previous paragraph. -
ip
[This is a paragraph. It has two sentences.]
The next.
End of previous paragraph. -
ap
[This is a paragraph. It has two sentences.
]The next. -
ip
<xml>[hello world]</xml> -
ap
[<xml>hello world</xml>] -
i(
ori)
1*([2+3]) -
a(
ora)
1*[(2+3)] -
i<
ori>
The <[tag]> -
a<
ori>
The [<tag>] -
i{
ori}
some {[code block]} -
a{
ora}
some [{code block}] -
i[
ori]
some [[code block]] -
a[
ora]
some [[code block]] -
i"
The "[best]" -
a"
The ["best"] -
i'
The '[best]' -
a'
The ['best']
vim快速增删改查命令
数字+命令+对象
表示多次执行命令,如 2dw
或者 命令+数字+对象
,如 d2w
Vim增加字符
增加字符就是进入插入模式,开始敲键盘吧
- 进入插入模式编辑文本
- 使用a/i/o进入插入模式
- 还记得A/I/O是什么作用么?
i # 在光标处进入插入模式
I # 在行首进入插入模式
a # 在光标后进入插入模式
A # 在行尾进入插入模式
o # 在下一行插入新行并进入插入模式
O # 在上一行插入新行并进入插入模式
gi # 进入到上一次插入模式的位置
<Esc> # 退出插入模式
Ctrl+[ # 退出插入模式,等价于 Esc 键
Vim快速删除
如何快速删除一个字符或者单词呢 ?
- Vim在normal模式下使用
x
快速删除一个字符 - 使用
d
(delete)配合文本对象快速删除一个单词daw
(delete around word)
dw
:默认为daw
d
和x
都可以搭配数字来执行多次
Vim快速修改
相比删除,更常用修改,一般是删除之后改成我们期望的文本
- normal 模式下,常用有三个,
r
(replace),c
(change),s
(substitute) - 使用
r
可以替换一个字符。 - 使用
s
替换并进入插入模式 - 使用
c
配合文本对象,我们可以快速进行修改整个文本对象。如ci"
、ciw
r # 替换当前字符
R # 进入替换模式,直至 Esc 离开
s # 替换字符(删除光标处字符,并进入插入模式,前可接数量)
S # 替换行(删除当前行,并进入插入模式,前可接数量)
cc # 改写当前行(删除当前行并进入插入模式),同 S
cw # 改写光标开始处的当前单词
ciw # 改写光标所处的单词
caw # 改写光标所处的单词,并且包括前后空格(如果有的话)
c0 # 改写到行首
c^ # 改写到行首(第一个非零字符)
c$ # 改写到行末
C # 改写到行尾(同 c$)
ci" # 改写双引号中的内容
ci' # 改写单引号中的内容
cib # 改写小括号中的内容
cab # 改写小括号中的内容(包含小括号本身)
ci) # 改写小括号中的内容
ci] # 改写中括号中内容
ciB # 改写大括号中内容
caB # 改写大括号中的内容(包含大括号本身)
ci} # 改写大括号中内容
cit # 改写 XML tag 中的内容
cis # 改写当前句子
c2w # 改写下两个单词
ct( # 改写到小括号前
x # 删除当前字符,前面可以接数字,3x 代表删除三个字符
X # 向前删除字符
dd # 删除(剪切)当前行,并把删除的行存到剪贴板里 --> Delete (cut) a line
d0 # 删除(剪切)到行首
d^ # 删除(剪切)到行首(第一个非零字符)
d$ # 删除(剪切)到行末
D # 删除(剪切)到行末(同 d$)
dw # 删除(剪切)当前单词
diw # 删除(剪切)光标所处的单词
daw # 删除(剪切)光标所处的单词,并包含前后空格(如果有的话)
di" # 删除双引号中的内容
di' # 删除单引号中的内容
dib # 删除小括号中的内容
di) # 删除小括号中的内容
dab # 删除小括号内的内容(包含小括号本身)
di] # 删除中括号中内容
diB # 删除大括号中内容
di} # 删除大括号中内容
daB # 删除大括号内的内容(包含大括号本身)
dit # 删除 XML 中 tag 中的内容
dis # 删除当前句子
d2w # 删除下两个单词
dt( # 删除到小括号前
dgg # 删除到文件头部
dG # 删除到文件尾部
d} # 删除下一个段落
d{ # 删除上一个段落
Nd # 删除从当前行开始的 N 行
:Nd # 删除第 N 行
:1,10d # 删除 1-10 行
J # 将多行合并为一行
. # 重复上一次操作
~ # 替换大小写
g~iw # 替换当前单词的大小写
gUiw # 将单词转成大写
guiw # 将当前单词转成小写
guu # 全行转为小写
gUU # 全行转为大写
<< # 减少缩进
>> # 增加缩进
== # 自动缩进。当前文件所有行自动缩进对齐:gg=G
Ctrl+A # 增加数字
Ctrl+X # 减少数字
Vim查询
查询单词也是一个常用操作
- 使用
/
或者?
进行前向或者反向搜索 - 使用
n/N
跳转到下一个或者上一个匹配
next
- 使用
*
或者#
进行当前单词的前向和后向匹配
*
:在正则表达式中表示出现0次或多次。
/pattern # 从光标处向文件尾搜索 pattern
?pattern # 从光标处向文件头搜索 pattern
n # 向同一方向执行上一次搜索
N # 向相反方向执行上一次搜索
% # 匹配括号移动,包括 (),{},[]。结合以下两个命令对程序员来说是相当强大(前提:需要把光标先移到括号上)
* # 向下搜索光标所在的单词
# # 向前搜索光标所在的单词
f<char> # 向后搜索当前行第一个为 <char> 的字符,2fv 可以找到第二个 v 字符
F<char> # 向前搜索当前行第一个为 <char> 的字符
t<char> # 向后搜索当前行第一个为 <char> 的字符前
T<char> # 向前搜索当前行第一个为 <char> 的字符前
; # 重复上次的字符查找命令(f/t命令)
, # 反转方向查找上次的字符查找命令(f/t命令)
tx # 搜索当前行到指定 字符串 之前
fx # 搜索当前行到指定 字符串 之处
重复命令
. # 小数点,即重复(Dot)命令,重复执行上一次命令
N<command> # 重复某个命令 N 次,例如:10k,光标上移 10 行
命令行模式
搜索命令(如何搜索替换)
Vim替换命令
substitute命令允许我们查找并且替换掉文本,并且支持正则式
:[range]s(substitute)/{pattern}/{string}/[flags]
range
:表示范围。比如:10,20
表示10-20行,%
表示本文件中所有的行。pattern
:是要替换的模式,正则表达式string
:是替换后文本
注意:此命令不仅能用来替换,还能用来删除!如 删除所有星号*,命令为
:%s/\*//g
替换范围range
你可以在命令之前设置一个范围。以下是一些方法:
m, n
:表示范围为从第 m 行到第 n 行1,
:表示范围为从第 1 行到当前行
注意:第一行的行号是已知的,行号为 1;而最后一行的行号是未知的,所以我们只用给最后一行分配一个符号代表即可。
除了数字之外,还可以使用这些符号作为范围:
.
:表示当前行,可以省略。如.,3
表示当前行到第 3 行。$
:表示文件中的最后一行。如3,$
表示第 3 行到最后一行。+n
:表示当前行的后 n 行。3,+1
或者3,.+1
,.
可以用或不用,表示第 3 行到当前行后的 1 行。%
:表示本文件中所有的行。
在 Vim 中,
%
通常表示整个文件。
示例:
:1,5g/console/d
匹配第 1 行和第 5 行之间的字符串"console"并删除它们。:,5g/console/d
如果逗号之前没有地址,则从当前行开始。它在当前行和行 5 之间寻找字符串"console"并删除它们。:3,g/console/d
如果逗号后没有地址,则以当前行结束。它寻找第 3 行和当前行之间的字符串"console"并删除它们。:3g/console/d
如果仅传递一个没有逗号的地址,则它只执行第 3 行的命令。它查看第 3 行,如果字符串"console",它将删除它。
替换模式pattern
请参照正则表达式
替换标志位flag
Flags有几个常用的标志
- 默认为空,表示仅替换一行上的第一个匹配项
g
(global) 表示改变一行上的每个符合条件的匹配项,全局范围内执行
global
c
(confirm)表示确认 ,可以确认或者拒绝修改
confirm
n
(number)报告匹配到的次数而不替换,可以用来查询匹配次数
number:
:%s/xxx//gn
可以查询匹配次数
& Reuse the flags from the previous substitute command. Must be passed as the first flag.
g Replace all matches in the line.
c Ask for substitution confirmation.
e Prevent error message from displaying when substitution fails.
i Perform case insensitive substitution
I Perform case sensitive substitution
There are more flags that I do not list above. To read about all the flags, check out .:h s_flags
全局命令(如何对匹配行执行命令)
global命令实际上是分成两步执行:首先扫描[range]
指定范围内的所有行,给匹配{pattern}
的行打上标记;然后依次对打有标记的行执行{command}
命令,如果被标记的行在对之前匹配行的命令操作中被删除、移动或合并,则其标记自动消失,而不对该行执行{command}命令。{command}
可以是一个ex命令,也可以是用|
分隔的多个ex命令,这样我们就可以对被标记行,或从标记行寻址到的行进行多种不同的操作。
全局命令执行步骤:
- 扫描
[range]
指定范围内的所有行,给匹配{pattern}
的行打上标记; - 依次对打有标记的行执行
{command}
命令,如果被标记的行在对之前匹配行的命令操作中被删除、移动或合并,则其标记自动消失,而不对该行执行{command}命令。
全局命令(The Global Command)
Vim 的全局命令用于同时在多行上运行命令行命令。
特别注意:全局命令是对匹配的行,来进行行操作,操作对象是整个行,而不仅仅是匹配的那一部分字符。
全局命令具有以下语法:
:[range]g(global)/{pattern}/{command}
该模式匹配包含该模式的所有行,类似于 substitute 命令中的模式。该命令可以是任何命令行命令。
全局命令的工作方式是对匹配pattern
的每一行执行command
命令。
反向全局命令
要在不匹配的行上运行全局命令,可以运行:
-
:[range]g(global)!/{pattern}/{command}
-
或
:v/{pattern}/{command}
通过示例来学习
如果你有下列表达式:
const one = 1;
console.log("one: ", one);
const two = 2;
console.log("two: ", two);
const three = 3;
console.log("three: ", three);
要删除所有包含“控制台”的行,您可以运行::g/console/d
结果:
const one = 1;
const two = 2;
const three = 3;
如果使用反向全局命令,则它将删除所有不包含“console”的行
外部命令
在Unix系统内部,您会发现许多小型的,超专业化命令,每个命令只做一件事(而且能很好地完成)。您可以将这些命令链接在一起以共同解决一个复杂的问题。如果可以从Vim内部使用这些命令,那不是很好吗?
答案是肯定的!在本章中,您将学习如何扩展Vim以使其与外部命令无缝协作。
!
命令
Vim有一个!
命令,可以执行三件事:
1.将外部命令的STDOUT读入当前缓冲区。
2.将缓冲区的内容作为STDIN写入外部命令。
3.从Vim内部执行外部命令。
让我们一个个认真看一下。
将外部命令的标准输出STDOUT读入Vim
将外部命令的STDOUT读入当前缓冲区的语法为:
:r !{cmd}
:r
是Vim的读命令。如果不带!
使用它,则可以使用它来获取文件的内容。如果当前目录中有文件file1.txt
,运行:
:r file1.txt
Vim会将file1.txt
的内容放入当前缓冲区。
如果您运行的:r
命令后面跟一个!
和外部命令,则该命令的输出将插入到当前缓冲区中。要获取ls
命令的结果,请运行:
:r !ls
它返回类似下列的文本:
file1.txt
file2.txt
file3.txt
您可以从curl
命令读取数据:
:r !curl -s 'https://jsonplaceholder.typicode.com/todos/1'
r命令也接受一个地址:
:10r !cat file1.txt
现在,将在第10行之后插入来自运行cat file.txt
的STDOUT。
将缓冲区内容写入外部命令
:w
命令除了保存文件,还可以用来将当前缓冲区中的文本作为作为STDIN传递给外部命令。语法为:
:w !cmd
如果您具有以下表达式:
console.log("Hello Vim");
console.log("Vim is awesome");
确保在计算机中安装了node,然后运行:
:w !node
Vim将使用node
执行Javascript表达式来打印"Hello Vim"和"Vim is awesome"。
当使用:w
命令时,Vim使用当前缓冲区中的所有文本,与global命令类似(大多数命令行命令,如果不给它传递范围,则仅对当前行执行该命令)。如果您通过:w
来指定地址:
:2w !node
"Vim"只使用第二行中的文本到node
解释器中。
:w !node
和:w! node
形式上区别很小,但功能上相隔千里。使用:w !node
,您是将当前缓冲区中的文本"写入"到外部命令node
中。用:w! node
,则您将强制保存文件并将其命名为"node"。
执行外部命令
您可以使用bang命令从Vim内部执行外部命令。语法为:
:!cmd
要以长格式查看当前目录的内容,请运行:
:!ls -ls
要终止在PID 3456上运行的进程,可以运行:
:!kill -9 3456
您可以在不离开Vim的情况下运行任何外部命令,因此您可以专注于自己的任务。
编解码
- md5
- xxd
- base64
Java的.class字节码文件
注意:无论是字节码文件也好,二进制文件也罢,都不是给人类看的,编辑器逆向反编译不出来是合理的。
可以使用md5
来判断是否为同一个文件
使用vim不方便看,可以下载jar下来丢到vscode里看
配合xxd
查看并编辑二进制文件
用vim打开 test.bin,vim 的 -b 选项是告诉 vim 打开的是一个二进制文件,不指定的话,会在后面加上 0x0a ,即一个换行符。
vim -b test.bin
在命令模式下键入::%!xxd
-
这里的冒号
:
是进入 Vim 的 command-line mode,跟一般的 Vim 指令相同,例如存档(:w)等。 -
百分比符号
%
是指定 ex command-line ranges,代表整个文档,也就是说将整个文档内容都进行转换。 -
感叹号
!
是指定 filter commands,filter command 是一个可从标准输入读取资料,经过一些处理之后,输出至标准输出的外部指令,而这里我们使用 xxd 这一个打印 16 进制数据的命令作为 filter command。
如果 vim 后面没有加 -b 选项就会出现可恶的 0x0a:
如果有 -b 选项就不会有这种情况:
过滤文本
如果给!
范围,则可用于过滤文本。假设您有:
hello vim
hello vim
让我们使用tr
(translate)命令将当前行大写。运行:
:.!tr '[:lower:]' '[:upper:]'
结果:
HELLO VIM
hello vim
命令分解:
.!
在当前行执行filter命令。!tr '[:lower:]' '[:upper:]'
调用tr
外部命令将所有小写字符替换为大写字符。
必须传递范围以运行外部命令作为过滤器。如果您尝试在没有.
的情况下运行上述命令(:!tr '[:lower:]' '[:upper:]'
),则会看到错误。
假设您需要使用awk命令删除两行的第二列:
:%!awk "{print $1}"
结果:
hello
hello
命令分解:
:%!
在所有行(%
)上执行filter命令。awk "{print $1}"
仅打印匹配项的第一列。
您可以使用管道运算符(|
)链接多个命令,就像在终端中一样。假设您有一个包含这些美味早餐的文件:
name price
chocolate pancake 10
buttermilk pancake 9
blueberry pancake 12
如果您需要根据价格对它们进行排序,并且仅以均匀的间距显示菜单,则可以运行:
:%!awk 'NR > 1' | sort -nk 3 | column -t
结果:
buttermilk pancake 9
chocolate pancake 10
blueberry pancake 12
命令分解:
:%!
将过滤器应用于所有行(%
)。awk 'NR > 1'
仅从第二行开始显示文本。|
链接下一个命令。sort -nk 3
使用列3(k 3
)中的值对数字进行排序(n
)。column -t
以均匀的间距组织文本。
普通模式命令
在普通模式下,Vim有一个过滤运算符(!
)。如果您有以下问候:
hello vim
hola vim
bonjour vim
salve vim
要大写当前行和下面的行,可以运行:
!jtr '[a-z]' '[A-Z]'
命令分解:
!j
运行常规命令过滤器运算符(!
),目标是当前行及其下方的行。回想一下,因为它是普通模式运算符,所以适用语法规则"动词+名词"。tr '[a-z]' '[A-Z]'
将小写字母替换为大写字母。
filter normal命令仅适用于至少一行以上的motion或至少一行以上的文本对象。如果您尝试运行!iwtr'[az]''[AZ]'
(在内部单词上执行tr
),您会发现它在整个行上都应用了tr命令,而不是光标所在的单词。
vim如何编辑命令(如 粘贴一个命令)
问题速成解决方式
怎样在vim的命令行中拷贝,粘贴?
在vim的普通模式下,输入:
进入命令行模式,我们可以在屏幕下方输入我们想让vim执行的命令。
有时候,我们需要在命令行中执行拷贝粘贴,例如 我们想要查找替换正文中的特殊字符,但我们又不知道怎么在命令行中输入这个特殊字符。
查找还好说,不一定非要在命令行中输入这个特殊字符,只要把光标放在这个特殊字符上,按*
向下查找,按#
向上查找。
但是如果我们要替换这个特殊字符,就必须在命令行中输入它了,但是又不知道怎么输入这个特殊字符,怎么办?
答案是拷贝粘贴,先在正文中复制这个字符,然后粘贴在命令行中。
可是怎么在命令行中实现粘贴呢?别急,介绍一个好东西:命令行窗口。
在正常模式下,输入q:
,就打开了命令行窗口。
命令行窗口中都是我们输入过的命令,在这个窗口中我们可以像编辑正文一样编辑新的命令,或修改旧的命令。
因为像编辑普通缓冲区一样,自然可以拷贝粘贴了。
编辑完之后,在想要执行的命令上按回车,就ok了。
命令执行后,命令行窗口也自动关闭了。
命令行窗口
“历史记录”窗口显示以前使用的命令行命令的列表,但是不能从“历史记录”窗口执行该命令。若要在浏览时执行命令,请使用命令行窗口。有三个不同的命令行窗口:
q: Command-line window
q/ Forward search window
q? Backward search window
q(quick,快速的):
q:
:命令行命令编辑,可以看到所有使用过的命令的历史记录q/
:向前搜索命令编辑,可以看到所有使用过的向前搜索命令的历史记录q?
:向后搜索命令编辑,可以看到所有使用过的向后搜索命令的历史记录
运行 q:
以启动命令行命令的命令行窗口。Vim 将在屏幕底部启动一个新窗口。您可以使用 Up 或 Ctrl-p 键向上遍历,使用 Down 或 Ctrl-n 键向下遍历。如果按下回车,Vim 将执行该命令。若要退出命令行窗口,请按 Ctrl-c、 Ctrl-w c 或键入: quit。
类似地,要启动用于搜索的命令行窗口,可以运行向前搜索的 q/
和向后搜索的 q?
。
vim复制粘贴与寄存器的使用
Vim Normal模式复制粘贴
初学者会感觉Vim复制粘贴比较奇怪,先从normal模式学习
- normal模式下复制粘贴分别使用
y
(yank)和p
(put) ,剪贴d
(delete)和p
(put) - 我们可以使用
v
(visual)命令选中所要复制的地方,然后使用p
粘贴 - 配合文本对象:比如使用
yiw
复制一个单词,yy
复制一行
Vim里的剪贴(Cut)复制(copy)粘贴(paste)
分别是delete/yank/put
p # 粘贴到光标后
P # 粘贴到光标前
v # 进入可视模式
y # 复制标记内容
V # 可视模式按行标记
Ctrl+V # 可视模式按列标记
y$ # 复制当前位置到本行结束的内容
yy # 复制当前行 --> Yank (copy) a line
Y # 复制当前行,同 yy
yiw # 复制当前单词
Nyy # 复制光标下 N 行内容
ddp # 剪切当前行并粘贴(先删除当前行复制到寄存器,并粘贴)
v0 # 选中当前位置到行首
v$ # 选中当前位置到行末
viw # 选中当前单词
vib # 选中小括号内的内容
vi) # 选中小括号内的内容
vi] # 选中中括号内的内容
viB # 选中大括号内的内容
vi} # 选中大括号内的内容
vis # 选中句子中的内容
vab # 选中小括号内的内容(包含小括号本身)
va) # 选中小括号内的内容(包含小括号本身)
va] # 选中中括号内的内容(包含中括号本身)
vaB # 选中大括号内的内容(包含大括号本身)
va} # 选中大括号内的内容(包含大括号本身)
:set paste # 允许粘贴模式(避免粘贴时自动缩进影响格式)
:set nopaste # 禁止粘贴模式
"?yy # 复制当前行到寄存器 ? ,问号代表 0-9 的寄存器名称
"?d3j # 删除光标下三行内容,并放到寄存器 ? ,问号代表 0-9 的寄存器名称
"?p # 将寄存器 ? 的内容粘贴到光标后
"?P # 将寄存器 ? 的内容粘贴到光标前
:registers # 显示所有寄存器内容
:[range]y # 复制范围,比如 :20,30y 是复制 20 到 30 行,:10y 是复制第十行
:[range]d # 删除范围,比如 :20,30d 是删除 20 到 30 行,:10d 是删除第十行
"_[command] # 使用 [command] 删除内容,并且不进行复制(不会污染寄存器)
"*[command] # 使用 [command] 复制内容到系统剪贴板(需要 Vim 版本有 clipboard 支持)
Insert模式下的复制粘贴
很多人会使用鼠标进行选中,然后使用ctrl+v
或者cmd+v
粘贴
-
这个和其他的文本编辑器差不多,但是粘贴代码有个坑
-
很多人在vimrc中设置了autoindent ,粘贴Python代码缩进错乱
这个时候需要使用:set paste
和:set nopaste
解决 -
Ctrl-r {register}
:可以粘贴寄存器{register}中的内容。
系统剪贴板寄存器为
"+
什么是Vim的寄存器?
你有没有好奇? Vim在normal模式下复制/剪贴的内容去了哪?
- Vim里操作的是寄存器而不是系统剪贴板,这和其他编辑器不同
- 默认我们使用
d
删除或者y
复制的内容都放到了“无名寄存器” - 用
x
删除一个字符放到无名寄存器,然后p
粘贴,可以调换俩字符
深入寄存器(register)
Vim不使用单一剪贴板进行剪贴、复制与粘贴,而是多组寄存器
- 通过
"{register}
前缀可以指定寄存器,不指定默认用无名寄存器 - 比如使用
"ayiw
复制一个单词到寄存器a中,"bdd
删除当前行到
寄存器b中 - Vim中
""
表示无名寄存器,缺省使用。""p
其实就等同p
其他常见寄存器
除了有名寄存器a-z, Vim中还有一些其他常见寄存器
- 复制专用寄存器
"0
:使用y
复制文本同时会被拷到复制寄存器0 - 系统剪贴板
"+
:可以在复制前加上"+
复制到系统剪贴板 - 其他一些寄存器比如
"%
:当前文件名,".
:上次插入的文本
:set clipboard=unnamed
:可以让你直接复制粘贴系统剪贴板内容
强大的vim宏(macro)
从需求说起
从一个需求说起,给多行url链接加上双引号,你会怎么做呢?
什么是Vim宏(macro)
很多使用Vim很久的Vimer都没用过宏
- 宏可以看成是一系列命令的集合
- 我们可以使用宏「录制」一系列操作,然后用于「回放」
- 宏可以非常方便地把一系列命令用在多行文本上
如何使用宏
宏的使用分为录制和回放,是不是有种拍电影的感觉
- Vim使用
q{register}
来录制,同时也是q
结束录制
quick
- 使用
q{register}
选择要保存的寄存器,把录制的命令保存其中 - 使用
q
结束录制 - 使用
@{register}
回放寄存器中保存的一系列命令
用宏解决刚才的问题
现在你知道宏怎么用了,如何解决刚才的问题呢?
- 先给一行加上双引号,然后再回放到其他所有行
- 我们先使用
q{register}
开始录制,给一行加上双引号,之后使用q
退出 - 在剩下的所有行中回放录制的宏(使用可视模式选中,然后使用宏)
需要使用v可视模式选择所有url,再使用
:normal
在命令模式下使用normal模式下的命令。
不使用宏解决刚才的问题
可以通过可视模式选择所有url
可以使用:normal
,在命令模式使用normal模式的命令
:normal I"
:normal A"
vim补全大法
什么是补全?
只要手速快,补全什么的都是浮云
- 补全是根据当前环境上下文由编辑器“猜”你想输入的东西
- 比如补全一个单词、文件名,或者代码中的函数名、变量名等
- Vim中提供了多种补全功能,还可以由插件拓展功能实现代码补全
vim中常用的补全
Vim中有很多种补全的方式
命令 | 补全类型 |
---|---|
<C-n> |
普通关键字 |
<C-x><C-n> |
当前缓冲区关键字 |
<C-x><C-i> |
包含文件关键字 |
<C-x><C-]> |
标签文件关键字 |
<C-x><C-k> |
字典查找 |
<C-x><C-l> |
整行补全 |
<C-x><C-f> |
文件名补全 |
<C-x><C-o> |
全能(Omni)补全 |
常见的三种补全类型
记不住不用担心,根据笔者经验,最常用的就三种
- 使用
ctrl+n和ctrl+p
补全单词 - 使用
ctrl+x和ctrl+f
补全文件名 - 使用
ctrl+x和ctrl+o
补全代码,需要开启文件类型检查,安装插件
vim多文件操作
Buffer Window Tab
我们先来介绍几个多文件操作相关的概念
- Buffer是指打开的一个文件的内存缓冲区
- 窗口是Buffer可视化的分割区域
- Tab可以组织窗口为一个工作区
Buffer
Buffer-什么是缓冲区?
- Vim 打开一个文件后会加载文件内容到缓冲区
- 之后的修改都是针对内存中的缓冲区,并不会直接保存到文件
- 直到我们执行
:w
(write)的时候才会把修改内容写入到文件里
Buffer切换
那如何在buffer之间切换呢?
- 使用
:ls
会列举当前缓冲区,然后使用:b n
跳转到第n个缓冲区 :bpre
、:bnext
、:bfirst
、:blast
- 或者用
:b buffer_name
加上tab
补全来跳转
Window窗口
窗口是可视化的分割区域
- 一个缓冲区可以分割成多个窗口,每个窗口也可以打开不同缓冲区
<Ctrl+w>s
水平分割,<Ctrl+w>v
垂直分割。或者:sp
和:vs
- 每个窗口可以继续被无限分 割(看你屏幕是否够大)
分割窗口示例
窗口分割效果
如何切换窗口
切换窗口的命令都是使用Ctrl+w
(window)作为前缀
命令 | 用途 |
---|---|
<C-w>w |
在窗口间循环切换 |
<C-w>h |
切换到左边的窗口 |
<C-w>j |
切换到下边的窗口 |
<C-w>k |
切换到上边的窗口 |
<C-w>l |
切换到右边的窗口 |
如何重排窗口?
重排窗口可以改变窗口的大小:h window-resize查看文档
命令 | 用途 |
---|---|
<C-w>= |
使所有窗口等宽、等高 |
<C-w>_ |
最大化活动窗口的高度 |
<C-w>| |
最大化活动窗口的宽度 |
[N]<C-w>_ |
把活动窗口的高度设为[N]行 |
[N]<C-w>| |
把活动窗口的宽度设为[N]列 |
Tab(标签页)将窗口分组
Tab是可以容纳-系列窗口的容器(:h tabpage)
- Vim的Tab和其他编辑器不太一样,可以想象成Linux的虚拟桌面
- 比如一个Tab全用来编辑Python文件, 一个Tab全是HTML文件
- 相比窗口, Tab一般用的比较少, Tab太多管理起来也比较麻烦
Tab(标签页)操作
Tab使用不多,简单了解一下常用操作就好
命令 | 用途 |
---|---|
:tabe[edit] {filename} |
在新标签页中打开 |
<C-w>T |
把当前窗口移到一个新标签页 |
:tabc [close] |
关闭当前标签页及其中的所有窗口 |
:tabo [only] |
只保留活动标签页,关闭所有其他标签页 |
Tab(标签页)切换操作
如何切换不同的标签页,一般建立两个就好,太多不好操作
Ex命令 | 普通模式命令 | 用途 |
---|---|---|
:tabn[next] {N} |
{N}gt |
切换到编号为{N} 的标签页 |
:tabn[next] |
gt |
切换到下一标签页 |
:tabp[previous] |
gT |
切换到上一标签页 |
vim设置
设置文件行号:set nu
,取消文件行号:set nonu
设置高亮:syntax on
常用操作总结
u
:undo,撤销上次命令
ctrl + r
:redo,恢复撤销的命令
vim查看压缩文件
vim javaTest.jar
然后筛选压缩文件内的文件,按下回车,则可进入文件
笔者将不定期更新【考研或就业】的专业相关知识以及自身理解,希望大家能【关注】我。
如果觉得对您有用,请点击左下角的【点赞】按钮,给我一些鼓励,谢谢!
如果有更好的理解或建议,请在【评论】中写出,我会及时修改,谢谢啦!
本文来自博客园,作者:Nemo&
转载请注明原文链接:https://www.cnblogs.com/blknemo/p/14088271.html