2.4 文本编辑——vim编辑器
# 10. vim 操作
# 10.1 概括
- 四种模式:
- Normal Mode:普通模式不能直接添加内容,但可以通过指令来修改文件;
- Insert Mode:插入模式下可以直接键盘输入来添加字符,可以使用删除键删除内容;
- Visual Mode:可视模式下可以通过选择文本后进行操作;
- Commad Mode:命令模式下可以输入vim提供的更多指令或者自定义功能的命令;
- 模式切换(普通模式):
- 普通模式:按下
<ESC>
键会带您回到Normal Mode
,如果已经在正常模式可以撤消一个不想输入或部分完整的命令; - 插入模式:在
Normal Mode
按下i
立即原地进入插入模式——光标在原地; - 选择模式:在
Normal Mode
按下v
立即进入选择模式; - 命令模式:在
Normal Mode
按下:
立即进入命令模式;
- 普通模式:按下
- 移动光标(普通模式):
- h (左移)
- j (下行)
- k (上行)
- l (右移)
- 命令格式(普通模式):
- 命令格式
operator [number] motion
operator
:操作符,代表要做的事情,比如 d 代表删除[number]
:可以附加的数字,代表动作重复的次数motion
:动作,代表在所操作的文本上的移动,例如w
代表单词(word),$
代表行末等等
- 命令格式
- 退出编辑器:关闭当前分割窗口,如果当前窗口没有分割,则退出 VIM
:q
退出 VIM:w
保存当前文件:q!
放弃所有改动退出: wq
保存改动后退出
# 10.2 【N】命令格式
在vim 任何模式下按下<ESC>
键会带您回到正常模式,如果已经在正常模式可以撤消一个不想输入或部分完整的命令。在普通模式下可以通过一些神奇的指令来高校完成文本的跳转、修改、查找、替换,格式一般为:
operator [number] motion
# 10.2.1 Operator——操作符
操作符直接表达了谓词语义——接下来要干什么,常见有下面这些操作符:
操作符 | 用途 |
---|---|
c | 修改 |
d | 删除 |
y | 复制 |
g~ | 大小写反转 |
gu | 转为小写 |
gU | 转为大写 |
> | 向右缩进 |
< | 向佐缩进 |
= | 自动缩进 |
# 10.2.2 motion——动作命令
操作符是用来指定一个操作,我们知道操作对象肯定是文本,但具体文本文件中的哪些文本呢?比如是复制全文,还是复制一段,还是只复制一个单词,这些都可以通过motion来指定操作符具体的作用对象和范围,分为两类:
- 一类是文本对象, 比如 aw , ap
- 一类是位置范围, 比如 l ,j,k,f{char},$,^,0…
# ① 文本对象类型的动作命令
文本对象 | 操作范围 |
---|---|
aw | 光标所在单词加上一个空格 |
iw | 光标所在单词 |
ap | 光标所在段落 |
i< | <> 里面的文本 |
i{ | {} 里面的文本 |
i” | "" 里面的文本 |
例如:
daw
:删除一个单词及其之后的空格ya"
:复制引号及其之内的内容
# ② 位置范围类型的动作命令
那什么是位置范围呢?就是从当前光标开始,经过一次移动命令以后新的光标位置之间的文本,比如3j
,10<Space>
,3l
,f{char}
等等等等,只要可以移动光标的命令都可以
假设现在有这样一行文本
I am a Vimer
我们要将Vimer
这个单词e
之前的文本全部转为大写
0 //移动到行首
gUte //(操作符 (gU)+(新的光标位置 te))
2
最后得到:
I AM A VIMer
operator*2
当一个操作符当被连续两次调用的时候,对应的作用范围就是当前行,比如dd
就是删除当前行,yy
就是复制当前行,gUgU
就是将当前行转为大写
# 10.3 【N】移动/跳转
在普通模式下除了通过方向控制光标移动,还有更丰富的跳转方式:
# ① 四大方向:
- h (左移)
- j (下行)
- k (上行)
- l (右移)
# ② 单词移动:
- 词首:
- w(向后移动一个单词)
- b(向前移动一个单词)
- 词尾:
- e(向后移动一个单词)
示例:
- 输入 2w 使光标向前移动两个单词。
- 输入 3e 使光标向前移动到第三个单词的末尾
# ③ 字符移动:
- 字符前:
- 通过使用
f/F + 字符
来移动到特定的字符前面 - f(向右移动一个字符)
- F(向左移动一个字符)
- 通过使用
- 字符后:
- 通过使用
t/T + 字符
来移动到特定的字符后面 - t(向右移动一个字符)
- T(向左移动一个字符)
- 通过使用
# ④ 行文首尾:
行内跳转
- 行首:
0
或者^
- 行尾:
$
- 行首:
跨行跳转:
- 第一行:
gg
- 最后行:
G
- 某一行:
nG=ngg
n代表要跳转的行号
- 第一行:
组合:可以通过连续的方向和行内跳转实现更精细的跳转:
j$
:移动光标到下一行的末尾
# ⑤ 其他
- CTRL-O 带您跳转回较旧的位置,CTRL-I 则带您到较新的位置。
- 还可以通过正则搜索的方式来移动
- 使用标记来移动,m + {a-z}标记位置(适用于单个文件,如果是多个文件,使用大写字母{A-Z}),``{mark}移动到标记位置的列,'{mark}移动到标记位置的行首,还有一些特殊的标记,'`表示跳转前光标的位置
- 输入 CTRL-W 可以在窗口之间跳转在窗口之间跳转 Ctrl + w + h 表示光标移动到左边的分割窗口 Ctrl + w + l 表示光标移动到右边的分割窗口 Ctrl + w + j 表示光标移动到下面的分割窗口 Ctrl + w + k 表示光标移动到上边的分割窗口
- :e filename 可以编辑磁盘文件
# 10.4 【N】复制/剪贴
# ① 删除
x删除字符
df + 字符删除从当前字符到指定字符
dw/daw删除单词
d$ / D 删除从当前光标到行尾
dd删除一行
de 从当前光标当前位置直到单词末尾,包括最后一个字符
d0:从当前光标位置(不包括光标位置)剪切之行首
d3l:从光标位置(包括光标位置)向右剪切3个字符
d5G:将当前行(包括当前行)至第5行(不包括它)剪切
d3B:从当前光标位置(不包括光标位置)反向剪切3个单词
dH:剪切从当前行至所显示屏幕顶行的全部行
dM:剪切从当前行至命令M所指定行的全部行
dL:剪切从当前行至所显示屏幕底的全部行
v 进入块模式,选中字符,然后 (”+y)(不包括括号,但是包括 + 号) 其中 “+ 是系统剪贴板的名称,y表示复制内容到系统剪贴板,当然,在系统中复制的内容如果想要粘帖到 VIM ,可以在命令模式下输入(”+p) ,“+ 表示系统剪贴板,p 表示粘帖
# ② 复制
- yw复制单词
- yf复制从当前字符到指定字符
- y$复制当前光标到行尾
- yy复制整行
- nyy:n表示大于1的数字,复制n行
- yw:从光标处复制至一个单子/单词的末尾,包括空格
- ye:从光标处复制至一个单子/单词的末尾,不包括空格
- y0:从当前光标位置(不包括光标位置)复制之行首
- y3l:从光标位置(包括光标位置)向右复制3个字符
- y5G:将当前行(包括当前行)至第5行(不包括它)复制
- y3B:从当前光标位置(不包括光标位置)反向复制3个单词
# ③ 粘贴
dd + p:delete一行,然后放在当前光标下方
dd + P:delete一行,然后放在当前光标上方
dw + p:delete单词,然后放在当前光标后面
dw + P:delete单词,然后放在当前光标前面
p/P可接受计数前缀,重复粘贴
# 10.5 【N】高级需求
# 10.5.1 替换
在Vim
普通模式中,如果你想键入一段新的文本来替代原有的文本,那么R
和r
这两个命令你是不可不知的
命令 | 作用 |
---|---|
R | 从光标处开始替换文本直到按下<ESC> |
r | 替换当前的一个字符 |
EG:
> 要将一行中的`Vimer`改为`loser`,我们可以这样来改
> 0(移动到句首)
> fV(移动到`Vimer`词首)
> Rlos(将`Vim`改为`los`)
2
3
4
注意:
- 我们在使用替换的时候,
Vim
是将占有多个空格宽度的制表符当做是一个替换字符,- 于是我们在进行替换时就会有各种不希望出现的缩进,不对齐。
- 为了避免这种情况,我们可以使用
gR
或者gr
命令来进行替换操作,- 在
gR
和gr
替换中,Vim
会将制表符当做一组空格来处理,- 具体的空格数要由制表符占用的空格宽度决定, 这种替换成为虚拟替换模式。
# 10.5.2 修改
更改类命令的格式是:
- v 进入块模式,选中字符,
- 然后 (”+y)(不包括括号,但是包括 + 号)
- 其中 “+ 是系统剪贴板的名称,y表示复制内容到系统剪贴板,
- 当然,在系统中复制的内容如果想要粘帖到 VIM ,可以在命令模式下输入(”+p) ,“+ 表示系统剪贴板,p 表示粘帖
r
:更改当前的字符R
:更改多个字符,进入替换模式c [number] motion
cf<char>
:更改从当前字符到指定字符c$
:更改从当前字符到行尾cc
:更改整行ce
:可以替换当前光标到单词的末尾的内容cw/caw/ciw
:更改单词ci"
:修改引号里的内容在一行内替换头一个字符串 old 为新的字符串 new,请输入 😒/old/new
在一行内替换所有的字符串 old 为新的字符串 new,请输入 😒/old/new/g
在两行内替换所有的字符串 old 为新的字符串 new,请输入 :#,#s/old/new/g
在文件内替换所有的字符串 old 为新的字符串 new,请输入 :%s/old/new/g
进行全文替换时询问用户确认每个替换需添加 c 标志 :%s/old/new/gc
合并
J
:合并当前行和下一行(去除当前行和下一行之间的空格)
# 10.5.3 查找
- CTRL-G 用于显示当前光标所在位置和文件状态信息。
- 输入 / 然后紧随一个字符串是在当前所编辑的文档中正向查找该字符串。
- 输入 ? 然后紧随一个字符串则是在当前所编辑的文档中反向查找该字符串。
- 完成一次查找之后按 n 键是重复上一次的命令,可在同一方向上查
- 找下一个匹配字符串所在;或者按大写 N 向相反方向查找下一匹配字符串所在。
- 按up/down可以浏览搜索历史
- 如果光标当前位置是括号(、)、[、]、{、},按 % 会将光标移动到配对的括号上
- 查找光标所在处的单词
# 10.5.4 撤销和回复
欲撤消以前的操作,请输入:u (小写的u) 欲撤消在一行中所做的改动,请输入:U (大写的U) 欲撤消以前的撤消命令,恢复以前的操作结果,请输入:CTRL-R
恢复文件 vi在编辑某一个文件时,会生成一个临时文件,这个文件以 . 开头并以 .swp结尾。正常退出该文件自动删除,如果意外退出例如忽然断电,该文件不会删除,我们在下次编辑时可以选择一下命令处理:
O只读打开,不改变文件内容 E继续编辑文件,不恢复.swp文件保存的内容 R将恢复上次编辑以后未保存文件内容 Q退出vi D删除.swp文件 或者使用vi -r 文件名来恢复未保存的内容
# 10.5.5 数值运算
<C-a>
:对数字进行加操作<C-x>
:对数字进行减操作
<C-a>
命令会把当前光标之上或者之上的数加 1,如果需要加多次,可以[count]<C-a>
, 这样就会使数值加上count
现有一段文本:
I am 23 years old
现在需要将23
改为24
, 如果现在你不知道这个技巧,那就只有
> `f3`(移动到`3`)
> `r4`(将`3`改为`4`)
2
未免太繁琐了 现在我们只需要
<Ctrl-a>
(光标立马跳转到23
上,并将数值加1
,变为24
)
要是现在需将23
改为1023
(千年老妖了)
只需要
1000<Ctrl-a>
同理可得<C-x>
# 10.5.6 重复操作
- https://blog.csdn.net/ii1245712564/article/details/46496347
- 当我们用
vim
编辑文本的时候,不免会进行一些重复的操作,当我们想要重复上次的操作,难道还要重复一遍相同的操作么?这样不免会浪费时间。- 于是
vim
就将你上次进行的一些操作记录在vim
的寄存器里,当你想要重复上次进行的操作的时候,直接点击快捷键就可以了。
# ① Vim重复的类型
vim 中有五种基本的重复类型,分别是:
重复类型 | 重复操作符 | 回退操作符 |
---|---|---|
文本改变重复 | . | u |
行内查找重复 | ; | , |
全文查找重复 | n | N |
文本替换重复 | & | u |
宏重复 | @[寄存器] |
下面我们来见详细介绍这几种重复操作
# ② 文本改变重复
通过
: h .
来查看 vim 的帮助手册:
.
Repeat last change, with count replaced with [count]. Also repeat a yank command, when the ‘y’ flag is included in ‘cpoptions’. Does not repeat a command-line command.
可见.
操作就是用来重复上一次更改的
举几个栗子:
example1: 用
x
操作来删除一个字符,接着用.
重复删除字符
example2: 用
dd
删除一行数据,然后用.
重复删除一行数据
example3: 用
yy
复制一行数据,p
进行粘贴,点击.
来重复粘贴操作
# ③ 行内查找重复
有时候我们想要在当前行内查找一个字符,我们可以通过f{char}/t{char}
来从当前位置开始到行尾进行查找,也可以通过F{char}/T{char}
从当前位置开始到行首进行查找。简单的说就是小写向后找,大写向前找。
通过
: h ;
来查看 vim 的帮助手册:
;
Repeat latest f, t, F or T [count] times. See cpo-;
,
Repeat latest f, t, F or T in opposite direction [count] times. See also cpo-;
可见我们可以用;
来重复 vim 查找的操作,,
重复反向找的操作
举几个栗子:
example1: 在文件
main.cc
的 31 行里面首先用f:
来查找:
字符,之后用;
来重复查找操作
example2: 我们将前文讲到的更改操作重复和行内查找操作重复结合在一起,在文件
main.cc
的 31 行里面首先用f+:
来查找:
字符,然后cl
将:
字符替换为+
字符,之后重复的键入;.
来将剩下的:
替换为+
# ④ 全文查找重复
通过
:h /
来查看vim
的帮助手册:
/{pattern}[/]<CR>
Search forward for the [count]’th occurrence of {pattern} exclusive.?{pattern}[?]<CR>
Search backward for the [count]’th previous occurrence of {pattern} exclusive.
在vim
里面通过/pattern<CR>
来从当前位置开始在全文中向下查找匹配项,或者?pattern<CR>
来从当前位置开始在全文中向上查找匹配项
通过
:h n
来查看vim
的帮助手册:
n
Repeat the latest “/” or “?” [count] times. last-pattern {Vi: no count}N
Repeat the latest “/” or “?” [count] times in opposite direction. last-pattern {Vi: no count}
在查找完毕以后,我们可以用n
跳转到下一个匹配项,N
跳转到上一个匹配项
举个栗子: 在
main.cc
里面查找suite
,并用gUaw
将单词转为大写,之后重复n.
操作将全部转为大写
# ⑤ 文本重复替换
通过
:h &
来查看vim
的帮助手册:
&
Synonym for 😒 (repeat last substitute). Note that the flags are not remembered, thus it might actually work differently. You can use :&& to keep the flags.
一般来说,我们可以采用这样的形式:s/target/replacement/g
来将行内出现的字符串target
替换为另外一个字符串replacement
, 要是我们想在其他行执行相同的替换工作,可以用&
来重复替换操作
举个栗子: 将
main.cc
文件 31 行内的::
字符串采用下面的形式替换为+-+
:s/::/+-+/g
, 之后用重复j&
操作替换下面的两行
# ⑥ 宏录制重复
通过
:h @
来查看vim
的帮助手册:
@{0-9a-z".=*+}
Execute the contents of register {0-9a-z”.=*+} [count] times. Note that register ‘%’ (name of the current file) and ‘#’ (name of the alternate file) cannot be used.
vim
里面宏录制是一个非常 NB 的功能,你可以录制一系列的操作到寄存器里面,之后直接@{寄存器}
就可以重复之前录制的一系列操作
vim
里面可以用q{寄存器}
开始进行录制,之后用q
来结束录制, 寄存器的名字a-z
中的任意一个,比如qa
就是将操作录制到寄存器a
中,之后如果想要使用该宏,使用@a
就可以重复录制的操作
举几个栗子:
example1: 将当前行的
::
替换为+-+
,然后删除行尾的;
号,并将文本向右缩进一行
example2: 在内容为
this is number1
进行复制,然后粘贴到下一行,并将数字1
增加为2
, 内容变为this is number2
, 以此重复十次,所以最后一行的内容应为this is number12
这里用到了
vim
里面的一个冷知识,那就是Ctrl+a
, 该操作会从光标开始,向后查找离光标最近的数字,如果找到就将数字的值加 1,同理Ctrl+x
就是将数字减 1,于是我们录制了这样的一个宏操作qa
,yy
,p
,ctrl+a
,q
, 然后10@a
将这个宏重复十次就成了上面的效果啦
# 10.6 【i】插入模式
# ① 进入插入模式
按键 | 功能 |
---|---|
a | 在光标后面进行插入 |
A | 在当前光标所在行末尾插入 |
i | 从光标所在出插入 |
I | 在当前光标所在行首插入 |
o | 在当前行下面新建一行,并进行插入 |
O | 在当前行上面新建一行,并进行插入 |
# ② 插入-更正
按键操作 | 作用 |
---|---|
<C-h> (Backspace ) | 删除前一个字符 |
<C-w> | 删除前一个单词 |
<C-u> | 删至行首 |
使用上面的快捷键就可以不用回到普通模式也可以快速的更改数据了
# ③ 插入 -普通模式
在插入模式的某些情况下我们只是想执行普通模式下面的一条命令,然后继续输入数据,我们可以用
<C-o>
来回到普通模式,在执行完一条命令以后,马上就会返回到插入模式。
比如你在编辑文本的时候需要将正在编辑的该行文本居中 (zz
) 或者是置顶 (zt
),你就可以<C-o>zz
就可以啦。
# ④ 插入-寄存器
首先,我们需要知道什么是Vim
寄存器,Vim
的寄存器顾名思义就是用来寄存一些特定的数据或者是用户自定义的数据,在我们需要的时候直接访问寄存器即可, 在Vim
里面输入:reg
来查看寄存器中存放的内容
可以看到各种各样的寄存器,如需了解Vim
寄存器,请看这里 vim 寄存器使用详解 (opens new window)
- 比如其中比较经常用到的数字寄存器
"[0-9]
, Vim
将复制的数据保存到寄存器"0
中,- 将删除的最新数据保存到
"1
中, - 旧的删除的数据将从前一个寄存器中移动到下一个寄存器中,
- 比如当删除新的数据的时候时候,寄存器
"1
的数据将会转移到寄存器"2
中,"2
的转移到"3
中,以此类推,最后将新的删除数据保存到"1
中。
有些时候我们想粘贴之前就删除的数据(不是最新删除的数据),这时候使用p
明显是不行的了,因为p
只粘贴最新的删除或者复制的数据,那么之前删除的数据就消失了么?其实不然,Vim
将会为我们保存九次删除操作的数据:
只要在插入模式下键入
<C-r>{register}
就可以粘贴register
中的数据了,在普通模式下为
"{register}p
EG:
> 我们有下面的文本
> 查看一下寄存器中的东西
> 我们要粘贴寄存器`"8`的数据,`<C-r>8`
2
3
注意:
- 使用
<C-r>{register}
粘贴的数据将会保留原有数据的缩进格式,- 如果你设置了
testwidth
或者是autoindent
,- 那么就有可能出现不必要的缩进。这时你就需要采用
<C-r><C-p>{register}
来单纯的插入数据,没有任何的缩进
# ⑤ 插入-数值运算
如果我们在插入模式中需要进行一些简单的运算,我们可以直接使用表达式寄存器"=
来计算我们的表达式,并插入结果,具体用法为<C-r>={expression}<CR>
, 其中expression
是我们需要计算的式子,比如1+2
,10*6
…
# ⑥ 插入-字符编码
只要我们知道某个字符的编码,Vim
就可以直接插入这个字符,我们只用在插入模式中输入<C-v>{code}
就可以插入code
对应的字符, 比如<C-v>065
就可以插入大写字母'A'
反之,如果你想知道某个字符的编码,你可以将光标移到该字符上,然后输入ga
,屏幕下方就会显示该字符的编码了
# 10.7 【V】可视模式
可视模式简单来说就是选中一块编辑区域,然后在上面执行一些操作,比如删除,替换,改变大小写等。
# 选择区域
在Vim
里面有三种激活可视模式,并选择一块区域的方法,他们分别是:
模式类型 | 激活方式 | 选择效果 |
---|---|---|
字符文本 | v (小写) | 逐个字符选择文本 |
行文本 | V (大写) | 逐行选择文本 |
块文本 | <C-v> | 按照块的方式选择文本 |
这上面说的什么
字符文本
,行文本
,块文本
指的是什么意思啊?- 其实就是一种控制选择粒度的方案,
字符文本
的选择粒度是一个字符,行文本
的选择粒度是一行文本,如果你想只选中一行里面的几个连续字符,那么使用字符文本
就不太适合了,因为行文本
的选择粒度是以行为最小单位的,每次最少都要选中一行内容,- 如果你想选中多行文本,那么使用
字符文本
明显是不合适的,因为太低效了。 - 而
块文本
就是功能最强大的选择模式了,它可以完全无视行的存在,可以在文本中按照需要的区域自由选择。
跳转:
- 我们在
普通模式
博客中已经介绍了许多快速移动光标的命令,比如h
,j
,k
,l
, 可以在四个方向移动光标, - 也可以用
f{char}
来跳转到某个字符上面,之后再用;,
来重复跳转, - 或者用查找命令
/target
来进行光标的快速移动,再用n/N
进行重复, - 还有许多这样的移动光标的命令,幸运的是,在可视模式下面,这些快速移动光标的命令我们都可以用
- 我们在
端点:
- 大家有没有发现在使用可视模式的时候,一旦切换到可视模式以后,选中的区域是由两个端点来界定的(一个在左上角,一个在右下角),
- 我们在默认情况下只可以控制右下角的端点,但是有些时候发现我们需要调整左上角的端点,这时我们可以使用
o
按键来在左上角和右下角之间进行切换。
重选:
- 我们可以使用
gv
命令来重新选中之前可视模式选中的目标区域, - 但是如果之前的选中的区域文本被删除,那么
gv
命令就会表现的有点神经了 - (
Vim
底层的实现可能是记住目标区域的起始行和行数
和起始列和列数
,键入gv
以后就根据之前保存行列信息进行还原)
- 我们可以使用
切换:
- 可视模式有一个好处就是我们可以在三种选择模式之间进行随意的切换,
- 比如在
行文本
模式下面希望进行更加细粒度的选择,我们可以直接按v
切换到字符模式
, - 同理可以得到在某一选择模式中切换到任意其他两种模式的方法。博主不再这里赘述
# 选中操作
我们选中一块区域,最直接的目的就是对这块区域进行操作,比如删除,调换大小写,改变文本等等。那么要如何对选中的区域进行操作呢?在文章的上一节中我们提到可以在可视模式
中使用普通模式
的跳转命令,没错,在可视模式
中也可以使用普通模式
模式下的修改命令。
命令 | 命令效果 |
---|---|
d | 删除选中文本 |
c | 修改选中文本 |
r | 替换选中文本 |
I | 在选中文本前插入 |
A | 在选中文本后插入 |
gu | 选中区域转为小写 |
gU | 选中区域转为大写 |
g~ | 大小写互调 |
> | 向右缩进一个单位 |
< | 向左缩进一个单位 |
比较常用的就是上面的几个。
下面我们来举几个栗子:
栗子一: 假设现在我们有下面一个 C++ 文件
main
函数的头三行代码忘了加;
号了,现在我们要用可视模式为这三行代码加上分号首先
<C-v>
开启块选择模式,然后点击jj$
号选择到行末尾,再用
A
在选中的区域后面添加文本;
, 虽然在编辑的过程中只有一行文本看上去添加了分号,但是只用按下
<Esc>
, 剩下的其余选中行也会自动添加分号,这里与其他编辑器稍有不同,新手应注意
栗子二: 下面是一个打开四个文件标识符的栗子
如果我们已经将四个文件
file1
,file2
,file3
,file4
移动到了新的目录/tmp/fileDir
里面,于是我们要将testDir
目录改为fileDir
目录
<C-v>
进入块选择
模式,并选中testDir
区域,如下图点击
c
对选中区域进行替换,并输入fileDir
跟之前的栗子一样,只有一行文本发生改变,点击
<Esc>
使改变作用于全部选中区域
# 可视命令的重复
说到重复,首先想到的肯定是.
命令啦,可是这个重复命令可不一般,首先来看几个栗子:
字符文本模式栗子:
首先在
字符文本
模式下选中27
行的open
单词,并用g~
命令来将open
转为大写注意这里我们选中的是四个字符,之后我们将光标向右移动几位,移动到单词
fileDir
的开头,我们点击.
重复上一个可视命令得到下面的结果:
我们惊奇的发现
OPEN
并没有转为预期的转为小写,而是fileDir
的前四个字符变成了大写
行文本模式栗子:
用
V
将27
行选中,并用g~
进行大小写转换现在跳转到
31
行,单击.
重复命令发现
31
行的全部文本全都进行大小写互换
块文本模式栗子:
点击
<C-v>
进入块文本
选择模式,随便选中一块区域,如下图
g~
进行大小写互换现在我们将光标下移一行,并将光标移到图示位置
此时点击
.
,我们发现从光标开始的右下角的一个矩形范围被调换了大小写,该矩形范围的大小与上次可视模式选中的区域大小一样
总结了一下,不同的选择模式有不同的重复效果
选择模式 | 重复效果 |
---|---|
字符文本选择模式 (Visual ) | 从当前光标开始,作用范围是上次操作的字符数 |
行文本选择模式 (Visual line ) | 从当前行开始,作用范围是上次操作的行数 |
块文本选择模式 (Visual Block ) | 从当前光标开始,作用范围是以当前光标为左上端点的上次操作的块范围 |
# Why Not
为什么这么讲呢?比如在字符文本
选择模式里面,如果我们要进行重复,那么重复的范围是通过上一次操作的字符数决定的,其中与上一次操作相同的字符数
就是一个很大的限制条件,必须这次操作的字符数与上次操作的字符数相同我们才可以放心的使用重复操作。
举个栗子:
我们要将
27-29
的printf
打印的内容全都转为大写在
27
行,我们采用vi"
选中引号内的东西,U
将选中的内容转化为大写如果我们下移一行,用
.
重复上次操作,得到发现只作用了前两个字符,后面的
llo
还是小写
不能重复上次的操作,难道还需要手动再来一遍?其实并不需要,我们只用使用普通模式
下面的操作符命令就可以啦
上面的栗子我们可以用操作符命令更好的实现需求
使用
gUi"
,将"
内的内容转化为大写,然后j.
就可以重复上一行的操作啦
# 10.8 【C】命令模式
:!command 用于执行一个外部命令 command。
请看一些实际例子: (MS-DOS) (Unix) :!dir :!ls - 用于显示当前目录的内容。 :!del FILENAME :!rm FILENAME - 用于删除名为 FILENAME 的文件。
:w FILENAME 可将当前 VIM 中正在编辑的文件保存到名为 FILENAME 的文 件中。
v motion :w FILENAME 可将当前编辑文件中可视模式下选中的内容保存到文件 FILENAME 中。
:r FILENAME 可提取磁盘文件 FILENAME 并将其插入到当前文件的光标位置 后面。
:r !dir 可以读取 dir 命令的输出并将其放置到当前文件的光标位置后面。
:version :显示的VIMRC目录
:scriptnames :显示vim启动后加载的所有script
:function :查看加载的所有function
# 其它
- 输入 :set xxx 可以设置 xxx 选项。一些有用的选项如下: 'ic' 'ignorecase' 查找时忽略字母大小写 'is' 'incsearch' 查找短语时显示部分匹配 'hls' 'hlsearch' 高亮显示所有的匹配短语 选项名可以用完整版本,也可以用缩略版本
- 在选项前加上 no 可以关闭选项: :set noic
- 可以创建一个 vimrc 启动脚本文件用来保存您偏好的设置
- 数字+action表示执行某个操作多少次
输入 d2w删除两个单词 输入3x删除从当前光标开始,向后3个字符
.
重复上一个操作- 补全
当输入 : 命令时,按 CTRL-D 可以查看可能的补全结果。
按
可以使用一个补全。 它对于 :help 命令非常有用。 - 宏录制 q + 寄存器(a-z)开始录制 录制动作 q停止录制
# help
- 输入 :help 或者按
键或 键可以打开帮助窗口。 - 输入 :help cmd 可以找到关于 cmd 命令的帮助。
- vimtutor 是一份入门文档,在终端直接输入 vimtutor 即可打开,这个文档在网上可以找到中文版。
- 另外,在 vim 中输入 :help 可以查看帮助文档,如果实在看不惯英文,也可以切换成中文的。 首先执行如下命令下载 vimcdoc-1.8.0.tar.gz: $ wget http://nchc.dl.sourceforge.net/sourceforge/vimcdoc/ (vimcdoc-1.8.0.tar.gz)(or later) 然后解压 vimcdoc-1.8.0.tar.gz,进入 vimcdoc-1.8.0 目录可以找到 doc 目录,将 doc 中的全部文件复制到 ~/.vim/doc/ 目录。 重新进入 vim,输入 :help 可以看到帮助文档变成中文了。 如果无法显示中文,在 ~/.vimrc 中添加:
set helplang=cn
set encoding=utf-8
2
# 10.9 窗口管理
window之间切换可以使用Ctrl + w + h/j/k/l(向左、下、上、右切换)或者Ctrl + w + w(在窗口间切换)
vim水平分屏的使用 :vim -on file1 file2 ...其中: o(是小写字母o,不是数字零)n(表示你要分屏的文件个数) filen(文件名多个文件用空格分开)
两个文件做测试想到上面那个文件用:ctrl + w + k 到下面的文件用:ctrl + w + j 懒的话可以用:ctrl + w + w 在水平分屏好的文件中在打开别的文件:sp filename
vim垂直分屏:vim -On file1 file2 .....
其中:
O(是大写字母O,不是数字零)n(表示你要分屏的文件个数)
filen(文件名多个文件用空格分开)
想到左面那个文件用:ctrl + w + h 想到右面的文件用:ctrl + w + l 最后要说明的是在单个文件可以进行的操作都可以在分屏文件里面进行操作
在垂直分屏好的文件中在打开别的文件:vsp filename
# 一、如果在终端中开没有打开vim,可以:
横向分割显示: $ vim -o filename1 filename2 纵向分割显示: $ vim -O filename1 filename2
# 二、如果已经用vim打开了一个文件,想要在窗口中同时再打开另一个文件:
横向分割显示: :vs filename 纵向分割显示: :sp filename 其中,vs可以用vsplit替换,sp可以用split替换。 如果finename不存在,则会新建该文件并打开。
分割窗口的选项
:[n] split(vsplit) [++opt] [+cmd] [file]
命令中: n 为vim指定在新窗口中显示的行数,且新窗口的大小刚好容纳该行数,新窗口位于画面顶端 opt 传递vim选项信息给新的窗口会话(请注意,它的前面必须加上两个加号) cmd 传入欲在新窗口中执行的命令(请注意,它的前面必须加上一个加号) file 指定在新窗口中编辑的文件
:sview filename 以只读的方式水平分割打开一个新窗口 :sfind [++opt] [+cmd] [file] 和split的运作方式相似,但在path中寻找filename,如果vim未找到文件则不显示
# 三、关闭窗口
关闭光标所在的窗口: :q 或 :close
关闭除光标所在的窗口之外的其他窗口: :only
关闭所有窗口: :qa
# 四、切换窗口
ctrl + F6: 打开了多个窗口,需要在窗口之间切换时: ctrl + w w 即按住ctrl键,再按两下w键。 或者ctrl + w 即按住ctrl键,按一次w键,再按一次表示方向的h或j或k或l,则光标会切换到当前窗口的 左|下|上|右 侧的窗口
文件间切换 Ctrl+6 下一个文件 :bn :下一个文件 :bp : 上一个文件
在窗口间游走
在gvim或vim中,在窗口中移动其实非常简单,因为gvim已默认支持鼠标点击来换编辑窗口,而vim中,则可以打开mouse选项, :set mouse = a 为命令、输入、导航都激活鼠标的使用
我们知道vim的特色就是可以脱离鼠标而工作,所以可以使用vim提供的全套导航命令,在会话中快速而准确的移动编辑窗口。
Ctrl + w + h:向左移动窗口 Ctrl + w + j: 向下移动窗口 Ctrl + w + j: 向上移动窗口 Ctrl + w + l: 向右移动窗口
Ctrl + w + w:这个命令会在所有窗口中循环移动 Ctrl + w + t:移动到最左上角的窗口 Ctrl + w + b:移动到最右下角的窗口 Ctrl + w + p:移动到前一个访问的窗口
# 五、移动窗口
vim中有两种移动窗口方式,一种只是简单地在屏幕上切换窗口,尺寸维持不变;另一种则是改变窗口的实际布局,还会调整尺寸,以填充它移动的位置。
- 移动窗口本身(轮换或交换)
Ctrl + w + r:向右或向下方交换窗口,而Ctrl + w + R则和它方向相反。
光标会随着窗口而移动
Ctrl + w + x:交换同列或同行的窗口的位置。vim默认交换当前窗口的与它下一个窗口的位置,如果下方没有窗口,则试着与上一个窗口交换位置。亦可在此命令前加上数量,与制定的窗口交换位置。
- 移动窗口并改变其布局
注:下面的第三个字母都是大写,按玩Ctrl + w之后,按shif + 相应的字母。后面用^代替Ctrl Ctrl + w + K :移动当前窗口至屏幕顶端,并占用全部宽度 ^WJ: 移动窗口至屏幕底端,并占用全部宽度 ^WH:移动窗口至屏幕左端,并占用全部高度 ^WL:移动窗口至屏幕右端,并占用全部高度
^WT :移动窗口至屏新的现有分页
# 六、调整窗口尺寸
改变当前窗口的尺寸,同时当然也会影响到其他窗口。 在gvim和vim中,可以用鼠标点击窗口的顶部白色条并窗口直接调整尺寸。
也可以直接用命令,调整尺寸命令也是以Ctrl + W开头: Ctrl + W + = :让所有窗口调整至相同尺寸(平均划分) Ctrl + W + -:将当前窗口的高度减少一行,也可在ex命令中,:resize -4明确指定减少的尺寸 Ctrl + W + +:将当前窗口的高度增加一行。同样在ex命令中,:resize +n 明确指定增加尺寸
Ctrl + W + < :将当前窗口的宽度减少 Ctrl + W + > :将当前窗口的宽度增加
Ctrl + W + |:将当前窗口的宽度调到最大,也可他哦你通过ex命令:vertical resize n明确指定改变宽度
# 七、vim 临时退出
方法一:使用 Ctrl-z 以及
fg
这两个命令组合。- 描述:这一解决方法主要利用了 Linux/Unix 的作业机制。
- 原理:
- Ctrl-z 命令将当前的 Vi/Vim 进程放到后台执行,之后 shell 环境即可为你所用;
- fg 命令则将位于后台的 Vi/Vim 进程放到前台执行,
- 这样我们就再次进入 Vi/Vim 操作界面并恢复到原先的编辑状态。
方法二:使用行命令
:sh
。- 操作:
- 在 Vi/Vim 的正常模式下输入 :sh即可进入 Linux/Unix shell 环境。
- 在要返回到 Vi/Vim 编辑环境时,输入 exit 命令即可。
- 操作:
这两种方法实现机制不一样,但效果一样,都非常快捷有效。
# 八、关闭与离开窗口
有4种关闭窗口的方式,分别是:离开(quit)、关闭(close)、隐藏(hide)、关闭其他窗口
- ^代表Ctrl键
- ^Wq,离开当前窗口
- ^Wc,关闭当前的窗口
- ^Wo,关闭当前窗口以外的所有窗口
# tab:分页编辑
- 描述:除了使多窗口编辑外,vim还允许创建多个分页(tab),每个分页各有独自的行为,类似于浏览器firefox或chrome的分页浏览功能。我们可以在vim或gvim中使用分页,但在gvim会更好用。
- 命令:
- :tabnew filename 打开新分页并编辑新文件(可选的)。如果未指定文件,则只打开新分页,并附上空的缓冲区。
- :tabclose(tabc) 关闭当前分页
- :tabonly 关闭其他所有的分页。如果其他分页中有修改过的文件,则不会移除该分页,除非设置了autowrite选项。此时,所有修改过的文件都在分页关闭前写入磁盘。
- 快捷键:
- tab的标题栏会显示该tab当前激活的window中文件的名字,及tab中一共有多少个window。
- 使用gt命令可以切换到下一个tab,使用gT命令可以切换到前一个tab
- 如果tab比较多,我们可以使用:tabs查看所有tab的列表,然后输入ngt命令切换到对应的tab,其中n是tab的编号
- 移动tab:
- 可以直接点鼠标来移动到另一个分页,也可以用命令
- Ctrl + PageDown:移动到下一个分页
- Ctrl + PageUp:移动到上一个分页
# buffer:缓冲编辑
buffer+window约等于tab
Vim 中的 window 和 tab 非常具有迷惑性,跟我们平时所说的 “窗口” 和 “标签页” ,是完全不同的两个概念,请看 vimdoc 给出的定义:
A buffer is the in-memory text of a file. A window is a viewport on a buffer. A tab page is a collection of windows.
简单来说就是:
buffer 可以看做是内存中的文本文件,在没写到磁盘上时,所有的修改都发生在内存中; window 用来显示 buffer,同一个 buffer 可以被多个 window 显示(一个 window 只能显示一个 buffer); tab page 包含了一系列的 window,其实叫 layout 更合适。
# buffer打开
buffer在显示器较小的时候就很有优势了,它能够实现在文件间的快速切换。
使用下面命令可以同时打开多个文件: vim test1 test2 test3
之后,可以用Vim命令 😮 继续打开文件 😮 test4
:buffers 命令还有两个更简单一些的别名: :ls 和 :files 。 上图中第一列是文件编号,第二列是缓冲文件的状态,第三列是文件的名称,第四列是上一次编辑的位置,即在不同文件之间切换的时候Vim会自动跳转到上一次光标所在的位置。 缓冲文件的状态有如下几种,仅供参考:
A | B |
---|---|
- | (非活动的缓冲区) |
a | (当前被激活缓冲区) |
h | (隐藏的缓冲区) |
% | (当前的缓冲区) |
# | (交换缓冲区) |
= | (只读缓冲区) |
+ | (已经更改的缓冲区) |
:badd b.py 可以打开b.py的buffer(badd代表buffer add,也可以简写成bad),只不过这个时候b.py的buffer是hidden的
# 切换缓冲区
最常用的功能是缓冲区之间的切换了,最直接的方式是先用 :buffers 命令查看所有的缓冲区,然后使用 :buffer <编号> 或者 :buffer <文件名> 切换:
:ls 列出所有已打开的 buffer :b 数字 切换到对应 buffer :bd 数字 删除对应 buffer
另外一种方式是使用切换上一个或者下一个缓冲区,以及直接切换到第一个和最后一个缓冲区的命令。文件比较少的时候的确很管用。 :bnext :bprevious :blast :bfirst
:bn -- buffer列表中下一个 buffer :bp -- buffer列表中前一个 buffer :b# -- 你之前所在的前一个 buffer
:buffers -- 查看当前Buffer中的文件列表
# 键盘映射
http://yyq123.blogspot.ru/2010/12/vim-map.html
如今基本上
- :mapclear 可以使用以下命令,取消所有映射。请注意,这个命令将会移除所有用户定义和系统默认的键盘映射。
- :unmap
注意:必须为:unmap命令指定一个参数。如果未指定任何参数,那么系统将会报错,而不会取消所有的键盘映射。 - :help :map-alt-keys :map,可以列出所有键盘映射。其中第一列标明了映射在哪种模式下工作:
# VIM系统变量
:echo $HOME :VIM HOME目录,对应于OS上的~目录
Linux上为/home/username/ Windows上为C:\Users\username\
:echo $VIM :VIM的安装目录 VIM的目录路径为:
\vim
\vim\vim74\
\vim\vimfiles\
_vimrc
:echo $VIMRUNTIME :vim.exe程序的目录
\vim\vim74\
2
3
4
5
6
:echo $MYVIMRC :用户VIMRC文件路径 Windows下为\vim\ _vimrc Linux下为~/.vimrc 对应:version命令可以看到生效的VIMRC文件
VIM环境变量 :set all查看所有环境变量的设置 :set查看所有与系统默认不同的环境变量 :set variable?显示指定环境变量的当前值 :set runtimepath?显示script搜索路径