Vim笔记
学习资料
《Vim实用技巧》第二版中文版 关于vim的好书,值得反复学习。
本书源码下载: https://pragprog.com/titles/dnvim2/practical-vim-second-edition/
可用于跟着书本训练。
本文档是该书的阅读笔记,同时不定时杂糅其他Vim的资料和学习笔记,vimrc配置单独笔记记录。
其他资料包括:
vim官网文档
bash
:h vimtutor
vim 复制粘贴,宿主机与虚拟机
参考:https://liushiming.cn/article/copy-and-paste-in-vim.html
bash
vim --version | grep clipboard
+clipboard 代表支持与系统剪切板交互,-代表不支持。
安装桌面版本一般可以解决,如:
bash
sudo apt install vim-gtk3
设置 vim 默认使用系统剪贴板。
确定 vim 支持+clipboard后,如果想y/p直接和系统剪贴板打通,可以在~/.vimrc中加上以下配置):
txt
set clipboard^=unnamed,unnamedplus
其中 unnamed 代表*寄存器
,unnamedplus 代表+寄存器
。在 mac 系统中,两者都一样;一般在 linux 系统中+
和*
是不同的,通过快捷键<C+c>复制的只会覆盖*寄存器
,但通过鼠标右键复制的,会同时覆盖*
和+
寄存器。(在linuxmint下面实操是如此)。在虚拟机里面,寄存器+
是直接跟宿主机的剪切板映射的,*
只能映射到虚拟机。综上,使用寄存器+
才可以打通宿主机和虚拟机和vim,而且是双向打通。
然后可以通过映射键盘来使用+寄存器
。
vim基本配置
bash
vim -u NONE -N
-u NONE 标志让 Vim 在启动时不加载你的vimrc,这样,你的定制 项就不会生效,插件也会被禁用。当用不加载 vimrc 文件的方式启动 时,Vim会切换到 vi 兼容模式,这将导致很多有用的功能被禁用,-N 标志则设置 ‘nocompatible’ 选项,防止进入 vi 兼容模式。对于本书中的大多数例子来说,用 vim -u NONE –N启动 Vim应该可以确保你获得与书中的描述相符的体验,不过也有几处例外。有些 Vim的内置功能是由 Vim 脚本实现的,也就是说,只有在激活插件时, 它们才会工作。下面的文件中包含了激活 Vim 内置插件的最小配置。
Vim为什么设定nocompatible?
compatible这个词是“兼容的”这个意思。
nocompatible就是不兼容的。具体是不兼容什么,简单点说就是很老的vi的格式。vim是vi的扩展,nocompatible就是指vim在工作的时候不需要考虑和vi兼容。vim 是 vi 的最流行的加强版。它在 vi 的基础上增加了很多功能,但就不与 vi 完全兼容了。
set compatible 就是让 vim 关闭所有扩展的功能,尽量模拟 vi 的行为。
但这样就不应用 vim 的很多强大功能,所以一般没有什么特殊需要的话(比如执行很老的 vi 脚本),都要在 vim 的配置开始,写上 set nocompatible,关闭兼容模式。
由于这个选项是最最基础的选项,会连带很多其它选项发生变动(称作副作用),所以它必需是第一个设定的选项。
具体设置:一般在vimrc中修改set compatible为set nocompatible
filetype plugin indent on 什么含义?
filetype plugin indent on
相当于
filetype on " 打开文件类型检测功能
filetype plugin on " vim加载文件类型插件
filetype indent on " 允许vim为不同类型的文件定义不同的缩进格式
Vim的不同版本和功能列表
不同的版本和安装方式(编译参数)可能导致功能列表的差异。
查看版本和安装信息:
bash
:version
:h +feature-list
Vim的功能集包括small、normal、big和huge
,在现代计算机上,没理由不用Vim的huge功能集。
关于移动的快捷键
基於单词移动:
段落移动:
删除修改一行:
撤销和重复:
和任何其他编辑器一样,Vim 也记录了每一步操作。按u
键可以撤销最后一次操作,而Ctrl + r
组合键则可以重做此操作。
搜索结果高亮:
搜索过程中常用到的一个选项是set hlsearch
可以用 :noh
命令清除高亮显示。 还有一个技巧是使用 set incsearch
。这个选项会在读者还未完整输入搜索命令时,就将光标动态跳转到第一个匹配处。
关于set paste:
Vim 会在粘贴过程中自动缩进代码或添加注释。为避免这种情况,在粘贴代码之前先禁用缩进和自动注释,方法是运行:set paste
命令,粘贴完成之后,恢复的命令为:set nopaste
。从 8.0 版本开始,Vim 默认启用括号化粘贴模式(bracketed paste mode),从而基本解决了这些问题。
用*
来搜索光标下的单词。
插入模式
vim的插入模式是一般编辑器的普通模式。
vim的普通模式、命令行模式、可视模式才是vim的灵魂所在。
自动补全:使用 ctrl-x + ctrl-n
,进行buffer补全。
普通模式
J命令 用来连接当前行于下一行(合并成当前行)
gu/gU 改变当前字符,gu/gUaw 改变当前单词,gugu/gUgU 改变当前整行。
f{char} 当前行从光标往后搜索字符 ;继续上次搜索,反向/回退搜索
F{char} 当前行从光标往前面搜索
与命令/word 搜索到结果后n是下一个结果,N是上一个结果。逻辑类似。Vim中还存在多种对应的操作。
/word命令查找全文,n下一个、N上一个结果。
dw 删除当前光标到单词尾部,db删除当前光标到单词头部,均不包括光标所在字符;daw:删除光标所在的整个单词和空格。
s命令:删除当前字符并进入insert模式编辑
>>或者 >$ 缩进当前行 >G 缩进所有(文末)
gg到第一行 G 到最后一行
R 命令可以由普通模式进入替换模式
可以用 vit 来选择标签里的内容。vit 可被解读为高亮选中标签内部的内容(visually select inside the tag),其中,it 命令是一种被称为文本对象(text object)的特殊动作命令。如<a href="#">one</a>
可视模式下的vit然后U:one变成ONE
等价于普通模式下的gUit。都是选中标签内的one。
可视模式
进入可视模式,小写v 字符可视模式 大写V 行可视模式 <C-v>
块可视模式。
可视模式下,选中后s或者c命令是替换模式,选中什么就替换成空,然后自行编辑;
选中后r是替换每个选中的字符变成修改的字符,单个字符。
可视模式可用于编辑块文本,如:
sh
var foo = 1
var bar = 'a'
var foobar = foo + bar
在每一行后加;
号
C-vjj$ A;ESC,
很方便高效。
命令行模式
命令行模式,也就是ex命令行模式
初时,先有 ed,ed 为 ex
之父,ex 为 vi 之父,而
vi为 Vim 之父。
ex命令行模式是ex 编辑器的余风遗韵。
有时insert模式下直接粘贴复制会出现格式异常,可以使用命令
:set paste
来进入,此时粘贴无格式异常。
全局查找并且替换:
sh
:%s/Line/line/g
不加%
,范围是当前行,不加/g
,范围是只替换查找到的第一个对象。
替换之前先确认,c参数(confirm):
sh
:%s/Line/line/gc
同时编辑多个文件,vim file1.txt file2.txt
文件编辑的其他命令
切换缓冲区(文件):buffer + 序号
实际上使用可以使用:ls
然后:buffer + 序号
。
如果文件本身不多,使用:ls
然后:bn
直接下一个更快,不用记住序号。
sh
bn == bnext;
bp == bprev
bf == bfirst
bl == blast
bd == bdelete (删除缓冲区)
命令:e filename.txt
打开另一个文件
当文件由:e 命令加载,你将无法用:n 或:N 命令来切换文件。这时要使用:buffer 命令加缓冲区号码,来切换文件。
以上切换方式,均可以使用yank来实现跨文件粘贴复制,很高效。
插入整个文件到另一个文件
在当前文件file1的普通模式中,:r file2可以直接将files2的所有内容都插入到file1光标所在行的下面。
文件另存为,使用 :w newfile,这样就保存了一份副本了。
保存以后,当前正在编辑的文件并不会切换,还是在原来的文件里面。
sh
:num1,num2操作,可以指定范围操作,如
:2p 2d :2,5p :2,5d
:.,$ 圆点代表当前行,$代表当前行到文本最后一行,中间逗号不能省略,否则只代表当前行。
:%代表当前文件所有行,等效于:1,$
复制和移动行:
text
:t == :co == :copy
:m == :move
:t.
命令会创建一个当前行副本,另外一种做法则是用普通模式的
复制和粘贴命令(yyp)来达到同样的效果。这两种复制当前行的技术
有个需要关注的差别:yyp
会使用寄存器:t
. 则不会。因此,当我不
想覆盖默认寄存器中的当前内容时,有时会使用:t
. 来复制行。
普通模式适合就近操作,ex命令可以远距离操作。
在指定范围上执行普通模式命令:normal
重复上次ex命令:@:
自动补全:tab
<C-d>
显示能补全的列表
把当前单词插入命令行
在 Vim 的命令行下, <C-r><C-w>
映射项会复制光标下的单词并
把它插入命令行中。可以利用这一功能减少击键的次数。
普通模式下,按q:
调出命令行窗口
当命令行窗口处于打开状态时,它会始终拥有焦点。这意味着,除 非关闭命令行窗口,否则无法切换到其他窗口。要想关闭命令行窗口, 可以执行 :q 命令(就像关闭普通 Vim 窗口那样),或是按 <CR>
。
在命令行窗口内按<CR>
时,该命令在活动窗口的上下文中执行。活动窗口是指在调出命令窗口前,处于活动状态的那个窗口。当命令行窗口处于打开状态时,Vim 并不会提示哪个窗口是活动窗口,因此如果使用了分割窗口,就需要特别留意。
ex命令行真正执行shell命令,使用:!
如:
:!python %
%代表当前文件,python即shell命令。
:shell
直接调出整个shell,使用完之后exit,回到之前的vim状态。
把Ex命令存成脚本并加载,可以用 :source
来执行batch.vim脚本(参见 :h source)。脚本中 的每一行都会被当成一条 Ex 命令执行,就像在 Vim 的命令行中输入这 些命令一样。
:argdo
命令表示对缓冲区列表里面的每个文件都执行命令:
sh
:argdo source batch.vim
命令行模式:shell 可以打开shell子进程,exit之后回到vim原来的界面。
由于vim本身自己在shell中,所以这种方式不如直接在vim当前界面<C+z>直接后台挂起,然后fg。
分屏目录浏览:
上下打开当前目录 :He
-> :Hexplore
在上面打开加感叹号!
, :He!
左右打开当前目录::Ve
全称为 :Vexplore
(在左边分屏间浏览目录,要在右边则是 :Ve!
)
分屏打开文件:
- :sp filename.txt split默认是水平分割,即上下打开
- :vs filename.txt vsplit是垂直分割,即左右打开
窗口跳转:
text
<C-W> 加方向键(h、j、k、l、<Left> 等等)可以在窗口之间跳转
<C-W>w 跳转到下一个(往右和往下)窗口,如果已经是右下角的窗口,则跳转到左上角的窗口
<C-W>W 跳转到上一个(往左和往上)窗口,如果已经是左上角的窗口,则跳转到右下角的窗口
<C-W>n 或 :new 打开一个新窗口
<C-W>c 或 :close 关闭当前窗口;当前窗口如果已经是最后一个则无效
<C-W>q 或 :quit 退出当前窗口,当最后一个窗口退出时则退出 Vim
<C-W>o 或 :only 只保留当前窗口,关闭其他所有窗口
<C-W>s 和 :split 作用相同,把当前窗口横向一分为二
<C-W>v 和 :vsplit 作用相同,把当前窗口纵向一分为二
<C-W>= 使得所有窗口大小相同(当调整过终端或图形界面 Vim 的窗口大小后特别有用)
<C-W>_ 设置窗口高度,命令前的数字表示高度行数,默认为纵向占满(想专心编辑某个文件时很有用)
<C-W>| 设置窗口宽度,命令前的数字表示宽度列数,默认为横向占满
<C-W>+ 增加窗口的高度,命令前的数字表示需要增加的行数,默认为 1
<C-W>- 减少窗口的高度,命令前的数字表示需要减少的行数,默认为 1
<C-W>> 增加窗口的宽度,命令前的数字表示需要增加的列数,默认为 1
<C-W><lt>(提醒,我们用 <lt> 表示“<”键)减少窗口的宽度,命令前的数字表示需要增加的列数,默认为 1
标签页跳转:
text
在已有命令行模式命令前加 tab␣ 可以在新标签页中展示命令的结果,如 :tab help
可以在新标签页中打开帮助,:tab split 可以在新标签页中打开当前缓冲区
:tabs 展示所有标签页的列表
:tabnew 或 :tabedit 可以打开一个空白的新标签页,后面有文件名的话则打开该文件
:tabclose 可以关闭当前标签页(如果标签页里只有一个窗口,使用窗口关闭命令<C-W>c 应该更快)
:tabnext、gt 或 <C-PageDown> 可以切换到下一个标签页
:tabNext、:tabprevious 、gT 或 <C-PageUp> 可以切换到上一个标签页
:tabfirst 或 :tabrewind 切换到第一个标签页
:tablast 切换到最后一个标签页