第 1 章,vi 文本编辑器#
-
简要历史回顾
-
打开和关闭文件
vi filename
,并编辑ZZ
,保存文件:w
,保存:w new-filename
,另存为:w!
,强制写入:e!
,恢复:q!
,强制退出:!rm junk-file
:!df
-
学习 vi 的唯一方法是实践。
第 2 章,简单编辑#
-
移动光标
- 单次移动:
h
,j
,k
,l
,它们太糟糕了!我使用neo 键盘布局 - 数字参数:1,2,...
- 行内移动:
0
,移动到行首$
,移动到行尾^
,移动到第一个非空字符
- 按文本块移动
w,b
,按单词前进、后退移动。W,B
,按大单词前进、后退移动。"-" 连接的单词视为一个8G
,移动到第 8 行G
,移动到文件末尾gg
,类似于1G
- 移动到上一行 / 下一行的第一个字符:
-
,+
- 单次移动:
-
简单编辑
a
,追加;(不必要,我会将这些键自定义为其他用途)i
,插入;c
,更改;cw, cb
,分别更改单词,向前,向后c2w
,向前更改 2 个单词c^
,到第一个非空字符c0, c$
,到行的开始,结束,或者你可以使用c[Home],c[End]
d
,删除;dw
,按单词db
,按单词,向后dd
,删除行d$,d[End],D
,删除到行尾dto
,dTx
,删除到(不包括)"x",向前 / 向后d/th
,删除到第一个匹配的 "th"diw
,删除当前单词di(
,删除当前括号内的内容
s
,替换s
(一个或多个字符),S
(整行)。
x,X
,删除一个字符,向前或向后,(不必要)xP,XP
,删除并粘贴回来xp,Xp
,交换两个字符
y
,复制;p
,粘贴;$p
,粘贴到行尾0P
,^P
,粘贴到行首
-
vi 命令的一般形式
cc,dd,yy
(command)(text object)
(command)(number)(text object)
(number)(command)(text object)
cc
,更改整行C
,类似于c$
~
,改变大小写
-
杂项
- 重复上一个命令
.
- 撤销,重做
u
,C-r
,U
,在 evil 模式下似乎工作不同
- 插入命令的数字参数:例如
4i<space><Esc>
- 重复上一个命令
-
注意
cc
,dd
,yy
,应用于行C
,D
,S
从当前位置应用到结束,而Y
应用于整行C
===c$
,D
===d$
,但Y
===yy
,而不是y$
-
总体
+------------------------------+------------------------------+------------------------------+------------------------------+ | 文本对象 | 更改 | 删除 | 复制 | +------------------------------+------------------------------+------------------------------+------------------------------+ | 一个单词 | cw | dw | yw | +------------------------------+------------------------------+------------------------------+------------------------------+ | 两个单词,不计算标点 | 2cW或c2W | 2dW或d2W | 2yW或y2W | | 标点 | | | | +------------------------------+------------------------------+------------------------------+------------------------------+ | 三个单词向后 | 3cb或c3b | 3db或d3b | 3yb或y3b | +------------------------------+------------------------------+------------------------------+------------------------------+ | 一行 | cc | dd | yy或Y | +------------------------------+------------------------------+------------------------------+------------------------------+ | 到行尾 | c$或C | d$或D | y$ | +------------------------------+------------------------------+------------------------------+------------------------------+ | 到行首 | c0 | d0 | y0 | +------------------------------+------------------------------+------------------------------+------------------------------+ | 单个字符 | r | x或X | yl或yh | +------------------------------+------------------------------+------------------------------+------------------------------+ | 五个字符 | 5s | 5x | 5yl | +------------------------------+------------------------------+------------------------------+------------------------------+
-
示例
r
,dd
,P
,cw
,x
使用编辑器你可以滚动页面, 使用屏幕编辑器你可以滚动页面, 移动光标,删除行,插入 移动光标,删除行,插入 字符,等等,同时看到 字符,等等,同时看到 你的编辑结果。 你的编辑结果。 由于它们允许你在阅读文件时进行更改, 屏幕编辑器非常流行。 就像你编辑打印的副本一样, 由于它们允许你在阅读文件时进行更改, 屏幕编辑器非常流行。 就像你编辑打印的副本一样。
P
,p
,.
使用屏幕编辑器你可以 使用屏幕编辑器你可以 滚动页面。 滚动页面。 移动光标。 使用屏幕编辑器你可以 删除行。 移动光标。 使用屏幕编辑器你可以 删除行。
J
使用一个 使用屏幕编辑器你可以滚动页面,移动光标 屏幕编辑器 你可以 滚动页面,移动光标
第 3 章,快速移动#
-
按屏幕移动
- 滚动屏幕:
C-b
,C-f
,C-u
(在 emacs evil 模式下无效),C-d
,C-y
,C-e
z<Enter>
,z.
,z-
,移动到顶部 / 中间 / 底部并滚动到那里(不如 emacs 的recenter-top-center
好,我会在我的 evil 模式中放弃这个)
- 滚动屏幕:
-
重新绘制屏幕:
C-l
(在我的 evil 模式下无效,我们有recenter-top-center
) -
屏幕内移动
H
,M
,L
:移动到屏幕的顶部 / 中间 / 底部2H
,2L
:从顶部 / 底部的第二行
-
按行移动
+
,<Enter>
,-
,移动到下一行 / 上一行的第一个字符。- 当前行的移动:
20|
,移动到第 20 列,^
,移动到第一个非空字符。
-
按文本块移动
e
,E
,单词的结尾,(忽略标点)(
,)
,当前 / 下一句的开头{
,}
,当前 / 下一段的开头[[
,]]
,当前 / 下一节的开头
-
按搜索移动
/pattern
,?pattern
,向前 / 向后搜索n
,下一个匹配N
,下一个匹配,反向位置:set nowrapscan
,不进行循环搜索d/pattern
-
当前行搜索
fx
,Fx
,移动到前一个 / 下一个 'x'tx
,Tx
,移动到字符 'x' 之前,前一个 / 下一个;
,,
,重复相同方向,反向方向7fx
,移动到第 7 个匹配dfx
,例如dfi
,从这里删除到第一个出现的 'i',然后d;
,删除到第二个出现的 'i'
-
按行号移动
20G
,移动到第 20 行``
, 返回(旧位置)''
,移动回去,但在行首
使用屏幕编辑器你可以滚动 页面,移动1移动2移动4移动5移动6移动7光标,删除行,插入 字符,等等,同时看到 字符,以及 你的编辑结果。
第 4 章,超越基础#
-
更多命令组合
+------------+------------+-----------+------------------------------+ |更改 |删除 |复制 |从光标到... | +------------+------------+-----------+------------------------------+ |cH |dH |yH |屏幕顶部 | +------------+------------+-----------+------------------------------+ |cL |dL |yL |屏幕底部 | +------------+------------+-----------+------------------------------+ |c+ |d+ |y+ |下一行 | +------------+------------+-----------+------------------------------+ |c5| |d5| |y5| |当前行的第5列 | +------------+------------+-----------+------------------------------+ |2c) |2d) |2y) |第二个句子 | +------------+------------+-----------+------------------------------+ |c{ |d{ |y{ |前一段 | +------------+------------+-----------+------------------------------+ |c/pattern |d/pattern |y/pattern |模式 | +------------+------------+-----------+------------------------------+ |cn |dn |yn |下一个模式 | +------------+------------+-----------+------------------------------+ |cG |dG |yG |文件末尾 | +------------+------------+-----------+------------------------------+ |c13G |d13G |y13G |第13行 | +------------+------------+------------+------------------------------+
-
启动 vi 时的选项
vi +3 filename
,在第 3 行打开文件vi + filename
,在最后一行打开文件vi +/pattern filename
,在模式的第一个出现处打开文件vi +R filename
,以只读模式读取文件vi -r filename
,ex -r filename
,恢复缓冲区
-
复制到命名缓冲区
"dyy
,复制到缓冲区 "d""ayw
,复制到缓冲区 "a""ap
,"
dp`,粘贴缓冲区"a"/"d"
-
标记你的位置
mx
,标记当前位置为 x'x
,''
,``
, 移动到最后一个位置
第 5 章,介绍 ex 编辑器#
__ _ _ _ _
/ _| ___ _ __ | | __ _| |_ ___ _ __ _ __ ___ __ _ __| (_)_ __ __ _
| |_ / _ \| '__| | |/ _` | __/ _ \ '__| | '__/ _ \/ _` |/ _` | | '_ \ / _` |
| _| (_) | | | | (_| | || __/ | | | | __/ (_| | (_| | | | | | (_| |
|_| \___/|_| |_|\__,_|\__\___|_| |_| \___|\__,_|\__,_|_|_| |_|\__, |
|___/
第 6 章,全局替换#
-
替换
:s/old/new
,替换第一个出现的 old:s/old/new/g
,多个出现:50,100s/old/new/g
,:50,100s/old/new
应用于 50~100 行:1,$s/old/new
,应用于整个文件
-
c,确认
y
表示是n
表示否Enter
,退出
-
内容敏感的替换
:%s/old/new/g
,不确认,整个文件:g/pattern/s/old/new/g
,:1,200g/pattern/s/old/new/g
:g/pattern/s/old/new/g
,与:g/pattern/s//new/g
相同
-
模式匹配规则
.
, 单个字符,除了换行符*
,匹配前一个字符的零个或多个出现- 例如
a*
可以匹配a
,aa
,aaa
等 - 例如
.*
可以匹配任何字符组合
- 例如
^,$
,当它是正则表达式的第一个 / 最后一个字符时,视为行的开始 / 结束,否则视为自身。- 例如
^Line
匹配任何以 "Line" 开头的行 - 例如
something^*
,可以匹配 "something","something^","something^^" 等
- 例如
[]
,例如[aoei]
匹配a
,o
,e
,i
;[a-z]
,;:[a-z0-9]
按预期工作。:%s/\(That\) or \(this\)/\2 or \1/
~
,匹配最后的搜索历史。就像你用/the
搜索 "the",然后你可以用/~n
搜索 "then"\
,例如\.
匹配 "."\<m
,\>tion
,匹配以 'm' 开头,以 "tion" 结尾的单词
-
POSIX 括号表达式
[:alnum:]
字母数字字符[:alpha:]
字母字符[:blank:]
空格和制表符字符[:cntrl:]
控制字符[:digit:]
数字字符[:graph:]
可打印和可见(非空)字符[:lower:]
小写字符[:print:]
可打印字符(包括空白)[:punct:]
标点字符[:space:]
空白字符[:upper:]
大写字符[:xdigit:]
十六进制数字
-
新的
s/old/NEW/g
模式\n
,n 为 1..9,匹配 (THIS)&
,匹配部分~
,s/thier/their/
,然后s/her/~/
就像s/her/their
\u,\l
,大写 / 小写字符。:s/\(That\) or \(this\)/\u\2 or \l\1/
\U,\L,\e,\E
,大写区域,或整个匹配:set ic
,忽略大小写
-
更多替换技巧
:s//~/
,重复最后的替换:%&g
,在所有地方重复最后的替换:%s;/user1/tim;/home/tim;g
-
练习
/four
,<Enter>
,cwfive
,n
(重复搜索),n
(跳过一个匹配),.
(应用最后的cwfive
)
-
示例
- 示例 - 1
<p>something</p> <p>somethingelse</p> <a>something</a> ===> `:%300,400g/<p>/s/something/somethingelse/g` ===> <a>something</a> <a>something</a> <a>something</a> <p>something</p> <p>somethingelse</p>
- 示例 - 2
one (one) two (two) three ===> `:348,352s/.*/(&)/` ===> (three) four (four) five (five)
- 示例 - 3
That or this ===> `:%s/\(That\) or \(this\)/\2 or \1/` ===> this or That
__ _ _ _ _
/ _| ___ _ __ | | __ _| |_ ___ _ __ _ __ ___ __ _ __| (_)_ __ __ _
| |_ / _ \| '__| | |/ _` | __/ _ \ '__| | '__/ _ \/ _` |/ _` | | '_ \ / _` |
| _| (_) | | | | (_| | || __/ | | | | __/ (_| | (_| | | | | | (_| |
|_| \___/|_| |_|\__,_|\__\___|_| |_| \___|\__,_|\__,_|_|_| |_|\__, |
|___/
第 7 章,高级编辑#
-
自定义 vi
- 命令
:set option
,或:set nooption
- .exrc 文件
- 命令
-
执行 Unix 命令
:!cmd
:r !date
,输出到文件,Thu May 1 12:59:55 CST 2014:. !date
,与:r
相同,但覆盖当前行:r Learning-Vim.md
,这是.... 好。
-
通过命令过滤文本
:%!sort
,你试你死...!)cmd
,将这些句子传递给 cmd!!
,当前行!2!
,2!!
,两行
-
保存命令
- 单词缩写
:ab abbr phrase
:unab abbr
- 单词缩写
第 8 章,vi 克隆介绍#
技巧#
diw
,di"
,di{}
:!xxd
,十六进制编辑器
:!xxd -r
de
,然后.
如你所愿ddp
,交换当前行和下一行bye
,yiw
'.
,最后编辑的行`.
, 最后编辑的字符:changes
,列出更改- /rgba/y A
10.gv
,重新选择最后的可视选择 g~~
,gUU
,guu
>>
,<<
,缩进#
,*
,搜索光标下的单词