Vim关闭缓冲区但没有拆分窗口

时间:2010-11-28 20:30:55

标签: vim buffer

如果我有2个水平/垂直分割的缓冲区并想要关闭其中一个缓冲区,但我不想关闭窗口。我希望保持分割窗口的位置与关闭缓冲区之前相同。

如果我按下:bd,关闭缓冲区的窗口也会关闭。

7 个答案:

答案 0 :(得分:27)

和@RusAlex一样,我不喜欢插件。我也想知道我输入的代码实际上是什么。

nmap ,d :b#<bar>bd#<CR>

简而言之,这会向vim的正常模式添加一个键映射,等待键序列,d。执行时,它会切换到先前打开的缓冲区,并尝试删除您切换的缓冲区。

删除屏幕外缓冲区会使屏幕保持原样分割。

该命令由三个以空格分隔的部分组成:

  • nmap - 添加/更改模式正常的键映射
  • ,d - 作出反应的关键序列;先,(逗号),然后d
  • :b#<bar>bd#<CR> - 执行的关键序列

要执行的命令由五部分组成:

  • : - 将vim切换到模式命令行
  • b# - 将窗口切换到先前打开的缓冲区
  • <bar> - 期待后续命令;代表|(管道字符);用于链接命令
  • bd# - 删除先前打开的缓冲区,即刚从
  • 切换的缓冲区
  • <CR> - 执行命令;表示回车,基本上是键ReturnEnter

该命令的格式为~/.vimrc之类的配置文件。如果你想在vim中添加映射,你先添加:(冒号) - 当退出vim时,映射就会丢失:

:nmap ,d :b#<bar>bd#<CR>

当你打开vim时,它通常处于正常模式,而不是模式插入(按-- INSERT --后按i指示在屏幕底部),视觉等等。 n中的nmap指定仅添加到正常模式的键映射。详细了解映射here

重要说明:

    如果
  • b#是唯一已知的缓冲区,则会切换到当前缓冲区。
  • b#可以切换到隐藏/关闭缓冲区,例如您刚刚关闭的,d
  • bd#将关闭当前缓冲区,如果它是唯一已知的缓冲区未分割屏幕,则会留下空缓冲区。
  • 如果缓冲区切换为隐藏/关闭缓冲区,
  • bd#将失败。
  • 如果在切换另一个窗口后显示要关闭的缓冲区,则
  • bd#仍会解除分离。

附加说明:

  • :windo b#会将所有窗口切换到之前打开的缓冲区。不确定如何与bd结合使用。
  • <CR>可以省略,在这种情况下,您必须手动按ReturnEnter才能执行。
  • :nmap ,显示以,开头的所有正常模式映射。
  • :ls列出了开放缓冲区。

答案 1 :(得分:9)

在vim中不可能有一个空窗口,但你可以使用:enew在当前窗口中创建一个新的空文件。

答案 2 :(得分:4)

我必须检查我的工作计算机,但我认为我正在使用的脚本是BufClose

答案 3 :(得分:2)

您想要删除缓冲区但保留拆分?然后你需要一个新的缓冲区 - :new会为你做这个,为新的/空文件创建一个缓冲区,但你仍然需要杀死旧的缓冲区/窗口。在vim中,窗口是缓冲区上的视口,因此如果您想要一个空窗口,则需要一个空缓冲区。

答案 4 :(得分:1)

@RusAlex版本+激活当前缓冲区到底需要删除缓冲区两次。

nmap ,d :b#<bar>bd#<bar>b<CR>

答案 5 :(得分:1)

这是@zenbro提供的答案的变体,即使您关闭的缓冲区是最后一个,也会保持所有(拆分)窗口和标签打开。

该函数将指向当前缓冲区(您正在关闭)的所有窗口切换到下一个缓冲区(如果当前缓冲区是最后一个缓冲区,则切换到新缓冲区)。

function! CloseBuffer()
    let curBuf = bufnr('%')
    let curTab = tabpagenr()
    exe 'bnext'

    " If in last buffer, create empty buffer
    if curBuf == bufnr('%')
        exe 'enew'
    endif

    " Loop through tabs
    for i in range(tabpagenr('$'))
        " Go to tab (is there a way with inactive tabs?)
        exe 'tabnext ' . (i + 1)
        " Store active window nr to restore later
        let curWin = winnr()
        " Loop through windows pointing to buffer
        let winnr = bufwinnr(curBuf)
        while (winnr >= 0)
            " Go to window and switch to next buffer
            exe winnr . 'wincmd w | bnext'
            " Restore active window
            exe curWin . 'wincmd w'
            let winnr = bufwinnr(curBuf)
        endwhile
    endfor

    " Close buffer, restore active tab
    exe 'bd' . curBuf
    exe 'tabnext ' . curTab  
endfunction

要映射它:

map <silent> <F4> :call CloseBuffer()<cr>

答案 6 :(得分:0)

以下是一些解决方法:

function! CloseSplitOrDeleteBuffer()
  let curNr = winnr()
  let curBuf = bufnr('%')
  wincmd w                    " try to move on next split
  if winnr() == curNr         " there is no split"
    exe 'bdelete'
  elseif curBuf != bufnr('%') " there is split with another buffer
    wincmd W                  " move back"
    exe 'bdelete'
  else                        " there is split with same buffer"
    wincmd W
    wincmd c
  endif
endfunction


nnoremap <silent> Q :call CloseSplitOrDeleteBuffer()<CR>