Linux_vim_会话和viminfo

所用命令涉及到的帮助入口:

1
2
3
4
5
6
:help mksession
:help 'sessionoptions'
:help source
:help wviminfo
:help rviminfo
:help 'viminfo'

很多软件都具有这样一种功能:在你下一次启动该软件时,它会自动为你恢复到你上次退出的环境,恢复窗口布局、所打开的文件,甚至是上次的设置。

vim有没有这种功能呢?答案当然是肯定的!这需要使用vim的会话(session)及viminfo的保存和恢复功能。

使用会话(session)和viminfo,可以把编辑环境保存下来,然后在下次启动vim后,可以再恢复回这个环境。在开发项目或书写文档时,如果在中途退出了vim而不能恢复原先的编辑环境的话,又要重新打开你所打开的文件,重新定义你的映射(map)、缩写(abbreviate),重新定位你所设定的标记的位置(mark),重新设置项目相关设置(options)等等,不是一般的麻烦!

要恢复上次的编辑环境,我们需要保存两种不同的信息,一种是会话(session)信息,另外一种是viminfo信息。

  • 会话信息中保存了所有窗口的视图,外加全局设置。
  • viminfo信息中保存了命令行历史(history)、搜索字符串历史(search)、输入行历史、非空的寄存器内容(register)、文件的位置标记(mark)、最近搜索/替换的模式、缓冲区列表、全局变量等信息。

会话

我们可以使用:mksession [file]命令来创建一个会话文件,如果省略文件名的话,会自动创建一个名为Session.vim的会话文件。

会话文件,其本质上是一个vim脚本,你可以使用上述命令生成一个session文件,然后再查看其中的内容,就会对session文件有一个深入的认识。

会话文件中保存哪些信息,是由sessionoptions选项决定的。缺省的sessionoptions选项包括:blank, buffers, curdir, folds, help, options, tabpages, winsize,也就是会话文件会恢复当前编辑环境的空窗口、所有的缓冲区、当前目录、折叠(fold)相关的信息、帮助窗口、所有的选项和映射、所有的标签页(tab)、窗口大小。

如果你使用windows上的vim,并且希望你的会话文件可以同时被windows版本的vim和UNIX版本的vim共同使用的话,在sessionoptions中加入slashunix,前者把文件名中的\替换为/,后者会把会话文件的换行符保存成unix格式。

如果你不希望在session文件中保存当前路径,而是希望session文件所在的目录自动成为当前工作目录,那么,需要在sessionoptions去掉curdir,加入sesdir,这样每次载入session文件时,此文件所在的目录就被设为vim的当前工作目录。在你通过网络访问其它项目的session文件时,或者你的项目有多个不同版本(位于不同的目录),而你想始终使用一个session文件时,这个选项比较有用:你只需要把session文件拷贝到不同的目录,然后使用就可以了。设置此选项后,session文件中保存的是文件的相对路径,而不是绝对路径。

我们在上面使用:mksession命令创建了会话文件,那么怎么使用会话文件恢复编辑环境呢?很简单,你只需要使用:source session-file来导入会话文件。因为会话文件是一个脚本,里面保存的是Ex命令,所以source命令只是把会话文件中的Ex命令执行一遍。

viminfo

使用:wviminfo [file]命令,可以手动创建一个viminfo文件。

其实,在vim退出时,每次都会保存一个.viminfo文件在用户的主目录。我们使用:wviminfo命令则是手动创建一个viminfo文件,因为缺省的.viminfo文件会在每次退出vim时自动更新,谁知道你在关闭当前软件项目后,又使用vim做过些什么呢?这样的话,.viminfo中的信息,也许就与你所进行的软件项目无关了。还是手动保存一个保险。

:wviminfo命令保存哪些内容,以及保存的数量,由viminfo选项决定,这个选项的值在windows上和在linux上的缺省值不同,具体含义参阅手册。

要读入你所保存的viminfo文件,使用:rviminfo [file]命令。

现在,先看一下我们当前目录,执行:pwd,显示/home/xcg/vimtest,接下来,执行下面的命令:

