vi/vim使用进阶: 使用会话和viminfo

<< 返回vim使用进阶: 目录

本节所用命令的帮助入口:

: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’中加入‘slash’‘unix’,前者把文件名中的’\’替换为’/’,后者会把会话文件的换行符保存成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/easwy/src/vim70″,接下来,执行下面的命令:

:cd src                            "切换到/home/easwy/src/vim70/src目录
:set sessionoptions-=curdir        "在session option中去掉curdir
:set sessionoptions+=sesdir        "在session option中加入sesdir
:mksession vim70.vim               "创建一个会话文件
:wviminfo vim70.viminfo            "创建一个viminfo文件
:qa                                "退出vim

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

:source ~/src/vim70/src/vim70.vim  '载入会话文件
:rviminfo vim70.viminfo            '读入viminfo文件

太棒了,又恢复到昨天退出时的状态了!继续工作~~~~

不过,每次都要手工修改‘sessionoptions’‘viminfo’吗?多麻烦啊……别着急,现在是时候介绍vimrc了,请移步下一章: vimrc初步。

[参考文档]

  1. vim手册
  2. vim中文手册

<< 返回vim使用进阶: 目录

“vi/vim使用进阶: 使用会话和viminfo”的38个回复

  1. 博主,看了你这个文章后,我觉得要是可以有个插件自动为project提供对session和viminfo文件的管理就太好了。但是在vim.org上没有找到能够同时对他们提供管理的plugin,所以我自己写了一个,昨天刚刚提交到vim.org,现在功能还不算复杂,希望您能帮忙看看给些意见(请访问http://brantchen.com/2014/08/17/my-vim-plugin-session-viminfo-management/),谢谢:) 另外,您知道有可以同时管理session和viminfo的插件吗?我想借鉴和用用,以便评估是不是需要继续开发我自己的插件。不过总的来说,我觉得我的插件已经满足了我的需求了,哈哈。

  2. 非常感谢楼主的分享.
    想请教下, 可不可以自动生成session和viminfo.
    VIM的脚本必须在VIM内通过:source来执行么?
    可不可以在SHELL或者C中调用执行.
    谢谢了.

    1. @lyle, viminfo是自动保存的,session可以用autocmd在退出vim时自动保存。

      为什么要在shell中调用vim脚本?如果是想自动处理文本文件的话,可以试试sed或awk

  3. 我想把vim插件中的miniBufExplorer和NERDTree,TagList整合起来所以加了let g:winManagerWindowLayout=”NERDTree|TagList|miniBufExpl”
    map :WMToggle
    可是按下F3后NERDTree|TagList可以正常打开,而minibufExplorer无法打开提示说:是找不到这个插件
    我的.vimrc的部分配置如下:
    let g:miniBufExplMapWindowNavVim = 1
    207 let g:miniBufExplMapWindowNavArrows = 1
    208 let g:miniBufExplMapCTabSwitchBufs = 1
    209 let g:miniBufExplModSelTarget = 1
    210 let g:miniBufExplMoreThanOne=0
    211
    212 let g:NERDTree_title=”[NERDTree]”
    213 let g:winManagerWindowLayout=”NERDTree|TagList|miniBufExpl”
    214
    215 function! NERDTree_Start()
    216 exec ‘NERDTree’
    217 endfunction
    218
    219 function! NERDTree_IsValid()
    220 return 1
    221 endfunction
    222
    223 map :WMToggle
    求高手指教

    1. 要把插件整合进WinManager窗口中,需要插件实现一些接口的。印象中NERDTree和miniBufExplorer是没有实现这些接口的,所以应该无法用WinManager插件管理

  4. @barbypie
    看错误提示,你应该是在shell里执行这个命令吧?这是个vim命令,需要在vim中执行,还有,如果在vim中执行”:!mksession [file]”也会有这个错误提示,正确的用法是”:mksession [file]”

  5. 非常感谢博主!!
    我在win7下使用gvim.编辑$vim/_vimrc文件,总是提示readonly,虽然在保存时使用!强制保存,总也保存不上。我该怎样处理,才能编辑$vim/_vimrc呢?

  6. 你好博主,我刚刚接触Linux和Vim。 想请教一下,我运行 mksession [file] 后,提示: -bash: mksession: command not foud 。 应该如何处理? 多谢多谢!

  7. 你好,博主,有个问题请教您:在shell里面输入gvim后,弹出一个小窗口,那键盘上有什么快捷键能一下子最大化gvim么?谢谢

  8. @clwyd
    在vim手册里有这样一段话:(:help ‘sessionoptions’)

    Don’t include both “curdir” and “sesdir”.
    When “curdir” nor “sesdir” is included, file names are stored with absolute paths.

    你应该在sessionoptions设置curdir,去掉sesdir。关于sesdir的含义在手册里有明确说明。

  9. 补充一下,两个会话文件在保存时,都设置了sessionoptions-=curdir,sessionoptions+=sesdir

    clwyd :
    我比较了保存于根目录下和$VIM/sessions目录下的会话文件,发现前一会话文件保存的文件名都以相对路径保存,而后一文件是以绝对路径保存,这应该是用前一会话文件进行恢复发生混乱的原因。那么有什么办法能让保存在根目录下的会话文件也自动保存绝对路径呢?

    clwyd :
    楼主,我有如下结构的会话
    1.txt
    2.txt
    3.txt
    data1/5.txt
    data1/6.txt
    data2/7.txt
    直接用mks保存会话文件于根目录下,恢复时不能正常恢复子目录下的文件,比如有时候会出现在data1/data1/下寻找6.txt的情况,这是何解?
    如果用您的方式,将会话文件保存于另外的文件夹如$VIM/sessions,则可以正常恢复。

  10. 我比较了保存于根目录下和$VIM/sessions目录下的会话文件,发现前一会话文件保存的文件名都以相对路径保存,而后一文件是以绝对路径保存,这应该是用前一会话文件进行恢复发生混乱的原因。那么有什么办法能让保存在根目录下的会话文件也自动保存绝对路径呢?

    clwyd :
    楼主,我有如下结构的会话
    1.txt
    2.txt
    3.txt
    data1/5.txt
    data1/6.txt
    data2/7.txt
    直接用mks保存会话文件于根目录下,恢复时不能正常恢复子目录下的文件,比如有时候会出现在data1/data1/下寻找6.txt的情况,这是何解?
    如果用您的方式,将会话文件保存于另外的文件夹如$VIM/sessions,则可以正常恢复。

  11. 楼主,我有如下结构的会话
    1.txt
    2.txt
    3.txt
    data1/5.txt
    data1/6.txt
    data2/7.txt
    直接用mks保存会话文件于根目录下,恢复时不能正常恢复子目录下的文件,比如有时候会出现在data1/data1/下寻找6.txt的情况,这是何解?

    如果用您的方式,将会话文件保存于另外的文件夹如$VIM/sessions,则可以正常恢复。

  12. 楼主,为什么每次用vim打开一个文件之后(假设文件名为data.txt)总会出现下面的语句:
    $ vi data.txt
    “data.txt” 5L, 27C
    Press ENTER or type command to continue

    我的.vimrc设置如下:
    “在vim退出前自动保存session
    autocmd VimLeave * mksession! Session.vim

    “在vim打开时自动打开session
    if filereadable(“Session.vim”)
    source Session.vim
    endif

  13. 您好,博主,我保存了session,当恢复session后,原来buffers内的文件的确都恢复出来了,但是我发现当前文件所在目录没有自动恢复,仍然还是默认的~/home/xxx,不是当前文件所在的目录~/home/xxx/src,请问是不是我操作会有问题,还是mksession命令是不能保存文件所在目录的信息?
    我在.vimrc中已经设置了
    set sessionoptions-=curdir
    set sessionoptions+=sesdir

  14. 请教一下Easwy,为啥我重新打开vim执行source的时候,会出现多个
    “-MiniBufExplorer-“[New File]
    “-MiniBufExplorer-“[Not edited]–No lines in buffer–
    Press Enter or type command to continue
    按回车后会显示3栏,顶上是miniBuffer,显示不正常,空白,中间和下面是两个一样的正常文件(同一个文件)
    背景:安装了MiniBufExplorer,Lookupfile
    mksession后会这样

    miniBuff和lookupfile配置如下
    “miniBuffExpl by LX
    let g:miniBufExplMapWindowNavVim = 1
    let g:miniBufExplMapWindowNavArrows = 1
    let g:miniBufExplMapCTabSwitchBufs = 1
    let g:miniBufExplModSelTarget = 1
    “mksession by LX
    map mks :mksession! C:\My Dropbox\vim\lx.vim
    map sou :source c:\My Dropbox\vim\lx.vim
    map wv :wviminfo c:\My Dropbox\vim\lx.viminfo
    map rv :rviminfo c:\My Dropbox\vim\lx.viminfo
    map vimrc :e c:\My Dropbox\vim\_vimrc
    autocmd! bufwritepost _vimrc source c:\My Dropbox\vim\_vimrc

  15. chewe :

    请问,那有什么办法恢复这些动态窗口呢?谢谢!

    动态窗口是动态生成的,不需要恢复。
    下次进入vim后再把生成这些动态窗口的插件打开,插件会自动生成的。

  16. (以下为CSDN评论的转帖)

    zhmsong 发表于2008-03-27 16:00:10 IP: 220.181.48.*
    感谢,很好

    #kevin 发表于2008-04-25 14:13:52 IP: 219.137.79.*
    我执行gvim &说这个命令没找到。我的linux里是有装vim的喔。是什么原因呢?

    2008-06-11 14:00:40作者回复
    可能是你的vim在编译时没有编译图形化版本,你自己重新编译一下吧

    #wuren 发表于2008-05-18 07:50:25 IP: 67.55.20.*
    说明你的系统里有vim,但是没有gvim

    #popeye 发表于2008-09-12 21:21:53 IP: 202.99.210.*
    你好,真的感谢您分享你的经验,使我这样的新手获益菲浅!

    我在学习你的这篇文章时,用mksession做了一个Session.vim后,等下次用gvim导入时,窗口很乱,和保存时的也不一样,,我保存的时候有的窗口:MiniBufExplorer(有两个文件),,,FileList,,,以及打开代码的窗口,,但是恢复的时候窗口很乱,,也不行。我的 sessionoptions和你文章里说的一样,我的环境是ubuntu8.04linux,,,。在只编辑一个文件,而且只有一个窗口的情况些,恢复的比较好。但是多窗口就是不行。。望指教!!

    2008-10-29 14:56:45作者回复
    你在mksession时,要把那些由插件动态生成的窗口关掉(例如MiniBufExplorer窗口、FileList窗口等),因为vim在恢复会话时,没法恢复这些动态的窗口。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注