350 lines
10 KiB
VimL
350 lines
10 KiB
VimL
" Author: Eric Van Dewoestine
|
|
"
|
|
" License: {{{
|
|
"
|
|
" Copyright (C) 2005 - 2014 Eric Van Dewoestine
|
|
"
|
|
" This program is free software: you can redistribute it and/or modify
|
|
" it under the terms of the GNU General Public License as published by
|
|
" the Free Software Foundation, either version 3 of the License, or
|
|
" (at your option) any later version.
|
|
"
|
|
" This program is distributed in the hope that it will be useful,
|
|
" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
" GNU General Public License for more details.
|
|
"
|
|
" You should have received a copy of the GNU General Public License
|
|
" along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
"
|
|
" }}}
|
|
|
|
" GlobalVariables {{{
|
|
let g:VerticalToolBuffers = {}
|
|
|
|
if !exists('g:VerticalToolWindowSide')
|
|
let g:VerticalToolWindowSide = 'left'
|
|
endif
|
|
|
|
if g:VerticalToolWindowSide == 'right'
|
|
let g:VerticalToolWindowPosition = 'botright vertical'
|
|
else
|
|
let g:VerticalToolWindowPosition = 'topleft vertical'
|
|
endif
|
|
|
|
if !exists('g:VerticalToolWindowWidth')
|
|
let g:VerticalToolWindowWidth = 30
|
|
endif
|
|
" }}}
|
|
|
|
function! eclim#display#window#VerticalToolWindowOpen(name, weight, ...) " {{{
|
|
" Handles opening windows in the vertical tool window on the left (taglist,
|
|
" project tree, etc.)
|
|
|
|
let taglist_window = -1
|
|
if exists('g:TagList_title')
|
|
let taglist_window = bufwinnr(eclim#util#EscapeBufferName(g:TagList_title))
|
|
let taglist_position = 'left'
|
|
if exists('g:Tlist_Use_Horiz_Window') && g:Tlist_Use_Horiz_Window
|
|
let taglist_position = 'horizontal'
|
|
elseif exists('g:TaglistTooPosition')
|
|
let taglist_position = g:TaglistTooPosition
|
|
elseif exists('g:Tlist_Use_Right_Window') && g:Tlist_Use_Right_Window
|
|
let taglist_position = 'right'
|
|
endif
|
|
endif
|
|
if taglist_window == -1 && exists(':TagbarOpen')
|
|
let taglist_window = bufwinnr('__Tagbar__')
|
|
let taglist_position = 'right'
|
|
if exists('g:tagbar_left') && g:tagbar_left
|
|
let taglist_position = 'left'
|
|
endif
|
|
endif
|
|
if taglist_window != -1
|
|
" don't consider horizontal taglist, or taglist configured to display
|
|
" opposite the tool windows as a tool window member.
|
|
if taglist_position != g:VerticalToolWindowSide
|
|
let taglist_window = -1
|
|
endif
|
|
endif
|
|
|
|
let relative_window = 0
|
|
let relative_window_loc = 'below'
|
|
if taglist_window != -1 || len(g:VerticalToolBuffers) > 0
|
|
if taglist_window != -1
|
|
let relative_window = taglist_window
|
|
endif
|
|
for toolbuf in keys(g:VerticalToolBuffers)
|
|
exec 'let toolbuf = ' . toolbuf
|
|
if bufwinnr(toolbuf) != -1
|
|
if relative_window == 0
|
|
let relative_window = bufwinnr(toolbuf)
|
|
if getbufvar(toolbuf, 'weight') > a:weight
|
|
let relative_window_loc = 'below'
|
|
else
|
|
let relative_window_loc = 'above'
|
|
endif
|
|
elseif getbufvar(toolbuf, 'weight') > a:weight
|
|
let relative_window = bufwinnr(toolbuf)
|
|
let relative_window_loc = 'below'
|
|
elseif getbufvar(toolbuf, 'weight') < a:weight
|
|
let relative_window = bufwinnr(toolbuf)
|
|
let relative_window_loc = 'above'
|
|
endif
|
|
endif
|
|
endfor
|
|
endif
|
|
|
|
if relative_window != 0
|
|
let wincmd = relative_window . 'winc w | keepalt ' . relative_window_loc . ' '
|
|
else
|
|
let wincmd = 'keepalt ' . g:VerticalToolWindowPosition . ' ' . g:VerticalToolWindowWidth
|
|
endif
|
|
|
|
let escaped = substitute(
|
|
\ a:name, '\(.\{-}\)\[\(.\{-}\)\]\(.\{-}\)', '\1[[]\2[]]\3', 'g')
|
|
if a:0 && a:1
|
|
let bufnum = -1
|
|
for bnr in tabpagebuflist()
|
|
if bufname(bnr) == a:name
|
|
let bufnum = bnr
|
|
break
|
|
endif
|
|
endfor
|
|
else
|
|
let bufnum = bufnr(escaped)
|
|
endif
|
|
let name = bufnum == -1 ? a:name : '+buffer' . bufnum
|
|
silent call eclim#util#ExecWithoutAutocmds(wincmd . ' split ' . name)
|
|
|
|
doautocmd BufWinEnter
|
|
setlocal winfixwidth
|
|
setlocal nonumber
|
|
setlocal nospell norelativenumber
|
|
|
|
let b:weight = a:weight
|
|
let bufnum = bufnr('%')
|
|
let g:VerticalToolBuffers[bufnum] = a:name
|
|
augroup eclim_vertical_tool_windows
|
|
autocmd!
|
|
autocmd BufDelete * call s:PreventCloseOnBufferDelete()
|
|
autocmd BufEnter * nested call s:CloseIfLastWindow()
|
|
augroup END
|
|
|
|
if exists('g:TagList_title') &&
|
|
\ (!exists('g:Tlist_Use_Horiz_Window') || !g:Tlist_Use_Horiz_Window)
|
|
augroup eclim_vertical_tool_windows_move_taglist
|
|
autocmd!
|
|
autocmd BufWinEnter * if bufname('%') == g:TagList_title | call s:MoveRelativeTo() | endif
|
|
augroup END
|
|
endif
|
|
if exists(':TagbarOpen')
|
|
augroup eclim_vertical_tool_windows_move_tagbar
|
|
autocmd!
|
|
autocmd BufWinEnter __Tagbar__ call s:MoveRelativeTo()
|
|
augroup END
|
|
endif
|
|
augroup eclim_vertical_tool_windows_buffer
|
|
exec 'autocmd BufWinLeave <buffer> ' .
|
|
\ 'silent! call remove(g:VerticalToolBuffers, ' . bufnum . ') | ' .
|
|
\ 'autocmd! eclim_vertical_tool_windows_buffer * <buffer=' . bufnum . '>'
|
|
augroup END
|
|
endfunction " }}}
|
|
|
|
function! eclim#display#window#VerticalToolWindowRestore() " {{{
|
|
" Used to restore the tool windows to their proper width if some action
|
|
" altered them.
|
|
|
|
for toolbuf in keys(g:VerticalToolBuffers)
|
|
exec 'let toolbuf = ' . toolbuf
|
|
if bufwinnr(toolbuf) != -1
|
|
exec 'vertical ' . bufwinnr(toolbuf) . 'resize ' . g:VerticalToolWindowWidth
|
|
endif
|
|
endfor
|
|
endfunction " }}}
|
|
|
|
function! eclim#display#window#GetWindowOptions(winnum) " {{{
|
|
" Gets a dictionary containing all the localy set options for the specified
|
|
" window.
|
|
|
|
let curwin = winnr()
|
|
try
|
|
exec a:winnum . 'winc w'
|
|
redir => list
|
|
silent exec 'setlocal'
|
|
redir END
|
|
finally
|
|
exec curwin . 'winc w'
|
|
endtry
|
|
|
|
let list = substitute(list, '---.\{-}---', '', '')
|
|
let winopts = {}
|
|
for wopt in split(list, '\(\n\|\s\s\+\)')[1:]
|
|
if wopt =~ '^[a-z]'
|
|
if wopt =~ '='
|
|
let key = substitute(wopt, '\(.\{-}\)=.*', '\1', '')
|
|
let value = substitute(wopt, '.\{-}=\(.*\)', '\1', '')
|
|
let winopts[key] = value
|
|
else
|
|
let winopts[wopt] = ''
|
|
endif
|
|
endif
|
|
endfor
|
|
return winopts
|
|
endfunction " }}}
|
|
|
|
function! eclim#display#window#SetWindowOptions(winnum, options) " {{{
|
|
" Given a dictionary of options, sets each as local options for the specified
|
|
" window.
|
|
|
|
let curwin = winnr()
|
|
try
|
|
exec a:winnum . 'winc w'
|
|
for key in keys(a:options)
|
|
if key =~ '^no'
|
|
silent! exec 'setlocal ' . key
|
|
else
|
|
silent! exec 'setlocal ' . key . '=' . escape(a:options[key], ' ')
|
|
endif
|
|
endfor
|
|
finally
|
|
exec curwin . 'winc w'
|
|
endtry
|
|
endfunction " }}}
|
|
|
|
function! s:CloseIfLastWindow() " {{{
|
|
if histget(':', -1) !~ '^bd'
|
|
let close = 1
|
|
for bufnr in tabpagebuflist()
|
|
if has_key(g:VerticalToolBuffers, bufnr)
|
|
continue
|
|
endif
|
|
if exists('g:TagList_title') && bufname(bufnr) == g:TagList_title
|
|
continue
|
|
endif
|
|
if exists('g:BufExplorer_title') && bufname(bufnr) == '[BufExplorer]'
|
|
let close = 0
|
|
break
|
|
endif
|
|
|
|
let buftype = getbufvar(bufnr, '&buftype')
|
|
if buftype != '' && buftype != 'help'
|
|
continue
|
|
endif
|
|
|
|
let close = 0
|
|
break
|
|
endfor
|
|
|
|
if close
|
|
if tabpagenr('$') > 1
|
|
tabclose
|
|
else
|
|
quitall
|
|
endif
|
|
endif
|
|
endif
|
|
endfunction " }}}
|
|
|
|
function! s:MoveRelativeTo() " {{{
|
|
" get the buffer that the taglist was opened from
|
|
let curwin = winnr()
|
|
let list_buffer = bufnr('%')
|
|
winc p
|
|
let orig_buffer = bufnr('%')
|
|
exec curwin . 'winc p'
|
|
|
|
for toolbuf in keys(g:VerticalToolBuffers)
|
|
exec 'let toolbuf = ' . toolbuf
|
|
if bufwinnr(toolbuf) != -1
|
|
call setwinvar(bufwinnr(toolbuf), 'marked_for_removal', 1)
|
|
let winoptions = eclim#display#window#GetWindowOptions(bufwinnr(toolbuf))
|
|
call remove(winoptions, 'filetype')
|
|
call remove(winoptions, 'syntax')
|
|
call eclim#display#window#VerticalToolWindowOpen(
|
|
\ g:VerticalToolBuffers[toolbuf], getbufvar(toolbuf, 'weight'))
|
|
call eclim#display#window#SetWindowOptions(winnr(), winoptions)
|
|
endif
|
|
endfor
|
|
|
|
let winnum = 1
|
|
while winnum <= winnr('$')
|
|
if getwinvar(winnum, 'marked_for_removal') == 1
|
|
exec winnum . 'winc w'
|
|
close
|
|
else
|
|
let winnum += 1
|
|
endif
|
|
endwhile
|
|
call eclim#display#window#VerticalToolWindowRestore()
|
|
|
|
" some window juggling so that winc p from taglist goes back to the original
|
|
" buffer
|
|
exec bufwinnr(orig_buffer) . 'winc w'
|
|
exec bufwinnr(list_buffer) . 'winc w'
|
|
endfunction " }}}
|
|
|
|
function! s:PreventCloseOnBufferDelete() " {{{
|
|
let index = 1
|
|
let numtoolwindows = 0
|
|
let numtempwindows = 0
|
|
let tempbuffersbot = []
|
|
while index <= winnr('$')
|
|
let buf = winbufnr(index)
|
|
let bufname = bufname(buf)
|
|
if index(keys(g:VerticalToolBuffers), string(buf)) != -1
|
|
let numtoolwindows += 1
|
|
elseif getwinvar(index, '&winfixheight') || getwinvar(index, '&winfixwidth')
|
|
let numtempwindows += 1
|
|
if getwinvar(index, '&winfixheight')
|
|
call add(tempbuffersbot, buf)
|
|
endif
|
|
endif
|
|
let index += 1
|
|
endwhile
|
|
|
|
if winnr('$') == (numtoolwindows + numtempwindows)
|
|
let toolbuf = bufnr('%')
|
|
if g:VerticalToolWindowSide == 'right'
|
|
vertical topleft new
|
|
else
|
|
vertical botright new
|
|
endif
|
|
setlocal noreadonly modifiable
|
|
let curbuf = bufnr('%')
|
|
let removed = str2nr(expand('<abuf>'))
|
|
let next = eclim#common#buffers#OpenNextHiddenTabBuffer(removed)
|
|
if next != 0
|
|
let curbuf = next
|
|
endif
|
|
|
|
" resize windows
|
|
exec bufwinnr(toolbuf) . 'winc w'
|
|
exec 'vertical resize ' . g:VerticalToolWindowWidth
|
|
|
|
" fix the position of the temp windows
|
|
for buf in tempbuffersbot
|
|
" open the buffer in the temp window position
|
|
botright 10new
|
|
exec 'buffer ' . buf
|
|
setlocal winfixheight
|
|
|
|
" close the old window
|
|
let winnr = winnr()
|
|
let index = 1
|
|
while index <= winnr('$')
|
|
if winbufnr(index) == buf && index != winnr
|
|
exec index . 'winc w'
|
|
close
|
|
winc p
|
|
break
|
|
endif
|
|
let index += 1
|
|
endwhile
|
|
endfor
|
|
|
|
exec bufwinnr(curbuf) . 'winc w'
|
|
endif
|
|
endfunction " }}}
|
|
|
|
" vim:ft=vim:fdm=marker
|