如何在Vim中保存和恢复多个不同的会话?


367

根据我在Vim中的任务,我会打开几个选项卡。

如何保存不同的会话以供以后使用?


16
@ldigas我认为ppl在这里找到问题(使用大字体,出色的格式...)比在旧学校论坛或终端文档上,或者,man
天生

6
@ldigas我个人一直对手册页b / c感到害怕,因为它们没有足够愚蠢的东西。与linux中的其他所有东西一样,它具有陡峭的学习曲线。
2012年

45
@Idigas-我认为您没有意识到我们,Google的集体智慧和堆栈溢出元知识管理之间的区别-这只是获得答案的一种更好的方式-您需要什么,而不是一长串的深奥选择,本页也说明了陷阱的现实世界体验,通常还有一些巧妙的捷径可以使您的生活更轻松。这同样适用于我看过的几乎所有手册(也许 php在线手册除外)。Viva stackoverflow!
ErichBSchulz

2
@ldigas,人们可以将其用作将来的参考,因为其他人可能需要它。
曼苏罗

4
@idigas我认为这些问题在一定意义上是真实的,vim初学者对帮助系统以及如何使用它并不了解很多,但是如果他们经验丰富,他们将知道如何在vim中找到自己的方法。
Edgar Klerks

Answers:


494

你想要类似的东西

:mksession ~/mysession.vim

然后,稍后您可以获取该vim文件,并返回原来的会话:

:source ~/mysession.vim

或使用-S选项打开vim:

$ vim -S ~/mysession.vim

27
噢,我几乎忘记了您可以通过键入以下内容来加载它:gvim
-S〜

1
谢谢@Benj。我是vim的新手。如何在命令行中“获取”?
Jogusa,

1
哎呀!对不起Benj,我的意思是命令模式。我已经找到了它:``:source〜/ mysession.vim´´。
Jogusa,

8
简短的是:so〜/ file。如果您碰巧想获取当前文件,则简单的:so%将为您完成工作。
Daniel Baulig 2011年

14
如果您未指定会话文件名,则默认为写入和读取Session.vim。因此,如果您只想在当前目录中保存一个会话,则可以使用vim :mksession:mks从vim中保存当前会话,然后仅vim -S打开它进行备份。
anishpatel

59

您可能需要在vimrc中设置这些会话选项。保存会话后更改vimrc时,尤其令人讨厌的选项。

set ssop-=options    " do not store global and local values in a session
set ssop-=folds      " do not store folds

1
大!我昨天确实有这个问题。非常感谢!
2009年

40

注意::mksession不会将更改保存到您所做的任何文件中。假设我将从那里开始,那么在保存会话后我就犯了关闭vim的错误。但是,下次我打开会话时,对文件所做的更改就消失了。


11
这应该附带与之相关的任何答案:mksession
Morgan Wilde

1
是的,您可能想跟进:wqa
JonnyRaa 2015年

11
或仅需:xa少一击。好极了!
罗宾2015年

您也可以将vim设置为自动在您的文件中保存文件(如果您喜欢这种东西).vimrcvimrc au FocusLost * silent! wa 这将在缓冲区失去焦点时自动保存。
grego

32

如果您使用NERDTree作为文件浏览器/破折号,我建议您使用xolox / vim-session插件,而不要使用内置的:mksession命令。由于某些原因,:mksession无法还原NERDTree缓冲区。您的里程可能会有所不同,但我想我会分享我的经验。


对于的MacVim,我需要确保:let g:nerdtree_tabs_open_on_gui_startup=0let g:nerdtree_tabs_open_on_new_tab=0作出xolox / vim的会话的作品。

18

如果您想在不使用任何插件的情况下自动化该过程,则可以使用Goaway并Vim Tips Wiki返回

每次退出Vim都会将当前会话保存在 ~/.vim/sessions并在Vim打开后再次加载。它也基于您当前的路径,因此,如果从不同目录打开Vim,您将拥有不同的会话,这在处理不同项目时非常有用。

只需编辑~/.vimrc文件并添加以下内容:

function! MakeSession()
  let b:sessiondir = $HOME . "/.vim/sessions" . getcwd()
  if (filewritable(b:sessiondir) != 2)
    exe 'silent !mkdir -p ' b:sessiondir
    redraw!
  endif
  let b:filename = b:sessiondir . '/session.vim'
  exe "mksession! " . b:filename
