文本编辑 Vim


原文链接: 文本编辑 Vim

VIM学习笔记
Vim - 文本/代码编辑器之中最为优秀经典的上古神器!
一起来说 Vim 语
简明 Vim 练级攻略
vim编辑器技巧备忘(初级-中级)
https://github.com/dofy/learn-vim
vim-程序员的利器
史上最全Vim快捷键键位图
提高 Vim 使用效率的 12 个技巧
提高VIM 效率
让人相见恨晚的vim插件:模糊查找神器LeaderF
Vim_Tips
Vim Cheat Sheet 快捷键
vimawesome 插件大全

Ubuntu vi 上下左右变ABCD问题解决方法-安装vim的full版本

sudo apt-get remove vim-common
sudo apt-get install vim
sudo add-apt-repository ppa:jonathonf/vim


移动

0 ^ B b h l w W g_ $

xxx xxx-xxxXxx_xx-xxx xxxx    

:version :显示的VIMRC目录
:function :查看加载的所有function
:scriptnames :显示vim启动后加载的所有script
:rew 重新回到第一个编辑的文档
:args 显示所有要编辑的文件
:marks 查看所有的mark
:reg 查看所有的@寄存器值
:buffers 等价 :ls 查看所有的buffer
:tabs
:tags
:clist :cw
jumps 显示所有跳转历史 [count] [count]
:changes 显示所有变更历史 [count]g; [count]g,
:scriptnames 看看vim加载了哪些脚本
:h keycodes 常见键盘键

q: 进入命令历史编辑
q: will show you command history in Vim.
q/ will show you history of searches

多标签页:

vim -p filename
最多不能超过"tabpagemax"数量,默认为10

正常模式下:
gt,gT 可以直接在tab之间切换,Ctrl+PageUp和Ctrl+PageDown也是一样。

命令:
:tabnew [++opt选项] [+cmd] 文件 建立对指定文件新的tab
:tabc 关闭当前的tab,如果带!,强制关闭当前tab
:tabo 关闭所有其他的tab
:tabs 查看所有打开的tab
:tabp 前一个
:tabn 后一个

.vimrc文件有用的设置:
set showtabline=2
设置标签栏的显示,0永远不显示 1两个以上显示 2 永远显示

状态栏 statusbar

serializers/core.py, serializers/order.py, starvation/models/order.py

:set laststatus=2 #2 - to always display status bar. 1 - display if there are more than one window, 0 - don't display status bar
:set statusline=%F #%F - Full file name & %f - short file name

f there are more than one window, 0 - don't display status bar
:set statusline=%F #%F - Full file name & %f - short file name

Can I use SPACE as mapleader in VIM?

let mapleader = ' '
nnoremap <leader>h :helpgrep<space>

查看启动时间

vim --startuptime timeCost.txt

VIM环境变量

:set all查看所有环境变量的设置
:set查看所有与系统默认不同的环境变量
:set variable?显示指定环境变量的当前值
:set runtimepath?显示script搜索路径

vim 变量查看

下面三个前缀用来访问特殊的数值
$ --访问环境变量;
& --访问 Vim 选项;
:echo &
"echo &foldmethod
@ --访问寄存器。

Vim中无法用Alt键来映射