1
2
3
4
5
6
:cd src                            "切换到/home/xcg/vimtest/src目录 需要先在外部创建该目录
:set sessionoptions-=curdir "在session option中去掉curdir
:set sessionoptions+=sesdir "在session option中加入sesdir
:mksession vim90.vim "创建一个会话文件
:wviminfo vim90.viminfo "创建一个viminfo文件
:qa "退出vim

退出vim后,在命令行下执行vim,再次进入vim,这时看到的是一个空白窗口。然后执行下面的命令:

1
2
:source ~/vimtest/src/vim90.vim    '载入会话文件
:rviminfo vim90.viminfo '读入viminfo文件

太棒了,又恢复到昨天退出时的状态了!继续工作。不过,每次都要手工修改sessionoptionsviminfo吗?多麻烦啊。别着急,现在是时候介绍vimrc了。

Linux_vimrc

vim安装

Linux下的安装。

The Vim repository at GitHub: Vim is available through git. This is the most straightforward way to get Vim and keep it up-to-date.

You can obtain Vim for the first time with:

1
git clone https://github.com/vim/vim.git

And, if you don’t have local changes, update to the latest version with:

1
2
cd vim
git pull

If you made some changes, e.g. to a makefile, you can keep them and merge with the latest version with:

1
2
3
4
cd vim
git stash
git pull
git stash pop

If you have local changes you may need to merge. If you are sure you can discard local changes (e.g. if you were just trying a patch), you can use:

1
2
git fetch --all
git reset --hard origin/master

Building Vim

Build and install Vim as usual. If you are happy with the defaults:

1
2
3
4
cd src
make distclean # if you build Vim before
make
sudo make install

vimrc在哪

vimrc究竟在哪儿呢?这个问题对一个vim的入门用户来说,可能实在不是个问题,你可能回答:”不就是$HOME/.vimrc吗?”。是的,这个答案正确,不过不是全部。

首先,在Linux下的Vim中输入:version命令(可能你是使用Linux下的vi命令打开编辑器,不过在大多数Linux中,vi命令打开的就是Vim),我们略过不相关的内容,关于vimrc的显示如下(可能你的显示不完全和这里相同):

1
2
3
4
5
6
7
8
9
10
11
12
13
# Linux下的vim
:version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Jun 26 2017 11:44:34)
Included patches: 1-678

system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
system gvimrc file: "$VIM/gvimrc"
user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
...

在上面,我们看到列出了几个vimrc文件,有一个系统的vimrc文件,还有用户的vimrc文件,以及系统和用户gvimrc文件。出于和vi兼容的目的,vim也支持vi的exrc配置文件。

接着,我们在Windows系统中输入:version命令,可以看到如下输出(使用的是预编译的Vim 8.0):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Windows下的vim
VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Jun 28 2022 12:46:00)
MS-Windows 32-bit GUI version with OLE support
Compiled by mool@tororo

system vimrc file: "$VIM\vimrc"
user vimrc file: "$HOME\_vimrc"
2nd user vimrc file: "$HOME\vimfiles\vimrc"
3rd user vimrc file: "$VIM\_vimrc"
user exrc file: "$HOME\_exrc"
2nd user exrc file: "$VIM\_exrc"
system gvimrc file: "$VIM\gvimrc"
user gvimrc file: "$HOME\_gvimrc"
2nd user gvimrc file: "$HOME\vimfiles\gvimrc"
3rd user gvimrc file: "$VIM\_gvimrc"
defaults file: "$VIMRUNTIME\defaults.vim"
system menu file: "$VIMRUNTIME\menu.vim"

比较一下上面两个:version命令的输出,我们发现:

  1. Vim启动时,会先尝试执行用户vimrc,并使用所找到的第一个用户vimrc中的配置,忽略其余的用户vimrc。其次才找系统的vimrc文件。
  2. 在Linux下使用的vimrc文件名为.vimrc,在Linux下,如果未找到名为.vimrc的文件,也会尝试查找名为_vimrc文件;在Windows下也是这样,只不过查找顺序颠倒一下,如果未找到名为_vimrc的文件,会去查找.vimrc
  3. 在Windows下因为不支持以点.开头的文件名,vimrc文件的名字使用_vimrc。有两个可选的用户vimrc文件,一个是$HOME\_vimrc,另外一个是$VIM\_vimrc
  4. 从这里可以看出,vimrc的执行先于gvimrc。所以我们可以把全部vim配置命令都放在vimrc中,不需要用gvimrc。

