即使没有足够的空间,如何让Vim打开一个新窗口

时间:2014-11-05 11:22:08

标签: vim

我在Rolodex模式下使用Vim,因此活动窗口总是被扩展为占用尽可能多的空间,但是非活动窗口每个至少有7行空间(如Why can't vim process .vimrc when winheight option isn't set twice?中所示) )。

.vimrc中的相关行:

set winheight=7
set winminheight=7
set winheight=999

这很好用,但有一个问题。如果我尝试使用:sp打开更多窗口,以便没有足够的空间为每个窗口提供7行,则Vim会输出以下错误:E36: Not enough room。我想要的是,如果没有足够的空间,Vim应该打开一个新窗口,只需要根据需要减少所有窗口的最小窗口高度,稍后如果任何窗口关闭,最小窗口高度应该会增加再次(使窗口最小尺寸再次增加到7)。换句话说:如何让Vim认为窗口最小高度是理想的,而不是严格的要求?

我也试过Golden Ratio,但在黄金比例中有2个问题:非活动窗口变得非常小,非活动窗口也有不相等的大小,一些非活动窗口可能有3行,有些只有1行

2 个答案:

答案 0 :(得分:3)

对于初始拆分,如果可能的话,我会使用try ... catch ... endtry块进行拆分,如果不可能则调整窗口高度。例如,这显示了该方法(但不够聪明,无法确定窗口的小小):

command! Split call MakeRoomAndSplit()

function! MakeRoomAndSplit()
  try
    split
  catch /E36:/
    let &winheight=&winminheight
    set winminheight=2
    set winheight=999
    split
  endtry
endfun

为了让你的窗户高度恢复,我认为你可以在autocmds中做类似的事情来检测关闭的窗口并相应地调整高度。例如:

augroup WINHEIGHT
  au!
  autocmd WinEnter * if exists('t:numwindows') && t:numwindows > winnr('$') | call IncreaseWinSize() | endif
  autocmd WinEnter * let t:numwindows = winnr('$')
augroup END

function! IncreaseWinSize()
  let oldheight = &winminheight
  try
    set winheight=7
    set winminheight=7
    set winheight=999
  catch /E36:/
    let &winheight=oldheight
    let &winminheight=&winheight
    set winheight=999
  endtry
endfun

答案 1 :(得分:1)

通过扩大Ben的答案,我得到了我想要的东西。这是我的解决方案:

修改:修正了使用foo打开文件:Split foo时的错误。

set winheight=7
set winminheight=7
set winheight=999

" adjust minimum window size down from 7 to 1 and up from 1 to 7 as needed.
" this is a hack, but it works.

" code to adjust minimum window size down from 7 to 1 begins here.

command! -nargs=* -complete=file Split call MakeRoomAndSplit7(<q-args>)

function! OpenFileOrDirectoryInNewWindow(...)
    :let combinedinput = join(a:000)
    :let inputlength = (strlen(combinedinput))
    :let lastchar = strpart(combinedinput, inputlength-1)
    if (inputlength == 0)
        " opens a new window with the current file.
        " if current buffer has no name, opens file viewer in a new window.
        :execute "Hexplore" bufname("%")
    else
        if (lastchar == '/')
            " opens file viewer in a new window.
            " directory names must end with '/',
            " luckily autocompletion does that.
            :execute "Hexplore" fnameescape(resolve(join(a:000)))
        elseif (lastchar == '~')
            " opens file viewer in a new window.
            :execute "Hexplore" fnameescape(resolve(join(a:000)))
        elseif (lastchar == '.')
            " opens file viewer in a new window.
            :execute "Hexplore" fnameescape(resolve(join(a:000)))
        else
            " opens the file in a new window.
            :execute ":split" fnameescape(resolve(join(a:000)))
        endif
    endif
endfun