这次在用Vim的时候,想设置以下快捷键,但是Alt+key()的设置一直不成功,后来在网上找了一下资料才明白原来将""的输入格式换成"^[key"就可以了
输入方式为:按下 Crtl+v后在按下 Alt+key(你想设置的键),这样vim中显示为:^[key, 这样就搞定了

map映射

在vim配置文件中经常会看到map、nmap、imap、vmap、vnoremap、nunmap、nmapclear等,都是什么意思呢?

map前的n、v、nore、un等表示下列含义:
nore -- 表示非递归。
n --表示在普通模式下生效。
v --表示在可视模式下生效。
i --表示在插入模式下生效。
c --表示在命令行模式下生效。
un --后面跟按键组合,表示删除这个映射。
clear --表示清除相关模式下的所有映射。
"n" Normal
"v" Visual (including Select)
"o" Operator-pending
"i" Insert
"c" Cmd-line
"s" Select
"x" Visual
"l" langmap language-mapping
"" Normal, Visual and Operator-pending

映 射 与 运 行 模 式
有五种映射存在

  • 对于普通模式: 当输入命令时.
  • 对于可视模式: 当输入命令并且 Visual 区域已被设置为高亮时.
  • 对于 Operator-pending mode: 当一个操作符正在进行中 ("d", "y", "c",等等之后)
    例如: ":omap { w" 会使 "y{" 和 "yw" 一样, "d{" 和 "dw"一样.
  • 对于插入模式: 也被用于替换模式.
  • 对于命令行模式: 当输入一个 ":" 或 "/" 命令时.

    vim 中文乱码

  • set enc=utf8
    一般来说就够了(只针对vim乱码的情况,操作系统乱码另说)
    如果还不行,可以再添加

  • set fencs=utf-8,gb2312,gb18030,gbk,ucs-bom,cp936,latin1
    还不行就把第一个的utf8换成gbk,第二个的gbk放到最前。

https://www.zhihu.com/question/22363620/answer/200242582

Ctrl+v: 进入 visual 模式,选取单位为块
~: 进入 visual 模式后,将选中字符大小写交换

visual模式

v 进入字符可视化模式 (移动一次选择一个字符)
V 进入行可视化模式
ctrl-V 进入块可视化模式
ctrl-Q
gv 选中前一次可视化模式时选择的文本
o 光标移动到选中文本的另一结尾 非常有用
O 光标移动到选中文本的另一角落

vim 强制保存只读文件

:w !sudo tee %

vim 让大写Q和小写q同样作用

别名:
cab Q q
cab W w
cab WQ wq

set hlsearch "打开高亮搜索
set nohlsearch "关闭高亮搜索
:noh "只取消掉当前的搜索高亮
map :nohl只需要按Ctrl-n取消查找后的高亮显示

打开光标所在词的文件

gf 就是这么牛B

man

Vim中大写K 默认是看光标所指标识符的 man 帮助页

现实光标文件编码

ga(显示光标下的字符在当前使用的 encoding 下的内码)

常用快捷键

15G #跳转到15行
Ctrl+] 跳转到tag
CTRL+t 标签退栈 :tags

CTRL-o 向后跳evil-jump-backword
CTRL-i 向前跳evil-jump-forword

撤销undo

u 取消上一步操作(最多连续取消500次)
U 取消当前行中所有的改动。
:undo 5 -- 撤销5个改变:undolist -- 你的撤销历史

redo

ctrl+r 恢复上一步被撤销的操作
:earlier 4m -- 回到4分钟前
:later 55s -- 前进55秒

0 跳转到行首
^ 跳转到词首

3G:移动到第三行
3|:移动到第三列

;:继续从光标位置向后搜索
,:继续从光标位置向前搜索

z[Enter]:使光标指向的当前行成为屏幕的首行
z.:使光标指向的当前行成为屏幕的中间行
z-:使光标指向的挡前行成为屏幕的尾行
#快速滚屏
Ctrl + d 向下滚动半屏
Ctrl + u 向上滚动半屏

Ctrl + f 向下滚动一屏
Ctrl + b 向上滚动一屏

Ctrl + e 向下滚动一行
Ctrl + y 向上滚动一行

快速跳转

f 向后查找,到所在字符之上
t 向后查找,到所在字符之前
F 向前查找

单词移动

w, e, b: 默认上来说,一个单词由字母,数字和下划线组成
W, E, B: 以空格为单位跳转 比如连字符-)|都作为单词组成

%: 跳转匹配的括号, (,{,[,],},) #最强跳转

修改

J 合并行 之间添加一个空格

:set ic(noic) 查找时,忽略大小写
:set incsearch  实时显示搜索结果。

J 合并行 之间添加一个空格

:set ic(noic) 查找时,忽略大小写
:set incsearch  实时显示搜索结果。

J 合并行 之间添加一个空格

:set ic(noic) 查找时,忽略大小写
:set incsearch  实时显示搜索结果。

J 合并行 之间添加一个空格

:set ic(noic) 查找时,忽略大小写
:set incsearch  实时显示搜索结果。

索结果。

