aliases | tags | created | modified | ||
---|---|---|---|---|---|
|
2023-08-18 12:44:52 -0700 |
2024-12-24 10:00:59 -0800 |
[!info] vim 操作本质 「从本质上讲, 我们的工作是重复性的。 不论是在几个不同的地方做相同的小改动, 还是在文档的相似结构间移动, 我们都会重复很多操 作。 凡是可以简化重复性操作的方式, 都会成倍地节省我们的时间。」-- 《vim实用技巧》
Vim 所有操作的本质实际是简化重复性工作。
在 VIM 的 Normal 模式下,所有的键就是功能键
h
: 向左移动一个字符位置l
: 向右移动一个字符位置j
: 向下移动一个字符位置k
: 向上移动一个字符位置^
: 跳到行首 (忽略行首缩进或空格)$
: 跳到行尾
单词,在 Vim 中是以空白来区隔的。 ^vim-word
[!quote]
「一个单词由字符、数字和下划线序列或者其他的非空白字符的序列组成。单词间可以空白字符 (空格、制表、换行) 分隔。这一规则可以用 'iskeyword' 选项改变。空行也被认 作单词。 WORD 一个字串由非空白字符序列组成。字串以空白分隔。空行也被认作字串。」
引自: VIM 中文帮助: word
w
: 向前移动到下一个词首W
: 向前移动到下一个词词首,忽略,
、.
等标点符号b
: 向后移动到上一个词B
: 向后移动到上一个词,忽略,
、.
等标点符号e
: 向右移动到单词的词尾(e
即「end」)E
: 向左移动到下一个空格前的单词词尾,忽略中间出现的标点符号
[!info]
E
,强调空格前,是非常必要的,E
不是简单的「忽略标点符号版」的e
,而它的跳转核心仍与w
和e
相同,即 单词以空白为分隔符,与e
区别,e
在下一个空白前的单词跳转「途中」出现如,
或.
等标点符号,这种空白为分隔符的跳转就会被「截停」,光标就会跳转到这些「标点」位置上,而E
就会将这些「途中」的标点忽略掉,直接掉到下个空白前的单词的词尾。另外,还要再说下,
e
或b
在实现「跨单词」跳转上,不如w
来得「稳定」。
w
操作时,无论当前光标在当前单词哪个位置,只要安了w
,就会跳到下一个单词词首位置。而
e
操作时,如果当前光标不在当前单词最后一个字符,那按了e
后,只会跳到当前单词词尾,而不会立即跳到下一个单词词尾。这种情况同样发生在
b
身上,就是当前光标所在单词非单词词首时,往回跳(往左)时,光标会先跳到当前单词的词首,下一次的b
才会跳到上一个单词的词首。对于b
的这个「缺陷」,可以使用ge
来替代。而e
就没办法了,所以更多时候向下(向右)跳转时,用得更多的是w
,而且其他的操作也是用w
的,如diw
(删除一个单词),所以w
因为使用率最高,所以有其「超然」的地位,所以在它的实现上有着e
和b
不一样的「稳定性」-- 这就点像 Java 中int
类型(Java 的 int 类型是数值类型最高使用率的类型,以至于在 字节码 上都有特别「定制」,如 i++和++i 这种自增操作,其他类型在字节码上使用的是add
指令,而且 Java 专门给 int 类型弄了个iinc
指令。)。
f 字符
: 向下查找包含字符并跳转到此字符上F 字符
: 向上查找包含的字符并跳转至此字符上数字 w
: 向前移动到 n 个词 (n 为 w 之前输入的数字)数字 b
: 向后移动到 n 个词 (n 为 b 之前输入的数字)*
:向下查找光标所在单词#
:向上查找光标所在单词
gg
:跳到文档首行G
: 跳到文档最后一行数字j
: 向下移动 n 行 (n 为 j 之前输入的数字,即相对行号),数字k
:向上移动 n 行 (n 为 k 之前输入的数字,即相对行号)数字G
: 跳到指定行 (数字为绝对行号) ^line-mv-numg数字gg
:与数字G
效果一样,都是跳到指定行。
[!info]
使用命令模式,也能实现指定行的跳转:
:N
,N 为绝对行号。
[!tip] 相对行号
为了配合
j
、k
快速进行行间跳转,得需要使用到计算出相对行号,这是件麻烦的事。为了避免自行计算相对行号,建议开启相对行号显示。开启了相对行号显示,可以通过
set relativenumber
代码设置。
一个句子以 '.'、'!' 或者 '?' 结尾并紧随着一个换行符、空格或者制表符。结束标点 和空白字符之间可以出现任何数量的闭括号和引号: ')'、']'、'"' 和 '''。段落和小节 的边界也视为句子的边界。
(
:向上一句跳转)
:向下一句跳转
Note
段落,在 Vim 中是以空行为分隔 -- 这点跟 Markdown 有相似的。
}
: 跳到下一个段落
{
: 跳到上一个段落
Ctrl+u
:向上翻半页
Ctrl+d
:向下翻半页
Ctrl+b
:向上翻一页
Ctrl+f
:向下翻一页
%
: 在()[] {} 间跳转
dd
: 删除光标所在当前行
ndd
: 删除光标所在行始往下 n 行 (n 为要删除行的数量,包括光标所在行)
dG
: 删除光标所在行始至文档末行 (包括光标所在行)
dgg
: 删除光标所在行始至文档顶行 (包括光标所在行)
dw
: 删除从光标到词末(包括词末的空格)
daw
: 删除 (剪切) 一个词 (不管光标是否在词首,会将词后空格也删除。a--around)
diw
: 删除 (剪切) 一个词 (同上,但不包括词后的空格)
db
: 从光标向左删除直至词首
das
: 删除 (剪切) 一句,包括句后的空格也一并删除 (以英文.及空格为断句条件,如不满足断句条件将继续往下直至行末,存在误删机率)
dis
: 删除 (剪切) 一句 (断句条件同上,只是不会将句后的空格删除)
de
: 删除从光标所在处后一个词所有内容,但不包括词后的空格
d{
: 向上删除一个代码块
d}
: 向下删除一个代码块
D
: 删除光标字符始至行尾所有字符 (包括光标所在字符也会删除)
x
: 删除一个字符仍保持 normal 模式
数字x
: 删除包括光标在字符在内的 n 个字符 (n 为 x 前的数字),仍保持 normal 模式
X
: 退格,即删除光标左边的字符,仍操持 normal 模式
数字X
: 向左删除包括光标所在的字符在内的 n 个字符 (n 为 X 前的数字),仍保持 normal 模式
[!tips] 关于删除操作
选取内容后按d和x,效果都是在当前文档是将所选内容移除,移除的内容通过 「:reg」 命令可以看到是被「移入」了寄存器中,所以在进行d或x操作,如果再进行p(粘贴),就能从寄存器中取出刚「移除」的内容 -- 这时寄存器就相当于「垃圾筒」,进行「移除」操作后再「粘贴」,就相当于从「垃圾筒」中再把刚丢的「垃圾」再「捡」回来,这也就相当于「剪切」!-- 道理与 linux 中使用 「rm」命令对文件进行「重命名」相似。
/
: 从上往下搜索 (按n依次向下跳转搜索结果,N依次向上跳转搜索结果)
?
: 从下往上搜索 (按n依次向上跳转搜索结果,N依次向下跳转搜索结果)
Tip
*
: 向下搜索光标所在的单词 (搜索结果跳转与 /
一致) 可以按反复按 *
跳转,也可以像 /
一样使用 n
和 N
#
: 向上搜索光标所在单词 (搜索结果跳转与 ?
一致) 可以按反复按 #
跳转,也可以像 /
一样使用 n
和 N
这两种搜索,是 /
与 ?
的快捷搜索方式,适合立即搜索光标所在单词
m+[0~9a~zA~Z]
:可以对光标所在位置进行「标记」。
[!info]
如果想要跨文件标记跳转,标记得使用大写字母来标记,小写字母只能在单文件内跳转。
- `+[a~z]:跳转到指定的「标记」位置。
'+[a~z]
:跳转到标记的文本行首。
dm[0~9a~zA-Z]
:删除某 标记
mark 用得更多的是 命令行模式下marks命令。
使用 :jumps
列出间弘跳转的历史记录。
Ctrl+o
:跳转到上一个位置
Ctrl+i
:跳转到下一个位置
yy/Y
: 复制光标所在行nyy
: 复制光标所在行至 n 行 (n 复制的行数,数量包括光标所在行)y$
: 复制从光标位置至行尾 (包括光标所在字符)y0/y^
:复制从到光标位置至行首 (不包括光标所在字符)yG
: 复制从光标位置至文档最末ygg
: 复制从光标所在行至文档最顶部所有行yw
: 复制从光标位置起至一个词词末内容(如果当前光标不在词首,则会复制这个单词时,会不完整,所以还是使用yaw
或yiw
)yaw
: 复制一个词 (不用管光标的位置) 这比上面那个好用 (包括词后的空格也一并复制) ^vim-cp-yawyiw
: 复制一个词 (不用管光标的位置)不包括词后的空格 ^vim-cp-yiwnyaw
: 执行 n 次yaw
操作,即复制 n 个词ynw
: 复制 n 个词 (n 为数字,标点符号也算一个词),此命令是从光标开始复制yl
: 复制一个字符ynl
: 复制光标开始算向右 n 个字符 (n 数量包括光标所在的字符)ynh
: 复制光标开始算向左 n 个字符 (n 数量不包括光标所在的字符)ye
: 复制当前光标所在位置至所在单词最后一个字符yas
: 复制一句 (不用管光标位置及换行,根据标点符号.
及空格断句,如果.后没有空格或使用中文句号则断句条件不成立),包括句后的空格nyas
: 执行 n 次yas
操作,即复制 n 个句子yis
: 复制一句 (断句条件同上),不包括句后的空格"ny
: 将选择好的内容存到寄存器 n 中 (n 为寄存器名称,a~z,如果 n 为大写字母则为向相应的寄存器追加内容)"np
: 从 n 寄存器中取出相应的内容进行粘贴 (n 为寄存器名称,a~z)p
: 将内容粘贴到光标之后P
: 将内容粘贴到光标之前nx
: 剪切光标向右 n 个字符 (n 为数字,包括光标所在字符)nX
: 剪切光标向左 n 个字符 (n 为数字,不包括光标所在字符)
[!info]
:reg
: 查看各个寄存器
Tip
一般不论复制还是剪切向左选取字符都不包括光标所在字符,而向右均包括光标所在字符
r
: 替换,将光标所在字符替换成 r 之后输入的字符ctrl+a
: 跳转到第一个包含数字的词上,光标停留在数字上,并将数字自增 1数字 ctrl+a
: 与上面命令类似,不过指定了增长的数字{visual} g ctrl+a
: 多行递进增长ctrl+x
: 跳转到第一个包含数字的词上,光标停留在数字上,并将数字自减 1数字 ctrl+x
: 与上面命令类似,不过指定了减少的数字{visual} g ctrl+x
: 多行递进减少
>>
: 非选中状态光标所在行向右缩进 (光标可在行中任意位置)n>>
: 非选中状态包括光标所在行在内的 n 行向右缩进 (n 为行数)<<
: 非选中状态光标在行向左缩进 (光标在行中任意位置)n<<
: 非选中状态包括光标所在行在内的 n 行向左缩进 (n 为行数)>
: 选中状态,>
能让选中内容向右缩进<
: 选中状态,<
能让选中内容向左缩进
激活折叠功能:
:set foldenable
:set foldmethod = indent
停用折叠功能:
:set nofoldenable
zf
: 将选中的代码块折叠 ^vim-fold-zfzd
: 展开并删除折叠zo
: 展开折叠 (折叠还在) ^vim-fold-zol
: 效果同上zr
: 递归展开内层折叠zR
: 打开所有折叠zc
: 折叠还在的情况下重新关闭折叠,与上面的zo
操作配合使用,方便将折叠进行关闭展开zm
: 递归关闭内层折叠zM
: 关闭所有折叠zfip
: 折叠一个代码块 (不用先对代码块选取)zj
: 跳转到下一个折叠zk
: 跳转到上一个折叠
[!info]
命令模式下,与折叠相关的命令
:mkview
: 保存折叠状态:loadview
: 载入折叠状态
[Ctrl]=
: 选中要格式化的内容,按=
或Ctrl+=
ggvG
=
: 全文格式化 gg 是跳转到页首行,v 是进入 可视模式,G
是表示从进入可视模式处一直选择到页底最后一行,=
是 vim 中格式化快捷键gg=G
: 全文格式化,为上面命令的简略形式G=gg
: 全文格式化,跟上面命令一样,不过当前光标在页底,从页底向上选直选到页首行,然后格式化==
: 格式化当前行
buffer 大部分操作均在 命令行模式的 buffer 下进行。
:tabe
: 新建一个标签页gt
: 向右切换标签页gT
: 向左切换标签页
更多的操作是在 命令行模式下
:sp
: 将当前窗口分割成两水平窗口 (文档在两窗口显示的内容完全一样):vsp
: 将当前窗口分割成两垂直窗口 (文档在两窗口显示的内容完全一样)
:new
: 在光标焦点所在的窗口再分割出一个水平窗口:vne
: 在光标焦点所在的窗口再分割出一个垂直窗口
ctrl+w+h/j/k/l
: 使用 ctrl+w 再加 h/j/k/l,可在窗口间切换ctrl+w+w
: 不定向窗口切换
:close
: 关闭当前窗口:qall
: 关闭所有窗口:only
: 只保留当前窗口,其余关闭
:res/:resize
: 没有给出行高将当前窗口的行高设为最高 (完全命令: resize):res n
: 设置当前窗口 n 行高 (完全命令 :resize n)ctrl+w +
: 每按一次将加一行行高ctrl+w >
: 增加窗口一个列宽ctrl+w <
: 减少窗口一个列宽
- 开多个文档,并以水平窗口加载各文档
vim -o 文档1 文档2 ....
- 开启多个文档,并以垂直窗口加载各文档
vim -O 文档1 文档2 ....
- 开启多个文档,并以多标签页方式加载各文档
vim -p 文档1 文档2 ....
Esc
:切换到普通模式
Ctrl+[
:切换到普通模式
Ctrl+o
:切换到「插入 - 普通模式」
Ctrl+g
:显示文档名、总共行数及光标位置
Ctrl+h
:删除前一个字符
Ctrl+w
:删除前一个单词
Ctrl+u
:从光标位置一直删到行首。
i
: 当前光标所在字符前插入
I
: 当前光标所在行的行首字符前插入
a
: 当前到光标所在字符后插入
A
: 当前光标所在行的行尾字符后插入
o
: 当前光标所在行之下新建一行
O
: 当前光标所在行之上新建一行
cw
: 删除从光标到词末(包括词末的空格),并且进入 insert 模式 (相当于dw
后再按了下i
。c
语义是「change」)C
: 从光标处一直删到行末,并进入 insert 模式caw
: 删除光标所在那个词,并进入 insert 模式 (不用管光标是否在词首,空格或标点为分词条件,标点也算一个词),包括词后的空格、引号等ciw
: 删除光标所在那个词,并进入 insert 模式 (分词条件与上同),但不包括词后的空格、引号等cit
: 删除光标所在 tag 中的内容,并进入 insert 模式cat
: 删除光标所在 tag,连 tag 也一并删除,并进入 insert 模式cas
: 删除一句,并进入 insert 模式(以英文.及空格断句,如果不符合这个条件就继续往后找断句直到行末,存在误删除的机率),包括句后的空格也一并删除cis
: 删除一句,并进入 insert 模式(断句条件与上同),不包括句后的空格cib
: 删除最近的小括号内的内容,并进入 Insert 模式。c{
: 向上删除一个代码块,并进入 insert 模式c}
: 向下删除内一个代码块,并进入 insert 模式s
: 删除光标所在的字符并进入 insert 模式数字s
: 删除包括光标所在字符在内至右边的 n 个字符(n 为 s 前的数字),并进入 insert 模式S
: 删除光标所在行并进入 insert 模式 (相当于dd
+i
)数字S
: 删除包括光标所在行在内的向下 n 行 (n 为 S 前的数字),并进入 insert 模式ctrl+w
:删除光标前一个词ctrl+u
:删除光标所在位置前行内所有的内容
ctrl+h
: 删除前一个字符ctrl+w
: 删除前一个单词ctrl+u
: 删除至行首
v
:进入字符 - 可视模式V
:进入行 - 可视模式ctrl+v
:进入块 - 可视模式
[!tip] 块操作 Windows 下是使用
Ctrl+q
来进入块操作模式。
vw
: 选择光标所在位置至词尾空格 (如果光标在词首那就相当于选了这个词)
viw
: 选择光标所在词 (不用管光标是否在词首,也不会选择词后的空格)
vaw
: 选择光标所在词及附近范围 (不用管光标是否在词首,但会将词外如空格也会被选择上。a--around)
vit
: 在 html、xml 中,选取某 tag 中的内容
vat
: 在 html、xml 中,选取包括 tag 在内的内容
v{
: 向上选取一个代码块
v}
: 向下选取一个代码块
vap
: 选取一个段落包括段落后的空行
vip
: 选取一个段落不包括段落后空行
[!info]
包括 normal 模式,visual 模式中,
i
,指的是 inner,而a
指的是 around。
vi
+ 双引号、单引号、括号等,可以选择这些符号中的内容
vit
其实就是这种选取模式的特例,因为 vi<是选取<>符号本身中的内容,如<f>foo<f> 使用vi<
,选取的是f
,而vit
选取的是foo
。(t
就是tag。)
vi(
: 选取括号()
里的内容
v数字i
+ 引号/括号等:选取多层内容
Tip
va
+ 双引号、单引号、括号等,可以连这些符号也包括在内一起选取
同样的,也有 vat
~
- 使用
U
和u
来进行大小写转换 (如果是将整行转换可以使gU
和gu
)
.
: 重复做最后一次连续动作
J
: 将光标所在行的下一行向上移动 (即将下一行与当前行缩排成一行) 也可以将选中的行一并缩排成一行
命令行模式也称为「末行模式」。是以 :
、/
或 ?
开始的。
以 :
命令为主,/
和 ?
的命令主要用于搜索。
:w
: 保存
:q
: 退出
:pwd
: 显示当前工作目录
:ver
: 显示版本信息
:! 指令
: 临时使用 terminal 指令 (相当于 ctrl+z
后执行一条指令再 fg
回到 vim 中)
:r !指令
: 将指令执行结果粘贴到 vim 中
在命令行模式下,想要操作某些范围操作,可以在操作指令前加范围边界。
:n1,n2y
:这就是将第n1行到第n2行的内容进行复制:.,$y
:这就是将当前行到最后一行的内容进行复制:n1,$y
:这就是将第n1行到最后一行的内容进行复制
:n1,n2d
:这就是将第n1行到第n2行的内容进行删除:.,$d
:这就是将当前行到最后一行的内容进行删除:n1,$d
:这就是将第n1行到最后一行的内容进行删除
命令行模式替换命令是 :s
。
:s/str1/str2
:将光标所在行中的字符串str1替换成字符串str2,默认替换第一个
:s/str1/str2/g
:将光标所在行中,所有的字符串str1替换成字符串str2
:n1,n2s/str1/str2/g
:将n1行到n2行范围中,所有字符串str1都替换成字符串str2:1,$s/str1/str2/g
:将第一行到最后一行范围中,所有字符串str1都替换成字符串str2,即全文替换:%s/str1/str2/g
:效果同上
[!tip] 范围替换
与 指定范围 操作的原理保持一致。
:buffers
:显示 buffer 列表:bnext
:切换下一个 buffer:bprevious
:切换上一个 buffer:bfirst
:切换第一个 buffer:blast
:切换最后一个 buffer:bdelete
:从内存中卸载 buffer,并从列表中删除:bunload
:从内存 中卸载 buffer,但列表中仍存在:badd
:加入文件到 buffer 列表
:tabn
: 切换下一个标签页:tabp
: 切换上一个标签页:tabc
: 关闭光标焦点为所在的标签页:tabo
: 关闭除了当前标签页其他标签页
:marks
:查看所有的标记:marks 标记符 标记符
:查看相关的标记符,查看多个标记符使用空格隔开:delmarks
+ 标记名:删除指定标记,可删除多个标记,多个标记使用空格分隔。:delmarks!
:删除所有的标记。
" 开启真彩色
set termguicolors
set nocompatible
set number
" 退格键设置
set backspace=indent,start
" 关闭各种自动生成文件
set noundofile
set nobackup
set noswapfile
" 高亮搜索
set hlsearch
set incsearch
" 显示状态栏
set laststatu=2
set ruler
" 与底部保持固定间距
set scrolloff=5
" 缩进
set shiftwidth=4
set tabstop=4
set softtabstop=4
" 不要将tab展开成空格
set noexpandtab
" 字符编码
set encoding=utf-8
set langmenu=zh_CN.UTF-8
set fileencodings=utf-8,gbk,gb18030,gb2312,ucs-bom,cp936,big5,euc-jp,euc-kr
" 语法高亮及文件类型
syntax on
filetype on
filetype plugin on
" 命令行提示
set wildmenu
关于缩进设置详解:
tabstop
表示一个 tab 显示出来是多少个空格的长度,默认 8。
softtabstop
表示在编辑模式的时候按退格键的时候退回缩进的长度,当使用 expandtab
时特别有用。
shiftwidth
表示每一级缩进的长度,一般设置成跟 softtabstop
一样。
设置成 expandtab
时,缩进用空格来表示;noexpandtab
则是用制表符表示一个缩进。
命令 | Normal Mode | Visual Mode | Insert Mode |
---|---|---|---|
map | * | * | |
nmap | * | ||
vmap | * | ||
imap | * |
禁用某些键示例:
map 要禁的键 \<Nop\>
禁用递归映射:
noremap 要映射的键 映射键
" 其他模式可用inoremap、nnoremap和vnoremap
try
语句
catch
语句
endtry
类别 | 符号 | 描述 |
---|---|---|
未命名寄存器 | " | 上一次复制或删除的文本 |
数字寄存器 | 0~9 | 文本复制和删除历史 |
行内删除寄存器 | - | 删除少于一行的文本 |
命名寄存器 | a |
存放文本 |
只读寄存器 | % | 当前文件名 |
只读寄存器 | . | 最近插入的文本 |
只读寄存器 | : | 最近执行的命令行 |
轮换缓冲区寄存器 | # | 交替文件的名字 |
表达式寄存器 | = | 返回表达式结果 |
使用 Ctrl-X Ctrl-F
快捷键,可以匹配并补全文件名。
如果当前光标下的文本不包含任何路径信息,那么将显示当前目录下的文件列表。
如果当前光标下的文本包含任何(绝对或相对)路径信息,那么将显示其指定目录下的文件列表。
如果当前光标下的文件包含唯一的路径信息(比如 ~
),那将自动转换为目录的完整名称。
Tip
文件名或称为路径补全,所有操作均在 插入模式(Insert)下进行。