function! MakeRoomAndSplit7(...)
    try
        call call('OpenFileOrDirectoryInNewWindow', a:000)
    catch /E36:/
        let &winheight=&winminheight
        set winminheight=6
        set winheight=999
        command! -nargs=* -complete=file Split call MakeRoomAndSplit6(<q-args>)
        call call('MakeRoomAndSplit6', a:000)
    endtry
endfun

function! MakeRoomAndSplit6(...)
    try
        call call('OpenFileOrDirectoryInNewWindow', a:000)
    catch /E36:/
        let &winheight=&winminheight
        set winminheight=5
        set winheight=999
        command! -nargs=* -complete=file Split call MakeRoomAndSplit5(<q-args>)
        call call('MakeRoomAndSplit5', a:000)
    endtry
endfun

function! MakeRoomAndSplit5(...)
    try
        call call('OpenFileOrDirectoryInNewWindow', a:000)
    catch /E36:/
        let &winheight=&winminheight
        set winminheight=4
        set winheight=999
        command! -nargs=* -complete=file Split call MakeRoomAndSplit4(<q-args>)
        call call('MakeRoomAndSplit4', a:000)
    endtry
endfun

function! MakeRoomAndSplit4(...)
    try
        call call('OpenFileOrDirectoryInNewWindow', a:000)
    catch /E36:/
        let &winheight=&winminheight
        set winminheight=3
        set winheight=999
        command! -nargs=* -complete=file Split call MakeRoomAndSplit3(<q-args>)
        call call('MakeRoomAndSplit3', a:000)
    endtry
endfun

function! MakeRoomAndSplit3(...)
    try
        call call('OpenFileOrDirectoryInNewWindow', a:000)
    catch /E36:/
        let &winheight=&winminheight
        set winminheight=2
        set winheight=999
        command! -nargs=* -complete=file Split call MakeRoomAndSplit2(<q-args>)
        call call('MakeRoomAndSplit2', a:000)
    endtry
endfun

function! MakeRoomAndSplit2(...)
    try
        call call('OpenFileOrDirectoryInNewWindow', a:000)
    catch /E36:/
        let &winheight=&winminheight
        set winminheight=1
        set winheight=999
        call call('OpenFileOrDirectoryInNewWindow', a:000)
    endtry
endfun

" code to adjust minimum window size down from 7 to 1 ends here.

" code to adjust minimum window size up from 1 to 7 begins here.

augroup WINHEIGHT
    au!
    autocmd WinEnter * if exists('t:numwindows') && t:numwindows > winnr('$') | call IncreaseWinSize7() | endif
    autocmd WinEnter * let t:numwindows = winnr('$')
augroup END

function! IncreaseWinSize7()
    try
        set winheight=7
        set winminheight=7
        set winheight=999
    catch /E36:/
        :call IncreaseWinSize6()
    endtry
endfun

function! IncreaseWinSize6()
    try
        set winheight=6
        set winminheight=6
        set winheight=999
    catch /E36:/
        :call IncreaseWinSize5()
    endtry
endfun

function! IncreaseWinSize5()
    try
        set winheight=5
        set winminheight=5
        set winheight=999
    catch /E36:/
        :call IncreaseWinSize4()
    endtry
endfun

function! IncreaseWinSize4()
    try
        set winheight=4
        set winminheight=4
        set winheight=999
    catch /E36:/
        :call IncreaseWinSize3()
    endtry
endfun

function! IncreaseWinSize3()
    try
        set winheight=3
        set winminheight=3
        set winheight=999
    catch /E36:/
        :call IncreaseWinSize2()
    endtry
endfun

function! IncreaseWinSize2()
    try
        set winheight=2
        set winminheight=2
        set winheight=999
    catch /E36:/
        :call IncreaseWinSize1()
    endtry
endfun

function! IncreaseWinSize1()
    set winheight=1
    set winminheight=1
    set winheight=999
endfun

" code to adjust minimum window size up from 1 to 7 ends here.