修改/查看文件编码(dos,mac,unix)

:set ff 或 :set fileformat
:set ff=unix 或 :set fileformat=unix
:w ++ff=mac filename, 以mac格式存储这个文件。
:e ++enc=utf8 filename, 让vim用utf-8的编码打开这个文件。

替换

删除行首空白 :%s/^ \+//g
删除行尾空格 :%s/\s\+$//

删除空行 %s/^n//g 全局替换所有以回车开头的字符,替换为空。
连续的空行,只保留一行 %s/^n$//g 如果有多个连续的空行,想保留一行。则只需在命令行模式输入下行即可:
#neovim
ln -s ~/.vimrc ~/.nvimrc
ln -s ~/.vim ~/.nvim

alias vim="nvim"

大小写转换

g~ 改变字符大小写
gU 将字符变大写
gu 将字符变小写
gul 将当前字符变小写
guw 将当前字符至该word结束变小写
gu$ 将当前字符至行尾变小写
gugu 将当前整行变小写,可省略为guu

动词

动词代表了我们打算对文本进行什么样的操作。例如:
d 表示删除delete
r 表示替换replace
c 表示修改change
y 表示复制yank
v 表示选取visual select

介词

介词界定了待编辑文本的范围或者位置。例如:
i 表示“在...之内”inside
a 表示“环绕...”around
t 表示“到...位置前”to 不包含要所在的字符
f 表示“到...位置上”forward 包含要所在的字符

名词 :h object