endfunction

function! LoadSession()
  let b:sessiondir = $HOME . "/.vim/sessions" . getcwd()
  let b:sessionfile = b:sessiondir . "/session.vim"
  if (filereadable(b:sessionfile))
    exe 'source ' b:sessionfile
  else
    echo "No session loaded."
  endif
endfunction

" Adding automatons for when entering or leaving Vim
au VimEnter * nested :call LoadSession()
au VimLeave * :call MakeSession()

即使是初学者这个脚本是有点容易理解和定制。

请注意,该脚本仅适用于Unix系统(MacOS / Linux),需要对其进行调整以在Windows上运行。


更新:添加0xc0de的建议,VimEnter如果希望Vim 仅在不提供任何参数的情况下加载会话,则可以将这些行替换为:

if(argc() == 0)
  au VimEnter * nested :call LoadSession()
endif

1
您可能只想在没有为vim提供参数的情况下打开会话。if argc() == 0 au VimEnter * nested :call LoadSession() end
2015年

感谢@ 0xc0de,一个很好的建议(我什至自己开始使用它)。我已经更新了答案。
mathielo

我将如何修改它,以便如果我使用参数打开vim时也不会保存该会话
Manhattan Dr.

很好,但是`exe'source'b:sessionfile`需要一个点吗?问题是自动加载会话取决于当前主目录(通过pwd),如何将其设置为退出vim之前的最后一个工作目录?这样它可以加载上一个工作会话,而不是加载下一个会话~/
范阿贝尔

如果你希望能够有会议,但仍打开目录的单个文件,而不会覆盖它看看我的这个修改后的版本在不同的答案:stackoverflow.com/questions/1642611/...
PMunch

6

这个任务有一个非常有用的插件vim-startify,它可以处理许多其他事情,例如最近打开的文件等,它也具有非常简单的界面。

我从几天开始一直在使用它,直到现在为止,它一直运行良好。希望对您有帮助。


5

由于这是我(可能还有其他人)在Google上的第一本关于如何在Vim中进行会话的工具,因此我决定在@mathielo的答案中添加一些有关使其自动实现的内容。

我喜欢他的代码,但是似乎缺少“仅当没有args时”解决方案。这是我的修改版本:

function! MakeSession(overwrite)
  let b:sessiondir = $HOME . "/.vim/sessions" . getcwd()
  if (filewritable(b:sessiondir) != 2)
    exe 'silent !mkdir -p ' b:sessiondir
    redraw!
  endif
  let b:filename = b:sessiondir . '/session.vim'
  if a:overwrite == 0 && !empty(glob(b:filename))
    return
  endif
  exe "mksession! " . b:filename
endfunction

function! LoadSession()
  let b:sessiondir = $HOME . "/.vim/sessions" . getcwd()
  let b:sessionfile = b:sessiondir . "/session.vim"
  if (filereadable(b:sessionfile))
    exe 'source ' b:sessionfile
  else
    echo "No session loaded."
  endif
endfunction

" Adding automatons for when entering or leaving Vim
if(argc() == 0)
  au VimEnter * nested :call LoadSession()
  au VimLeave * :call MakeSession(1)
else
  au VimLeave * :call MakeSession(0)
endif

这里值得注意的更改是可选的替代。如果您打开不带选项的Vim,它将打开任何现有会话并覆盖您离开时所做的更改。如果使用选项打开Vim,它将仅在不存在新会话的情况下创建新会话,这意味着您可以在具有会话的目录中打开单个文件而不会覆盖该文件。然后,您可以打开不带选项的Vim来运行会话。如果不存在会话,那么它将创建一个新会话。


我刚刚在Neovim 0.2.2中尝试了上述发布的解决方案,并将您的代码段放入其中,$HOME/.vim/plugin/sessions.vim但它没有保存会话文件。¯\ _(ツ)_ /¯
ipatch '18

该线程,尤其是链接的注释,可能会有所帮助:superuser.com/questions/404686/…我在.vimrc中拥有它,并且工作正常。
PMunch

得到它的工作,显然我已经退出(N)VIM为了要写入的会话插入恶意的玩笑 再次感谢分享👍
iPatch系统

3

