Vim,NERDtree无法在会话恢复中恢复

28
当我有一个NERDtree面板并保存Vim会话(mksession [filename])时,然后打开会话(vim -S filename),该面板被打开并标记为“NERDtree”,但未填充内容。如果我尝试从命令行使用“:NERDtree”,则窗口确实被填充,但现在另一个面板就会打开。 对于这种奇怪的行为有任何想法吗?
8个回答

28

我决定自己解决这个问题。在我的情况下,当我使用以下vimrc退出Vim时,会创建一个会话:

autocmd VimLeave * mksession! [filename]

我还试图在Vim打开时自动打开NERDTree:

autocmd VimEnter * NERDTree

结果是我的会话中出现了两个NERDTree实例,就像原帖所描述的那样。我的解决方案是,在保存会话之前简单地关闭NERDTree,这样我的自动打开调用就只会打开一个NERDTree实例。

我的解决方案

" Save session on quitting Vim
autocmd VimLeave * NERDTreeClose
autocmd VimLeave * mksession! [filename]

" Restore session on starting Vim
autocmd VimEnter * call MySessionRestoreFunction()
autocmd VimEnter * NERDTree

到目前为止,对我而言它工作得非常好。希望这可以帮到你。


1
顺便说一句,我在这里使用了会话恢复代码:https://dev59.com/LG435IYBdhLWcg3w6EmF#6052704 - Walty Yeung
我更喜欢使用 vim-nerdtree-tabs 提供的 NERDTreeTabsClose 方法,而不是 NERDTreeClose。这种组合在多个标签会话中也能完美运行。 - Egel
" Save session on quitting Vim autocmd VimLeave * NERDTreeClose autocmd VimLeave * mksession! ~/mysession.vim " Start NERDTree when Vim starts with a directory argument. autocmd StdinReadPre * let s:std_in=1 autocmd VimEnter * source ~/mysession.vim autocmd VimEnter * NERDTree - Ilídio Martins

6

我也曾遇到同样的问题,在调研期间发现了两种解决方案:

你可以使用名为"session.vim"的插件,它对恢复NERDTree有基本支持。你可以在这里找到它:http://www.vim.org/scripts/script.php?script_id=3150

但我发现这个插件并不适合我,所以我采取了另一种方法。你可以配置vim自动将你工作目录的路径设置为缓冲区的路径。

autocmd BufEnter * lcd %:p:h

由于NERDTree在第一次打开时会打开工作目录,所以您已经到达了想要去的地方!

只需在打开文件或者你的会话之后再打开NERDTree。

然而,由于魔法只会在一个选项卡中第一次生效,您可以使用以下命令让NERDTree在树中找到您的文件。

map <leader>r :NERDTreeFind<cr>

要清理树形结构,只需使用“p”命令向上跳转几个目录,然后键入“C”即可。

我是通过这篇文章中的人们发现了这些命令:

https://superuser.com/questions/195022/vim-how-to-synchronize-nerdtree-with-current-opened-tab-file-path


+1 对于:"session.vim",它具有基本支持是真的!此外,session.vim 还具有自动恢复上次会话选项。正是我想要的... - Igor Parra

4
为了修复NERDTree会话,应该使用嵌入在会话插件中的新会话命令"SaveSession"和"OpenSession",而不是"mksession"和"source"。
根据会话插件作者的评论:Vim的:mksession命令并不真正兼容生成内容创建缓冲区的插件,因此session.vim包括针对这些插件的特定解决方案: •支持BufExplorer、Project和NERDtree窗口; •当安装了shell.vim时,Vim的全屏状态得以保留; •netrw和taglist.vim插件支持会话开箱即用。 也许这就是为什么我们应该使用新命令来解决NERDTree会话问题的原因。
有关更多详细信息,请参见http://peterodding.com/code/vim/session/

2

或者你可以使用Vimpanel,它内置了会话支持和其他功能。


2

基于stevelove的另一种解决方案:

fun! Mksession(name)
    let need_tree = g:NERDTree.IsOpen()
    NERDTreeClose
    execute "mksession! " . a:name
    if need_tree
        call writefile(readfile(a:name)+['NERDTree'], a:name)
        NERDTree
    endif
endfun

command! -nargs=1 Mksession call Mksession(<f-args>)

1

让NERDTree在会话中按预期工作的最简单方法可能是修补NERD_tree.vim,向NERDTree autocommand组添加一个autocommand(在augroup NERDTree行之后):

exec "autocmd BufEnter ". s:NERDTreeBufName ."* call <SID>initNerdTreeInPlace(\"\")"

这个功能没有经过广泛测试,但是在我使用多种布局和不同数量的NERDTree窗口时似乎可以工作。

编辑:实际上,这并不是很好用,因为NERDTree有主窗口和次要窗口,并且在会话文件中没有指示NERDTree缓冲区是哪一个。看起来为插件添加可靠的支持并不是一项很大的挑战,但也不是微不足道的。同时,对于简单的情况,添加以下自动命令(而不是上面的命令)可能会达到您想要的效果:

exec "autocmd BufEnter ". s:NERDTreeBufName ."* :NERDTreeToggle | :NERDTreeToggle"

1

在我的情况下,在加载会话后NERDTree被打开,但是没有显示任何文件。以下脚本解决了这个问题:

" Automatically save the session when leaving vim
set sessionoptions=blank,buffers,curdir,help,tabpages,winsize
autocmd VimLeave * NERDTreeClose
autocmd! VimLeave * mksession! ~/Session.vim

" Automatically load the session when entering vim when no arguments were provided
if argc() == 0 && filereadable(expand('~/Session.vim'))
    autocmd! VimEnter * source ~/Session.vim
    autocmd VimEnter * :NERDTreeToggle | wincmd l | wincmd q
endif

即:

  • 保存会话前 - 关闭 NERDTree
  • 加载会话后 - 打开 NERDTree(现在有两个),使用 wincmd l 前往另一个,并使用 wincmd q 关闭

0

例子:

" Save session on quitting Vim but we have to first close NERDTree
autocmd VimLeave * NERDTreeClose
autocmd VimLeave * mksession! ~/mysession.vim

" Open session first and then start NERDTree
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * source ~/mysession.vim
autocmd VimEnter * NERDTree

NERDTreeClose | mksession! ~/mysession.vim | NERDTree - Ilídio Martins
NERDTreeClose | source ~/mysession.vim | NERDTree - Ilídio Martins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接