名词代表了我们即将处理的文本。Vim 中有一个专门的术语叫做文本对象text object,下面是一些文本对象的示例:
B 表示一个block {括号所围起来的内容} == {
b 表示一个block (括号所围起来的内容) == (
p 表示一个段落paragraph
s 表示一个句子sentence
w 表示一个单词word
t 表示一个 HTML 标签tag
'"<[]>"'引号或者各种括号所包含的文本称作一个文本块。

Ctrl-A will increment the next number, and typing Ctrl-X will decrement the next number
##隔行插入自增数字
宏实现行 插入
qa
^
yf
3j
P
^
Ctrl-A
q
117@a to perform the macro 117 times.

Mappings

You can define your own mappings with the :map family of commands. Each
command of that family defines a mapping for a certain set of modes. Technically
Vim comes with a whopping 12 modes, 6 of them can be mapped. Additionally, some
commands act on multiple modes at once.

RecursiveNon-recursiveUnmapModes
:map:noremap:unmapnormal, visual, operator-pending
:nmap:nnoremap:nunmapnormal
:xmap:xnoremap:xunmapvisual
:cmap:cnoremap:cunmapcommand-line
:omap:onoremap:ounmapoperator-pending
:imap:inoremap:iunmapinsert

This mapping is triggered by \h. If you want to use <space>h instead:

marks :h marks

0-9 最近使用的文件

. 最近编辑的位置 Position where last change was made.
∧ 最近插入的位置 Position where last insertion stopped.
' 跳转前的位置 Position before the latest jump.
" 退出当前文件时的位置 Position when last exiting the current buffer.
[] 上次 修改 [开始|结尾] previously changed
<> 上次 选择 <开始|结尾> last visual selection
() 当前 sentence 句子(开始|结尾) current sentence.
{} 当前 paragraph 段落{开始|结尾} current paragraph

移动到标记的光标位置

:marks 列示所有标记
:delmarks a b c命令,可以删除某个或多个标记;
:delmarks! 命令,则会删除所有标记

命令,则会删除所有标记

################################################################################
编辑类
i: insert,进入插入模式,新字符插入在光标前
a: append,进入编辑模式,新字符插入在光标后
c: change,修改
d: delete,删除
p: put,放置,可以将d删除的内容,放置在光标后面
y: yank,拷贝
r: replace,替换,和c不同在于,不必进入编辑模式即可替换
s: substitute,替代,和c不同在于,可以只修改一个字符而非整个字
x: x,和d不同在于,可以只删除一个字符而非整个字
~: change case,替换大小写
.: repeat,重复上一条命令
u: undo,撤销上一条命令
J: join,将两行合并为一行
保存退出类
q: quit,退出,如果有未保存的修改则无法退出
q!: force quit,强制退出
w: write edits to disk (save file),保存文件
w!: force write,强制保存
ZZ: quit and save edits,保存文件并退出
e!: revert your changes,回滚所有修改至原始状态
移动光标类
h: left,向左移动光标
j: down,向下移动光标
k: up,向下移动光标
l: right,向由移动光标
0: digit zero, move to beginning of line,移动到行首
$: move to end of line,移动到行尾
w: move by word,按字向后移动光标(包括标点)
W: move by large word,按字向后移动光标(忽略标点)
b: move backward by word,按字向前移动光标(包括标点)
B: move backward by large word,按字向前移动光标(忽略标点)
e: move to end of word,移动到字尾(包括标点)
E: move to large end of word,移动到字尾(忽略标点)
G: go to end of the file,移动到文件末尾最后一行
记住,vi对于命令区分大小写,I和i不是同一个命令。vi的命令不会显示在屏幕上,每一个命令后面不需要敲击回车(Enter)。当你不知道你处于哪个模式下时,连续按3下Esc总能让你回到命令行模式。

组合命令
vi的便捷性在于你可以组合命令,通过数字+字母,或者字母+字母,甚至数字+字母+字母,可以将单命令构造出你想操作的组合命令

3h: 3 left,向左移动3次光标,等同于lll
3W: 3 move by large word,按3个字向后移动光标(忽略标点等)
1G: go to line 1,移动到文件首行
3G: go to line 3,移动到文件第三行
cw: change, move by word,修改后面的一个字
c3b: change, move backward by 3 words,修改前面的三个字
c$: change, move to end of line,修改光标后面整行文字
c0: change, move to beginning of line,修改光标之前整行文字
dw: delete word,删除字
d3w: delete 3 words,删除三个字
3p: put 3 times,重复放置3次
甚至你可以重复组合

cc: change line,修改整行
dd: delete line,删除整行
3dd: delete 3 line,删除三行
yy: yank line,拷贝整行
按屏移动
在命令行模式下,vi的整屏移动命令可以按以下方式速记:

Ctrl+F :forward:同PageDown键,向下移动整屏
Ctrl+B: backward:同PageUp键,向上移动整屏
Ctrl+D: down:向下移动半屏
Ctrl+U: up:向上移动半屏
z[Enter]:使光标指向的当前行成为屏幕的首行
z.:使光标指向的当前行成为屏幕的中间行
z-:使光标指向的挡前行成为屏幕的尾行
H: home:使光标移动到当前屏幕的首行
M: middle:使光标移动到当前屏幕的中间行
L: last:使光标移动到当前屏幕的尾行
[Enter]:使光标移动到下一行的第一个字符
+:同[Enter],使光标移动到下一行的第一个字符
-:使光标移动到上一行的第一个字符
同样,你可以利用vi的组合命令特性,采用数字+字符的方式来移动,如

3H: 3 lines below home line:使光标移动到当前屏幕的首行的下数第三行3L: 3 lines above last line:使光标移动到当前屏幕的尾行的上数第三行
按字词移动
除了按屏移动,你也需要按字/词来移动,同样在命令行模式下,vi的整屏移动命令可以按以下方式速记:

e: move to end of word:移动到字/词的尾部(包括标点)
E: move to large end of word,移动到字/词的尾部(忽略标点)
(:移动到句首(根据?.!等标点符号)
):移动到下一句
{:移动到段首(根据空行)
}:移动到下一段
[[:移动到章首
]]:移动到下一章
同样,你可以利用vi的组合命令特性,采用数字+字符的方式来移动,如

3)):移动到后三句
按搜索词移动
搜索移动应该是最常使用的移动方式,在命令行模式下输入'/'来启动搜索

/assignment[Enter]:在文中搜索assignment/programming[Enter]:在文中搜索programming
此处有一个技巧,如果你想搜索an,你可以在an前后各敲一个空格,搜索

/ an [Enter]
当你希望继续搜索时,输入

此处有一个技巧,如果你觉得搜索的时候屏幕跳动太快,可以输入

此处有一个技巧,如果你觉得搜索的时候屏幕跳动太快,可以输入