对于vim初学者,如果不知道$HOME或者$VIM具体是哪个目录,可以在vim中用下面的命令查看:

1
2
:echo $VIM     # /usr/shared/vim
:echo $HOME # /home/xcg

分别打印的是/usr/share/vim(vim目录),/ssd_b/xcg(家目录)。

选择vim配置

Windows版本的Vim在安装时,缺省会安装一个$VIM/_vimrc,你可以直接修改这个_vimrc,加入你自己的配置(使用:e $VIM/_vimrc即可打开此文件)。或者,你也可以在Windows中增加一个名为HOME的环境变量(控制面板 -> 系统 –> 高级 –> 环境变量),然后把你的vimrc放在HOME环境变量所指定的目录中。从上面:version命令的输出看到,$HOME/_vimrc如果存在,就会执行这个文件中的配置,从而跳过$VIM/_vimrc

  1. 如果使用vim -u filename命令来启动Vim,则会用你指定的filename作为Vim的配置文件(在调试你的vimrc时有用);
  2. 如果用vim -u NONE命令启动Vim,则不读取任何vimrc文件:当你怀疑你的vimrc配置有问题时,可以用这种方式跳过vimrc的执行。

总结

Linux和Windows下vim的启动优先寻找$HOME/.vimrc(Windows下是_vimrc),即用户自己的配置。用户配置文件不存在时,使用的是系统的配置文件$VIM/vimrc

vimrc初步

所用命令的帮助入口:

1
2
3
4
:help compatible
:help mapleader
:help map
:help autocmd

vim的环境依赖会话(session)文件和viminfo文件,其中‘sessionoptions’选项和‘viminfo’选项的配置可能会根据需要进行调整。但如何保存所做的调整呢?需要vimrc文件。

当vim在启动时,如果没有找到vimrc或gvimrc,它缺省为VI兼容的模式。这意味着,只能使用VI所具备的功能,而vim中的大量扩展功能将无法使用。

vim中自带了一个vimrc例子,从这个例子开始分析。

下面以Linux下的vim为例。

示例的vimrc(名为vimrc_example.vim)通常位于/usr/share/vim/vimXXX/目录下,其中vimXXX与使用的vim版本有关。

首先把这个示例的vimrc拷贝到相应的目录,在Linux下,应该把它拷贝到你的home目录下,名字为”.vimrc”。

下面是shell命令:

1
cp /usr/share/vim/vim90/vimrc_example.vim ~/.vimrc 

或者你在vim中执行下面的命令,和上面的shell命令完成相同的功能:

1
:!cp $vimRUNTIME/vimrc_example.vim ~/.vimrc 

可以先读一下现在的vimrc,看看它都设定了什么:

1
:e ~/.vimrc 

这是一个注释良好的文件,不需要多解释。

对windows版本的vim,它已经默认的有了一个vimrc,可以在vim在使用下面的命令来查看它。

1
:e $vim/_vimrc 

在这个文件中,它包含了上面提到的vimrc_example.vim。同时,它会把vim设置的更符合windows的操作习惯。比如,支持CTRL-C拷贝,CTRL-V粘贴等等。Windows下的用户,可以使用$vim/_vimrc来做为第一个vimrc。

顺便提一句,在unix/linux中,文件名可以以”.”开头,表明此文件是隐藏的。而在windows中,不允许文件名以”.”开头,所以,windows版本的vim,将读取_vimrc来做为自己的配置文件。

打开vimrc的快捷方式

在今后使用vim的日子里,会频繁的更改vimrc。所以需要设置一些快捷方式,使我们能快速的访问vimrc。

把下面这段内容拷贝到vimrc中:

1
2
3
4
5
6
7
8
9
1  "Set mapleader
2 let mapleader = ","
3
4 "Fast reloading of the .vimrc
5 map <silent> <leader>ss :source ~/.vimrc<cr>
6 "Fast editing of .vimrc
7 map <silent> <leader>ee :e ~/.vimrc<cr>
8 "When .vimrc is edited, reload it
9 autocmd! bufwritepost .vimrc source ~/.vimrc
  • 在vimrc中,双引号开头的行,将被当作注释忽略。
  • 第2行,用来设置mapleader变量,当mapleader为未设置或为空时,使用缺省的”\”来作为mapleader。