有一个很棒的插件调用vim-session。非常强大。要安装它:

cd ~/.vim/bundle
git clone https://github.com/xolox/vim-session.git

我已将其功能映射到我的.vimrc文件中,如下所示:

nnoremap <leader>so :OpenSession 
nnoremap <leader>ss :SaveSession 
nnoremap <leader>sd :DeleteSession<CR>
nnoremap <leader>sc :CloseSession<CR>

现在,在普通模式下,只需键入<leader>ss,您将看到类似这样的命令

:SaveSession 

现在添加您的会话名称

 :SaveSession namesession

就这样。

当您关闭Vim并重新打开它时,只需执行

 :OpenSession

您将看到会话打开。

您的.vimrc文件中还有很多其他配置要添加,请参见文档中的示例:

let g:session_directory = "~/.vim/tmp/session"  // the directory must be created before the sessions will be saved there
let g:session_autoload = "no"                   // automatic reload sessions
let g:session_autosave = "no"                   // autosave
let g:session_command_aliases = 1

YouTube上有一个很好的教程


2

我个人只是包装了Tim Pope的Obsession插件,以允许定义a sessiondir并避免键入路径:

let g:sessiondir = $HOME . ".vim/sessions"

command! -nargs=1 MkSession call MkSession(<f-args>)
function! MkSession(sessionfile)
  if !isdirectory(g:sessiondir)
    call mkdir(g:sessiondir, "p")
  endif
  exe 'Obsession' g:sessiondir . '/' . a:sessionfile
endfunction

command! -nargs=1 LoadSession call LoadSession(<f-args>)
function! LoadSession(sessionfile)

  let a:sessionpath = g:sessiondir . a:sessionfile
  if (filereadable(a:sessionpath))
    exe 'source ' a:sessionpath
  else
    echo "No session loaded."
  endif
endfunction

我在Airline插件和会话方面遇到了具体问题。改用Obsession解决了问题,经过数周的努力,这是一个了不起的发现。见github.com/vim-airline/vim-airline/issues/...
icc97

1

感谢@mathielo以下是@mathielo的示例,我在.vimrc中添加了以下代码以保存活动会话(如果有):

au VimLeave * if this_session != "" | exe "mksession! ".this_session

如果要添加更多行,则需要使用endif:

au VimLeave * if v:this_session != ""
au VimLeave *   exe "mksession! ".this_session
au VimLeave * endif

您只需要使用以下命令在vim中保存新会话:

:mks [Session filename]

然后开始

$ vim -S [Session filename]

vim将启动会话,您不必担心每次关闭vim都会保存会话。

如果您没有活动的会话,.vimrc将不执行任何操作。像以前一样。

那就是我想要的!再次感谢@mathielo!


这也是我一直在寻找的东西。太好了!我不记得我失去了多少次会议,:q而不是:bd...谢谢!
Joel.O

1

如果您计划该项目只有1个工作阶段,请执行

:mks

这将Session.vim在当前目录中创建一个文件,然后打开会话(从同一目录):

vim -S

如果您更改会话并想要保存它:

:mks!

这样可以保存会话,而不是文件本身!

如果您打算进行多个会话,我更喜欢将它们保存在项目目录的隐藏文件中:

:mks .session-name.vim

要打开它(从同一目录):

vim -S .session-name.vim

保存会议:

:mks! .session-name.vim

由于会话保存在隐藏文件中,因此查看它们时请不要忘记 -a

ls -a

0

您可以将会话存储在任意位置。

例如:

:mksession! D:/session.ses

这会将会话存储在D驱动器中。

可以通过键入打开

:so D:/session.ses

在任何vim文件中。


0

以下是唯一的配置文件。真的对我有用。我从这里拿走的,在这里您还可以获取更完整/更复杂的版本。

set viewoptions+=cursor,folds,slash,unix
set viewoptions-=options

augroup vimrc
    autocmd BufWritePost *
    \   if expand('%') != '' && &buftype !~ 'nofile'
    \|      mkview
    \|  endif
    autocmd BufRead *
    \   if expand('%') != '' && &buftype !~ 'nofile'
    \|      silent loadview
    \|  endif
augroup END

0

为了管理多个会话(基于每个目录/存储库),我最近从vim-session插件切换到vim-workspace。它的会话管理相对简单,并且运行良好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.