巧,如果你觉得搜索的时候屏幕跳动太快,可以输入

:set nowrapscan
搜索的高级用法这里先卖个关子,以免太过复杂,学习曲线太陡,后面我再罗列如果你只希望在当前行搜索,可以用下面的方法

在日常编程中,经常需要直接根据行号来跳转,如编译错误、日志行数等跳转前,你需要打开行号,输入

在日常编程中,经常需要直接根据行号来跳转,如编译错误、日志行数等跳转前,你需要打开行号,输入

在日常编程中,经常需要直接根据行号来跳转,如编译错误、日志行数等跳转前,你需要打开行号,输入

号,输入

:set nu
下面是移动命令,利用vi的组合命令特性,采用数字+字符的方式来移动

3G:移动到第三行
3|:移动到第三列
:移动当跳转前的行,按搜索词移动也可用 '':同,区别在于光标跳转到行首
最后,你可以输入Ctrl+G来查看当前行列号,以及文本的总行数

撤销和重复的技巧
vi一共可以撤销之前的九次操作,这九次操作存放在vi的九个缓存区中,用数字1-9表示。当你希望撤销第三次操作,输入:

"3p
如果你不记得应该撤销第几次操作,可以输入:

"1pu.u.u.
来找到你想要的内容,其中u撤销上一条命令的意思,.是重复上一条命令的意思,详见Vim实战指南(一):基础编辑命令。

复制和粘贴的技巧
事实上,vi的缓存不仅仅用于撤销,还能用于复制和粘贴,vi提供了字母a-z共26个缓存区供你使用。当你希望拷贝的内容存放到缓存区c,输入:

"cyy
你也可以使用组合命令,拷贝3行到缓存区c,输入:

"c3yy
粘贴缓存区c的内容,输入:

"cp
删除也同样可以使用缓存区c,输入:

"cdd
书签
善用缓存区,还能让缓存区变成书签标记供你使用。当你希望建立标签c时,输入:

mc
跳转到标签c所在的行,输入:

vim全局替换命令

语法为 :[addr]s/源字符串/目的字符串/[option]
全局替换命令为::%s/源字符串/目的字符串/g

s : 表示替换操作

表示操作类型
:g 表示全局替换;
:c 表示进行确认
:p 表示替代结果逐行显示(Ctrl + L恢复屏幕);
省略option时仅对每行第一个匹配串进行替换;
如果在源字符串和目的字符串中出现特殊字符,需要用”\”转义

结果逐行显示(Ctrl + L恢复屏幕);
省略option时仅对每行第一个匹配串进行替换;
如果在源字符串和目的字符串中出现特殊字符,需要用”\”转义

下面是一些例子:

#将That or this 换成 This or that
:%s/\(That\) or \(this\)/\u\2 or \l\1/
—-
#将句尾的child换成children
:%s/child\([ ,.;!:?]\)/children\1/g
—-
#将mgi/r/abox换成mgi/r/asquare
:g/mg\([ira]\)box/s//mg//my\1square/g    <=>  :g/mg[ira]box/s/box/square/g
—-
#将多个空格换成一个空格
:%s/  */ /g
—-
#使用空格替换句号或者冒号后面的一个或者多个空格
:%s/\([:.]\)  */\1 /g
—-
#删除所有空行
:g/^$/d
—-
#删除所有的空白行和空行
:g/^[  ][  ]*$/d
—-
#在每行的开始插入两个空白
:%s/^/>  /
—-
#在接下来的6行末尾加入.
:.,5/$/./
—-
#颠倒文件的行序
:g/.*/m0O  <=> :g/^/m0O
—-
#寻找不是数字的开始行,并将其移到文件尾部
:g!/^[0-9]/m$ <=> g/^[^0-9]/m$
—-
#将文件的第12到17行内容复制10词放到当前文件的尾部
:1,10g/^/12,17t$
~~~~重复次数的作用
—-
#将chapter开始行下面的第二行的内容写道begin文件中
:g/^chapter/.+2w>>begin
—-
:/^part2/,/^part3/g/^chapter/.+2w>>begin
—-
:/^part2/,/^part3/g/^chapter/.+2w>>begin|+t$
`