123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- " === plugin configuration variables === {{{
- "
- " open NERDTree on gvim/macvim startup
- if !exists('g:nerdtree_tabs_open_on_gui_startup')
- let g:nerdtree_tabs_open_on_gui_startup = 1
- endif
- " open NERDTree on console vim startup (off by default)
- if !exists('g:nerdtree_tabs_open_on_console_startup')
- let g:nerdtree_tabs_open_on_console_startup = 0
- endif
- " do not open NERDTree if vim starts in diff mode
- if !exists('g:nerdtree_tabs_no_startup_for_diff')
- let g:nerdtree_tabs_no_startup_for_diff = 1
- endif
- " On startup - focus NERDTree when opening a directory, focus the file if
- " editing a specified file. When set to `2`, always focus file after startup.
- if !exists('g:nerdtree_tabs_smart_startup_focus')
- let g:nerdtree_tabs_smart_startup_focus = 1
- endif
- " Open NERDTree on new tab creation if NERDTree was globally opened
- " by :NERDTreeTabsToggle
- if !exists('g:nerdtree_tabs_open_on_new_tab')
- let g:nerdtree_tabs_open_on_new_tab = 1
- endif
- " unfocus NERDTree when leaving a tab so that you have descriptive tab names
- " and not names like 'NERD_tree_1'
- if !exists('g:nerdtree_tabs_meaningful_tab_names')
- let g:nerdtree_tabs_meaningful_tab_names = 1
- endif
- " close current tab if there is only one window in it and it's NERDTree
- if !exists('g:nerdtree_tabs_autoclose')
- let g:nerdtree_tabs_autoclose = 1
- endif
- " synchronize view of all NERDTree windows (scroll and cursor position)
- if !exists('g:nerdtree_tabs_synchronize_view')
- let g:nerdtree_tabs_synchronize_view = 1
- endif
- " synchronize focus when switching tabs (focus NERDTree after tab switch
- " if and only if it was focused before tab switch)
- if !exists('g:nerdtree_tabs_synchronize_focus')
- let g:nerdtree_tabs_synchronize_focus = 1
- endif
- " when switching into a tab, make sure that focus will always be in file
- " editing window, not in NERDTree window (off by default)
- if !exists('g:nerdtree_tabs_focus_on_files')
- let g:nerdtree_tabs_focus_on_files = 0
- endif
- " when starting up with a directory name as a parameter, cd into it
- if !exists('g:nerdtree_tabs_startup_cd')
- let g:nerdtree_tabs_startup_cd = 1
- endif
- "
- " }}}
- " === plugin mappings === {{{
- "
- noremap <silent> <script> <Plug>NERDTreeTabsOpen :call <SID>NERDTreeOpenAllTabs()
- noremap <silent> <script> <Plug>NERDTreeTabsClose :call <SID>NERDTreeCloseAllTabs()
- noremap <silent> <script> <Plug>NERDTreeTabsToggle :call <SID>NERDTreeToggleAllTabs()
- noremap <silent> <script> <Plug>NERDTreeMirrorOpen :call <SID>NERDTreeMirrorOrCreate()
- noremap <silent> <script> <Plug>NERDTreeMirrorToggle :call <SID>NERDTreeMirrorToggle()
- noremap <silent> <script> <Plug>NERDTreeSteppedOpen :call <SID>NERDTreeSteppedOpen()
- noremap <silent> <script> <Plug>NERDTreeSteppedClose :call <SID>NERDTreeSteppedClose()
- noremap <silent> <script> <Plug>NERDTreeFocusToggle :call <SID>NERDTreeFocusToggle()
- "
- " }}}
- " === plugin commands === {{{
- "
- command! NERDTreeTabsOpen call <SID>NERDTreeOpenAllTabs()
- command! NERDTreeTabsClose call <SID>NERDTreeCloseAllTabs()
- command! NERDTreeTabsToggle call <SID>NERDTreeToggleAllTabs()
- command! NERDTreeMirrorOpen call <SID>NERDTreeMirrorOrCreate()
- command! NERDTreeMirrorToggle call <SID>NERDTreeMirrorToggle()
- command! NERDTreeSteppedOpen call <SID>NERDTreeSteppedOpen()
- command! NERDTreeSteppedClose call <SID>NERDTreeSteppedClose()
- command! NERDTreeFocusToggle call <SID>NERDTreeFocusToggle()
- "
- " }}}
- " === plugin functions === {{{
- "
- " === NERDTree manipulation (opening, closing etc.) === {{{
- "
- " s:NERDTreeMirrorOrCreate() {{{
- "
- " switch NERDTree on for current tab -- mirror it if possible, otherwise create it
- fun! s:NERDTreeMirrorOrCreate()
- let l:nerdtree_open = s:IsNERDTreeOpenInCurrentTab()
- " if NERDTree is not active in the current tab, try to mirror it
- if !l:nerdtree_open
- let l:previous_winnr = winnr("$")
- silent NERDTreeMirror
- " if the window count of current tab didn't increase after NERDTreeMirror,
- " it means NERDTreeMirror was unsuccessful and a new NERDTree has to be created
- if l:previous_winnr == winnr("$")
- silent NERDTreeToggle
- endif
- endif
- endfun
- " }}}
- " s:NERDTreeMirrorToggle() {{{
- "
- " toggle NERDTree in current tab, use mirror if possible
- fun! s:NERDTreeMirrorToggle()
- let l:nerdtree_open = s:IsNERDTreeOpenInCurrentTab()
- if l:nerdtree_open
- silent NERDTreeClose
- else
- call s:NERDTreeMirrorOrCreate()
- endif
- endfun
- " }}}
- " s:NERDTreeOpenAllTabs() {{{
- "
- " switch NERDTree on for all tabs while making sure there is only one NERDTree buffer
- fun! s:NERDTreeOpenAllTabs()
- let s:nerdtree_globally_active = 1
- " tabdo doesn't preserve current tab - save it and restore it afterwards
- let l:current_tab = tabpagenr()
- tabdo call s:NERDTreeMirrorOrCreate()
- exe 'tabn ' . l:current_tab
- endfun
- " }}}
- " s:NERDTreeCloseAllTabs() {{{
- "
- " close NERDTree across all tabs
- fun! s:NERDTreeCloseAllTabs()
- let s:nerdtree_globally_active = 0
- " tabdo doesn't preserve current tab - save it and restore it afterwards
- let l:current_tab = tabpagenr()
- tabdo silent NERDTreeClose
- exe 'tabn ' . l:current_tab
- endfun
- " }}}
- " s:NERDTreeToggleAllTabs() {{{
- "
- " toggle NERDTree in current tab and match the state in all other tabs
- fun! s:NERDTreeToggleAllTabs()
- let l:nerdtree_open = s:IsNERDTreeOpenInCurrentTab()
- let s:disable_handlers_for_tabdo = 1
- if l:nerdtree_open
- call s:NERDTreeCloseAllTabs()
- else
- call s:NERDTreeOpenAllTabs()
- " force focus to NERDTree in current tab
- if exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) != -1
- exe bufwinnr(t:NERDTreeBufName) . "wincmd w"
- endif
- endif
- let s:disable_handlers_for_tabdo = 0
- endfun
- " }}}
- " s:NERDTreeSteppedOpen() {{{
- "
- " focus the NERDTree view, creating one first if none is present
- fun! s:NERDTreeSteppedOpen()
- if !s:IsCurrentWindowNERDTree()
- if s:IsNERDTreeOpenInCurrentTab()
- call s:NERDTreeFocus()
- else
- call s:NERDTreeMirrorOrCreate()
- endif
- endif
- endfun
- " }}}
- " s:NERDTreeSteppedClose{() {{{
- "
- " unfocus the NERDTree view or closes it if it hadn't had focus at the time of
- " the call
- fun! s:NERDTreeSteppedClose()
- if s:IsCurrentWindowNERDTree()
- call s:NERDTreeUnfocus()
- else
- let l:nerdtree_open = s:IsNERDTreeOpenInCurrentTab()
- if l:nerdtree_open
- silent NERDTreeClose
- endif
- endif
- endfun
- " }}}
- " s:NERDTreeFocusToggle() {{{
- "
- " focus the NERDTree view or creates it if in a file,
- " or unfocus NERDTree view if in NERDTree
- fun! s:NERDTreeFocusToggle()
- let s:disable_handlers_for_tabdo = 1
- if s:IsCurrentWindowNERDTree()
- call s:NERDTreeUnfocus()
- else
- if !s:IsNERDTreeOpenInCurrentTab()
- call s:NERDTreeOpenAllTabs()
- endif
- call s:NERDTreeFocus()
- endif
- let s:disable_handlers_for_tabdo = 0
- endfun
- " }}}
- "
- " === NERDTree manipulation (opening, closing etc.) === }}}
- " === focus functions === {{{
- "
- " s:NERDTreeFocus() {{{
- "
- " if the current window is NERDTree, move focus to the next window
- fun! s:NERDTreeFocus()
- if !s:IsCurrentWindowNERDTree() && exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) != -1
- exe bufwinnr(t:NERDTreeBufName) . "wincmd w"
- endif
- endfun
- " }}}
- " s:NERDTreeUnfocus() {{{
- "
- " if the current window is NERDTree, move focus to the next window
- fun! s:NERDTreeUnfocus()
- " save current window so that it's focus can be restored after switching
- " back to this tab
- let t:NERDTreeTabLastWindow = winnr()
- if s:IsCurrentWindowNERDTree()
- let l:winNum = s:NextNormalWindow()
- if l:winNum != -1
- exec l:winNum.'wincmd w'
- else
- wincmd w
- endif
- endif
- endfun
- " }}}
- " s:NERDTreeRestoreFocus() {{{
- "
- " restore focus to the window that was focused before leaving current tab
- fun! s:NERDTreeRestoreFocus()
- if g:nerdtree_tabs_synchronize_focus
- if s:is_nerdtree_globally_focused
- call s:NERDTreeFocus()
- elseif exists("t:NERDTreeTabLastWindow") && exists("t:NERDTreeBufName") && t:NERDTreeTabLastWindow != bufwinnr(t:NERDTreeBufName)
- exe t:NERDTreeTabLastWindow . "wincmd w"
- endif
- elseif exists("t:NERDTreeTabLastWindow")
- exe t:NERDTreeTabLastWindow . "wincmd w"
- endif
- endfun
- " }}}
- " s:SaveGlobalFocus() {{{
- "
- fun! s:SaveGlobalFocus()
- let s:is_nerdtree_globally_focused = s:IsCurrentWindowNERDTree()
- endfun
- " }}}
- " s:IfFocusOnStartup() {{{
- "
- fun! s:IfFocusOnStartup()
- return strlen(bufname('$')) == 0 || !getbufvar('$', '&modifiable')
- endfun
- " }}}
- "
- " === focus functions === }}}
- " === utility functions === {{{
- "
- " s:NextNormalWindow() {{{
- "
- " find next window with a normal buffer
- fun! s:NextNormalWindow()
- let l:i = 1
- while(l:i <= winnr('$'))
- let l:buf = winbufnr(l:i)
- " skip unlisted buffers
- if buflisted(l:buf) == 0
- let l:i = l:i + 1
- continue
- endif
- " skip un-modifiable buffers
- if getbufvar(l:buf, '&modifiable') != 1
- let l:i = l:i + 1
- continue
- endif
- " skip temporary buffers with buftype set
- if empty(getbufvar(l:buf, "&buftype")) != 1
- let l:i = l:i + 1
- continue
- endif
- return l:i
- endwhile
- return -1
- endfun
- " }}}
- " s:CloseIfOnlyNerdTreeLeft() {{{
- "
- " Close all open buffers on entering a window if the only
- " buffer that's left is the NERDTree buffer
- fun! s:CloseIfOnlyNerdTreeLeft()
- if exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) != -1 && winnr("$") == 1
- q
- endif
- endfun
- " }}}
- " s:IsCurrentWindowNERDTree() {{{
- "
- " returns 1 if current window is NERDTree, false otherwise
- fun! s:IsCurrentWindowNERDTree()
- return exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) == winnr()
- endfun
- " }}}
- " s:IsNERDTreeOpenInCurrentTab() {{{
- "
- " check if NERDTree is open in current tab
- fun! s:IsNERDTreeOpenInCurrentTab()
- return exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) != -1
- endfun
- " }}}
- " s:IsNERDTreePresentInCurrentTab() {{{
- "
- " check if NERDTree is present in current tab (not necessarily visible)
- fun! s:IsNERDTreePresentInCurrentTab()
- return exists("t:NERDTreeBufName")
- endfun
- " }}}
- "
- " === utility functions === }}}
- " === NERDTree view manipulation (scroll and cursor positions) === {{{
- "
- " s:SaveNERDTreeViewIfPossible() {{{
- "
- fun! s:SaveNERDTreeViewIfPossible()
- if exists("t:NERDTreeBufName") && bufwinnr(t:NERDTreeBufName) == winnr()
- " save scroll and cursor etc.
- let s:nerdtree_view = winsaveview()
- " save NERDTree window width
- let s:nerdtree_width = winwidth(winnr())
- " save buffer name (to be able to correct desync by commands spawning
- " a new NERDTree instance)
- let s:nerdtree_buffer = bufname("%")
- endif
- endfun
- " }}}
- " s:RestoreNERDTreeViewIfPossible() {{{
- "
- fun! s:RestoreNERDTreeViewIfPossible()
- " if nerdtree exists in current tab, it is the current window and if saved
- " state is available, restore it
- let l:view_state_saved = exists('s:nerdtree_view') && exists('s:nerdtree_width')
- if s:IsNERDTreeOpenInCurrentTab() && l:view_state_saved
- let l:current_winnr = winnr()
- let l:nerdtree_winnr = bufwinnr(t:NERDTreeBufName)
- " switch to NERDTree window
- exe l:nerdtree_winnr . "wincmd w"
- " load the correct NERDTree buffer if not already loaded
- if exists('s:nerdtree_buffer') && t:NERDTreeBufName != s:nerdtree_buffer
- silent NERDTreeClose
- silent NERDTreeMirror
- endif
- " restore cursor, scroll and window width
- call winrestview(s:nerdtree_view)
- exe "vertical resize " . s:nerdtree_width
- " switch back to whatever window was focused before
- exe l:current_winnr . "wincmd w"
- endif
- endfun
- " }}}
- "
- " === NERDTree view manipulation (scroll and cursor positions) === }}}
- "
- " === plugin functions === }}}
- " === plugin event handlers === {{{
- "
- " s:LoadPlugin() {{{
- "
- fun! s:LoadPlugin()
- if exists('g:nerdtree_tabs_loaded')
- return
- endif
- let g:NERDTreeHijackNetrw = 0
- let s:disable_handlers_for_tabdo = 0
- " global on/off NERDTree state
- " the exists check is to enable script reloading without resetting the state
- if !exists('s:nerdtree_globally_active')
- let s:nerdtree_globally_active = 0
- endif
- " global focused/unfocused NERDTree state
- " the exists check is to enable script reloading without resetting the state
- if !exists('s:is_nerdtree_globally_focused')
- call s:SaveGlobalFocus()
- end
- augroup NERDTreeTabs
- autocmd!
- autocmd VimEnter * call <SID>VimEnterHandler()
- autocmd TabEnter * call <SID>TabEnterHandler()
- autocmd TabLeave * call <SID>TabLeaveHandler()
- autocmd WinEnter * call <SID>WinEnterHandler()
- autocmd WinLeave * call <SID>WinLeaveHandler()
- autocmd BufWinEnter * call <SID>BufWinEnterHandler()
- augroup END
- let g:nerdtree_tabs_loaded = 1
- endfun
- " }}}
- " s:VimEnterHandler() {{{
- "
- fun! s:VimEnterHandler()
- " if the argument to vim is a directory, cd into it
- if g:nerdtree_tabs_startup_cd && isdirectory(argv(0))
- exe 'cd ' . escape(argv(0), '\ ')
- endif
- let l:open_nerd_tree_on_startup = (g:nerdtree_tabs_open_on_console_startup && !has('gui_running')) ||
- \ (g:nerdtree_tabs_open_on_gui_startup && has('gui_running'))
- if g:nerdtree_tabs_no_startup_for_diff && &diff
- let l:open_nerd_tree_on_startup = 0
- endif
- " this makes sure that globally_active is true when using 'gvim .'
- let s:nerdtree_globally_active = l:open_nerd_tree_on_startup
- if l:open_nerd_tree_on_startup
- let l:focus_file = !s:IfFocusOnStartup()
- let l:main_bufnr = bufnr('%')
- if !s:IsNERDTreePresentInCurrentTab()
- call s:NERDTreeOpenAllTabs()
- endif
- if (l:focus_file && g:nerdtree_tabs_smart_startup_focus == 1) || g:nerdtree_tabs_smart_startup_focus == 2
- exe bufwinnr(l:main_bufnr) . "wincmd w"
- endif
- endif
- endfun
- " }}} s:NewTabCreated {{{
- "
- " A flag to indicate that a new tab has just been created.
- "
- " We will handle the remaining work for this newly created tab separately in
- " BufWinEnter event.
- "
- let s:NewTabCreated = 0
- " }}}
- " s:TabEnterHandler() {{{
- "
- fun! s:TabEnterHandler()
- if s:disable_handlers_for_tabdo
- return
- endif
- if g:nerdtree_tabs_open_on_new_tab && s:nerdtree_globally_active && !s:IsNERDTreeOpenInCurrentTab()
- call s:NERDTreeMirrorOrCreate()
- " move focus to the previous window
- wincmd p
- " Turn on the 'NewTabCreated' flag
- let s:NewTabCreated = 1
- endif
- if g:nerdtree_tabs_synchronize_view
- call s:RestoreNERDTreeViewIfPossible()
- endif
- if g:nerdtree_tabs_focus_on_files
- call s:NERDTreeUnfocus()
- " Do not restore focus on newly created tab here
- elseif !s:NewTabCreated
- call s:NERDTreeRestoreFocus()
- endif
- endfun
- " }}}
- " s:TabLeaveHandler() {{{
- "
- fun! s:TabLeaveHandler()
- if g:nerdtree_tabs_meaningful_tab_names
- call s:SaveGlobalFocus()
- call s:NERDTreeUnfocus()
- endif
- endfun
- " }}}
- " s:WinEnterHandler() {{{
- "
- fun! s:WinEnterHandler()
- if s:disable_handlers_for_tabdo
- return
- endif
- if g:nerdtree_tabs_autoclose
- call s:CloseIfOnlyNerdTreeLeft()
- endif
- endfun
- " }}}
- " s:WinLeaveHandler() {{{
- "
- fun! s:WinLeaveHandler()
- if s:disable_handlers_for_tabdo
- return
- endif
- if g:nerdtree_tabs_synchronize_view
- call s:SaveNERDTreeViewIfPossible()
- endif
- endfun
- " }}}
- " s:BufWinEnterHandler() {{{
- "
- " BufWinEnter event only gets triggered after a new buffer has been
- " successfully loaded, it is a proper time to finish the remaining
- " work for newly opened tab.
- "
- fun! s:BufWinEnterHandler()
- if s:NewTabCreated
- " Turn off the 'NewTabCreated' flag
- let s:NewTabCreated = 0
- " Restore focus to NERDTree if necessary
- if !g:nerdtree_tabs_focus_on_files
- call s:NERDTreeRestoreFocus()
- endif
- endif
- endfun
- " }}}
- "
- " === plugin event handlers === }}}
- call s:LoadPlugin()
|