mapleader变量是作用是什么呢?看下面的介绍。

  • 第5行定义了一个映射(map),这个映射把<leader>ss,映射为命令:source ~/.vimrc<cr>。当定义一个映射时,可以使用<leader>前缀。而在映射生效时,vim会把<leader>替换成mapleader变量的值。也就是说,我们这里定义的<leader>ss在使用时就变成了”,ss“,当输入这一快捷方式时,就会source一次~/.vimrc文件(也就是重新执行一遍.vimrc文件)。
  • 第7行,定义了<leader>ee快捷键,当输入,ee时,会打开~/.vimrc进行编辑。
  • 第9行,定义了一个自动命令,每次写入.vimrc后,都会执行这个自动命令,source一次~/.vimrc文件。

有了上面的快捷键,我们就能快速的打开vimrc文件编辑,快速重新source vimrc文件,方便多了。注意,,ee,ss命令不是在冒号模式下输入,而是空悬模式下输入,在右下角可看到输入的命令。

使用同一个vimrc文件

为了实现无论在windows还是在linux中都能使用vim作为缺省编辑器。并且,想使用同一个vimrc文件。因此定义了一个MySys()函数,用来区分不同的平台,以进行不同的配置。

另外,在编辑vimrc文件时,最好新开一个标签页来编辑,而不是在当前窗口中。因此,定义了SwitchToBuf()函数,它在所有标签页的窗口中查找指定的文件名,如果找到这样一个窗口,就跳到此窗口中;否则,它新建一个标签页来打开vimrc文件。

注:标签页(tab)功能只有在vim 7.0版本以上才支持。

下面是示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
" Platform
function! MySys()
if has("win32")
return "windows"
else
return "linux"
endif
endfunction

function! SwitchToBuf(filename)
"let fullfn = substitute(a:filename, "^\\~/", $HOME . "/", "")
" find in current tab
let bufwinnr = bufwinnr(a:filename)
if bufwinnr != -1
exec bufwinnr . "wincmd w"
return
else
" find in each tab
tabfirst
let tab = 1
while tab <= tabpagenr("$")
let bufwinnr = bufwinnr(a:filename)
if bufwinnr != -1
exec "normal " . tab . "gt"
exec bufwinnr . "wincmd w"
return
endif
tabnext
let tab = tab + 1
endwhile
" not exist, new tab
exec "tabnew " . a:filename
endif
endfunction

"Fast edit vimrc
if MySys() == 'linux'
"Fast reloading of the .vimrc
map <silent> <leader>ss :source ~/.vimrc<cr>
"Fast editing of .vimrc
map <silent> <leader>ee :call SwitchToBuf("~/.vimrc")<cr>
"When .vimrc is edited, reload it
autocmd! bufwritepost .vimrc source ~/.vimrc
elseif MySys() == 'windows'
" Set helplang
set helplang=cn
"Fast reloading of the _vimrc
map <silent> <leader>ss :source ~/_vimrc<cr>
"Fast editing of _vimrc
map <silent> <leader>ee :call SwitchToBuf("~/_vimrc")<cr>
"When _vimrc is edited, reload it
autocmd! bufwritepost _vimrc source ~/_vimrc
endif

" For windows version
if MySys() == 'windows'
source $VIMRUNTIME/mswin.vim
behave mswin
endif

注意:在windows中也定义了一个”HOME”环境变量,然后把_vimrc放在”HOME”环境变量所指向的目录中。这样才能在windows中使用。

好了,现在我们知道如何永久更改‘sessionoptions’选项和‘viminfo’选项了,把对它们的配置放入vimrc即可。

vim自带的示例vimrc中,只定义最基本的配置。

http://www.amix.dk/vim/vimrc.html有一个非常强大的vimrc,有人戏称为”史上最强的vimrc”,或许有些言过其实。不过,如果通读了这个vimrc,相信能从中学到很多。[这里](http://blog.csdn.net/redguardtoo/archive/2006/09/03/1172136.aspx)有一个redguardtoo修改过的版本,可以对照参考一下。但是不要照拷这两个vimrc,可能这个文件的设定并不符合你的习惯。另外,这个文件的设定,可能也不能在当前的工作环境中运行。