mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 06:30:03 +08:00
562 lines
18 KiB
VimL
562 lines
18 KiB
VimL
|
" ============================================================================
|
|||
|
" File: mundo.vim
|
|||
|
" Description: vim global plugin to visualize your undo tree
|
|||
|
" Maintainer: Hyeon Kim <simnalamburt@gmail.com>
|
|||
|
" License: GPLv2+ -- look it up.
|
|||
|
" Notes: Much of this code was thiefed from Mercurial, and the rest was
|
|||
|
" heavily inspired by scratch.vim and histwin.vim.
|
|||
|
"
|
|||
|
" ============================================================================
|
|||
|
|
|||
|
|
|||
|
let s:save_cpo = &cpoptions
|
|||
|
set cpoptions&vim
|
|||
|
|
|||
|
"{{{ Init
|
|||
|
|
|||
|
" Initialise global vars
|
|||
|
let s:auto_preview_timer = -1"{{{
|
|||
|
let s:preview_outdated = 1
|
|||
|
let s:has_supported_python = 0
|
|||
|
let s:has_timers = 0
|
|||
|
let s:init_error = 'Initialisation failed due to an unknown error. '
|
|||
|
\ . 'Please submit a bug report :)'
|
|||
|
|
|||
|
" This has to be outside of a function, otherwise it just picks up the CWD
|
|||
|
let s:plugin_path = escape(expand('<sfile>:p:h'), '\')"}}}
|
|||
|
|
|||
|
" Default to placeholder functions for exposed methods
|
|||
|
function! mundo#MundoToggle() abort "{{{
|
|||
|
call mundo#util#Echo('WarningMsg',
|
|||
|
\ 'Mundo init error: ' . s:init_error)
|
|||
|
endfunction
|
|||
|
|
|||
|
function! mundo#MundoShow() abort
|
|||
|
call mundo#util#Echo('WarningMsg',
|
|||
|
\ 'Mundo init error: ' . s:init_error)
|
|||
|
endfunction
|
|||
|
|
|||
|
function! mundo#MundoHide() abort
|
|||
|
call mundo#util#Echo('WarningMsg',
|
|||
|
\ 'Mundo init error: ' . s:init_error)
|
|||
|
endfunction
|
|||
|
"}}}
|
|||
|
|
|||
|
" Check vim version
|
|||
|
if v:version <? '703'"{{{
|
|||
|
let s:init_error = 'Vim version 7.03+ or later is required.'
|
|||
|
let &cpoptions = s:save_cpo
|
|||
|
finish
|
|||
|
elseif v:version >=? '800' && has('timers')
|
|||
|
let s:has_timers = 1
|
|||
|
endif"}}}
|
|||
|
|
|||
|
" Check python version
|
|||
|
if g:mundo_prefer_python3 && has('python3')"{{{
|
|||
|
let s:has_supported_python = 2
|
|||
|
elseif has('python')"
|
|||
|
let s:has_supported_python = 1
|
|||
|
elseif has('python3')"
|
|||
|
let s:has_supported_python = 2
|
|||
|
endif
|
|||
|
|
|||
|
if !s:has_supported_python
|
|||
|
let s:init_error = 'A supported python version was not found.'
|
|||
|
let &cpoptions = s:save_cpo
|
|||
|
finish
|
|||
|
endif"}}}
|
|||
|
|
|||
|
" Python init methods
|
|||
|
function! s:InitPythonModule(python)"{{{
|
|||
|
exe a:python .' import sys'
|
|||
|
exe a:python .' if sys.version_info[:2] < (2, 4): '.
|
|||
|
\ 'vim.command("let s:has_supported_python = 0")'
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoSetupPythonPath()"{{{
|
|||
|
if g:mundo_python_path_setup == 0
|
|||
|
let g:mundo_python_path_setup = 1
|
|||
|
call s:MundoPython('sys.path.insert(1, "'. s:plugin_path .'")')
|
|||
|
call s:MundoPython('sys.path.insert(1, "'. s:plugin_path .'/mundo")')
|
|||
|
end
|
|||
|
endfunction"}}}
|
|||
|
"}}}
|
|||
|
|
|||
|
"{{{ Mundo buffer settings
|
|||
|
|
|||
|
function! s:MundoMakeMapping(mapping, action)
|
|||
|
exec 'nnoremap <script> <silent> <buffer> ' . a:mapping .' '. a:action
|
|||
|
endfunction
|
|||
|
|
|||
|
function! s:MundoMapGraph()"{{{
|
|||
|
for key in keys(g:mundo_mappings)
|
|||
|
let l:value = g:mundo_mappings[key]
|
|||
|
if l:value == "move_older"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoMove(1,'. v:count .')')<CR>")
|
|||
|
elseif l:value == "move_newer"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoMove(-1,'. v:count .')')<CR>")
|
|||
|
elseif l:value == "preview"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoRenderPreview(1)<CR>:<C-u> call <sid>MundoPythonRestoreView('MundoRevert()')<CR>")
|
|||
|
elseif l:value == "move_older_write"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoMove(1,'.v:count.',True,True)')<CR>")
|
|||
|
elseif l:value == "move_newer_write"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoMove(-1,'.v:count.',True,True)')<CR>")
|
|||
|
elseif l:value == "move_top"
|
|||
|
call s:MundoMakeMapping(key, "gg:<C-u>call <sid>MundoPython('MundoMove(1,'.v:count.')')<CR>")
|
|||
|
elseif l:value == "move_bottom"
|
|||
|
call s:MundoMakeMapping(key, "G:<C-u>call <sid>MundoPython('MundoMove(0,0)')<CR>:<C-u>call <sid>MundoRefresh()<CR>")
|
|||
|
elseif l:value == "play_to"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPythonRestoreView('MundoPlayTo()')<CR>zz")
|
|||
|
elseif l:value == "diff"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPythonRestoreView('MundoRenderPatchdiff()')<CR>")
|
|||
|
elseif l:value == "toggle_inline"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPythonRestoreView('MundoRenderToggleInlineDiff()')<CR>")
|
|||
|
elseif l:value == "search"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoSearch()')<CR>")
|
|||
|
elseif l:value == "next_match"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoNextMatch()')<CR>")
|
|||
|
elseif l:value == "previous_match"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoPrevMatch()')<CR>")
|
|||
|
elseif l:value == "diff_current_buffer"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPythonRestoreView('MundoRenderChangePreview()')<CR>")
|
|||
|
elseif l:value == "diff"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoRenderPreview(1)<CR>")
|
|||
|
elseif l:value == "toggle_help"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoPython('MundoToggleHelp()')<CR>")
|
|||
|
elseif l:value == "quit"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoClose()<CR>")
|
|||
|
elseif l:value == "mouse_click"
|
|||
|
call s:MundoMakeMapping(key, ":<C-u>call <sid>MundoMouseDoubleClick()<CR>")
|
|||
|
endif
|
|||
|
endfor
|
|||
|
|
|||
|
cabbrev <script> <silent> <buffer> q call <sid>MundoClose()
|
|||
|
cabbrev <script> <silent> <buffer> quit call <sid>MundoClose()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoMapPreview()"{{{
|
|||
|
nnoremap <script> <silent> <buffer> q :<C-u>call <sid>MundoClose()<CR>
|
|||
|
cabbrev <script> <silent> <buffer> q call <sid>MundoClose()
|
|||
|
cabbrev <script> <silent> <buffer> quit call <sid>MundoClose()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoSettingsGraph()"{{{
|
|||
|
setlocal buftype=nofile
|
|||
|
setlocal bufhidden=hide
|
|||
|
setlocal noswapfile
|
|||
|
setlocal nobuflisted
|
|||
|
setlocal nomodifiable
|
|||
|
setlocal filetype=Mundo
|
|||
|
setlocal nolist
|
|||
|
setlocal nonumber
|
|||
|
setlocal norelativenumber
|
|||
|
setlocal nowrap
|
|||
|
call s:MundoSyntaxGraph()
|
|||
|
call s:MundoMapGraph()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoSettingsPreview()"{{{
|
|||
|
setlocal buftype=nofile
|
|||
|
setlocal bufhidden=hide
|
|||
|
setlocal noswapfile
|
|||
|
setlocal nobuflisted
|
|||
|
setlocal nomodifiable
|
|||
|
setlocal filetype=MundoDiff
|
|||
|
setlocal syntax=diff
|
|||
|
setlocal nonumber
|
|||
|
setlocal norelativenumber
|
|||
|
setlocal nowrap
|
|||
|
setlocal foldlevel=20
|
|||
|
setlocal foldmethod=diff
|
|||
|
call s:MundoMapPreview()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoSyntaxGraph()"{{{
|
|||
|
let b:current_syntax = 'mundo'
|
|||
|
syn match MundoCurrentLocation '@'
|
|||
|
syn match MundoHelp '\v^".*$'
|
|||
|
syn match MundoNumberField '\v\[[0-9]+\]'
|
|||
|
syn match MundoNumber '\v[0-9]+' contained containedin=MundoNumberField
|
|||
|
syn region MundoDiff start=/\v<ago> / end=/$/
|
|||
|
syn match MundoDiffAdd '\v\+[^+-]+\+' contained containedin=MundoDiff
|
|||
|
syn match MundoDiffDelete '\v-[^+-]+-' contained containedin=MundoDiff
|
|||
|
hi def link MundoCurrentLocation Keyword
|
|||
|
hi def link MundoHelp Comment
|
|||
|
hi def link MundoNumberField Comment
|
|||
|
hi def link MundoNumber Identifier
|
|||
|
hi def link MundoDiffAdd DiffAdd
|
|||
|
hi def link MundoDiffDelete DiffDelete
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
"}}}
|
|||
|
|
|||
|
"{{{ Mundo buffer/window management
|
|||
|
|
|||
|
function! s:MundoResizeBuffers(backto)"{{{
|
|||
|
call mundo#util#GoToBuffer('__Mundo__')
|
|||
|
exe "vertical resize " . g:mundo_width
|
|||
|
|
|||
|
call mundo#util#GoToBuffer('__Mundo_Preview__')
|
|||
|
exe "resize " . g:mundo_preview_height
|
|||
|
|
|||
|
exe a:backto . "wincmd w"
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
" Open the graph window. Assumes that the preview window is open.
|
|||
|
function! s:MundoOpenGraph()"{{{
|
|||
|
if !mundo#util#GoToBuffer("__Mundo__")
|
|||
|
call assert_true(mundo#util#GoToBuffer('__Mundo_Preview__'))
|
|||
|
let existing_mundo_buffer = bufnr("__Mundo__")
|
|||
|
|
|||
|
if existing_mundo_buffer == -1
|
|||
|
" Create buffer
|
|||
|
silent new __Mundo__
|
|||
|
|
|||
|
if g:mundo_preview_bottom
|
|||
|
execute 'wincmd ' . (g:mundo_right ? 'L' : 'H')
|
|||
|
endif
|
|||
|
else
|
|||
|
" Open a window for existing buffer
|
|||
|
if g:mundo_preview_bottom
|
|||
|
let pos = (g:mundo_right ? 'botright' : 'topleft')
|
|||
|
silent execute pos.' vsplit +buffer' . existing_mundo_buffer
|
|||
|
else
|
|||
|
silent execute 'split +buffer' . existing_mundo_buffer
|
|||
|
endif
|
|||
|
endif
|
|||
|
|
|||
|
call s:MundoResizeBuffers(winnr())
|
|||
|
endif
|
|||
|
|
|||
|
if exists("g:mundo_tree_statusline")
|
|||
|
let &l:statusline = g:mundo_tree_statusline
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoOpenPreview()"{{{
|
|||
|
if !mundo#util#GoToBuffer("__Mundo_Preview__")
|
|||
|
let existing_preview_buffer = bufnr("__Mundo_Preview__")
|
|||
|
|
|||
|
if existing_preview_buffer == -1
|
|||
|
" Create buffer
|
|||
|
if g:mundo_preview_bottom
|
|||
|
silent botright keepalt new __Mundo_Preview__
|
|||
|
else
|
|||
|
let pos = (g:mundo_right ? 'botright' : 'topleft')
|
|||
|
silent execute pos.' keepalt vnew __Mundo_Preview__'
|
|||
|
endif
|
|||
|
else
|
|||
|
" Open a window for existing buffer
|
|||
|
if g:mundo_preview_bottom
|
|||
|
silent execute 'botright keepalt split +buffer' .
|
|||
|
\ existing_preview_buffer
|
|||
|
else
|
|||
|
let pos = (g:mundo_right ? 'botright' : 'topleft')
|
|||
|
silent execute pos.' keepalt vsplit +buffer' .
|
|||
|
\ existing_preview_buffer
|
|||
|
endif
|
|||
|
endif
|
|||
|
endif
|
|||
|
|
|||
|
if exists("g:mundo_preview_statusline")
|
|||
|
let &l:statusline = g:mundo_preview_statusline
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
" Quits *all* open Mundo graph and preview windows.
|
|||
|
function! s:MundoClose() abort
|
|||
|
let [l:tabid, l:winid] = win_id2tabwin(win_getid())
|
|||
|
|
|||
|
" Close all graph and preview windows
|
|||
|
while mundo#util#GoToBufferGlobal('__Mundo__') ||
|
|||
|
\ mundo#util#GoToBufferGlobal('__Mundo_Preview__')
|
|||
|
quit
|
|||
|
endwhile
|
|||
|
|
|||
|
" Attempt to return to previous window / tab or target buffer
|
|||
|
if win_gotoid(l:winid)
|
|||
|
return
|
|||
|
elseif l:tabid != 0 && l:tabid <= tabpagenr('$')
|
|||
|
execute 'normal! ' . l:tabid . 'gt'
|
|||
|
endif
|
|||
|
|
|||
|
call mundo#util#GoToBuffer(get(g:, 'mundo_target_n', -1))
|
|||
|
endfunction
|
|||
|
|
|||
|
" Returns 1 if the current buffer is a valid target buffer for Mundo, or a
|
|||
|
" (falsy) string indicating the reason if otherwise.
|
|||
|
function! s:MundoValidateBuffer()"{{{
|
|||
|
if !&modifiable
|
|||
|
let reason = 'is not modifiable'
|
|||
|
elseif &previewwindow
|
|||
|
let reason = 'is a preview window'
|
|||
|
elseif &buftype == 'help' || &buftype == 'quickfix' || &buftype == 'terminal'
|
|||
|
let reason = 'is a '.&buftype.' window'
|
|||
|
else
|
|||
|
return 1
|
|||
|
endif
|
|||
|
|
|||
|
call mundo#util#Echo('None', 'Current buffer ('.bufnr('').') is not a '
|
|||
|
\ .'valid target for Mundo (Reason: '.reason.')')
|
|||
|
return 0
|
|||
|
endfunction "}}}
|
|||
|
|
|||
|
" Returns True if the graph or preview windows are open in the current tab.
|
|||
|
function! s:MundoIsVisible()"{{{
|
|||
|
return bufwinnr(bufnr("__Mundo__")) != -1 ||
|
|||
|
\ bufwinnr(bufnr("__Mundo_Preview__")) != -1
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
" Open/reopen Mundo for the current buffer, initialising the python module if
|
|||
|
" necessary.
|
|||
|
function! s:MundoOpen() abort "{{{
|
|||
|
" Validate current buffer
|
|||
|
if !s:MundoValidateBuffer()
|
|||
|
return
|
|||
|
endif
|
|||
|
|
|||
|
let g:mundo_target_n = bufnr('')
|
|||
|
call s:MundoClose()
|
|||
|
|
|||
|
" Initialise python module if necessary
|
|||
|
if !exists('g:mundo_py_loaded')
|
|||
|
call s:MundoSetupPythonPath()
|
|||
|
|
|||
|
if s:has_supported_python == 2
|
|||
|
exe 'py3file ' . escape(s:plugin_path, ' ') . '/mundo.py'
|
|||
|
call s:InitPythonModule('python3')
|
|||
|
else
|
|||
|
exe 'pyfile ' . escape(s:plugin_path, ' ') . '/mundo.py'
|
|||
|
call s:InitPythonModule('python')
|
|||
|
endif
|
|||
|
|
|||
|
let g:mundo_py_loaded = 1
|
|||
|
endif
|
|||
|
|
|||
|
" Save and reset `splitbelow` to avoid window positioning problems
|
|||
|
let saved_splitbelow = &splitbelow
|
|||
|
let &splitbelow = 0
|
|||
|
|
|||
|
" Temporarily disable automatic previews until Mundo is opened
|
|||
|
let saved_auto_preview = g:mundo_auto_preview
|
|||
|
let g:mundo_auto_preview = 0
|
|||
|
|
|||
|
" Create / open graph and preview windows
|
|||
|
call s:MundoOpenPreview()
|
|||
|
call mundo#util#GoToBuffer(g:mundo_target_n)
|
|||
|
call s:MundoOpenGraph()
|
|||
|
|
|||
|
" Render the graph and preview, ensure the cursor is on a graph node
|
|||
|
call s:MundoPythonRestoreView('MundoRenderGraph(True)')
|
|||
|
call s:MundoRenderPreview()
|
|||
|
call s:MundoPython('MundoMove(0,0)')
|
|||
|
|
|||
|
" Restore `splitbelow` and automatic preview option
|
|||
|
let &splitbelow = saved_splitbelow
|
|||
|
let g:mundo_auto_preview = saved_auto_preview
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoToggle()"{{{
|
|||
|
if s:MundoIsVisible()
|
|||
|
call s:MundoClose()
|
|||
|
else
|
|||
|
call s:MundoOpen()
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoShow()"{{{
|
|||
|
if !s:MundoIsVisible()
|
|||
|
call s:MundoOpen()
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoHide()"{{{
|
|||
|
call s:MundoSetupPythonPath()
|
|||
|
if s:MundoIsVisible()
|
|||
|
call s:MundoClose()
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
"}}}
|
|||
|
|
|||
|
"{{{ Mundo mouse handling
|
|||
|
|
|||
|
function! s:MundoMouseDoubleClick()"{{{
|
|||
|
let start_line = getline('.')
|
|||
|
|
|||
|
if stridx(start_line, '[') == -1
|
|||
|
return
|
|||
|
else
|
|||
|
call <sid>MundoPythonRestoreView('MundoRevert()')
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
"}}}
|
|||
|
|
|||
|
"{{{ Mundo rendering
|
|||
|
|
|||
|
function! s:MundoPython(fn)"{{{
|
|||
|
exec "python".(s:has_supported_python == 2 ? '3' : '')." ". a:fn
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
" Wrapper for MundoPython() that restores the window state and prevents other
|
|||
|
" Mundo autocommands (with the exception of BufNewFile) from triggering.
|
|||
|
function! s:MundoPythonRestoreView(fn)"{{{
|
|||
|
" Store view data, mode, window and 'evntignore' value
|
|||
|
let currentmode = mode()
|
|||
|
let currentWin = winnr()
|
|||
|
let winView = winsaveview()
|
|||
|
let eventignoreBack = &eventignore
|
|||
|
set eventignore=BufLeave,BufEnter,CursorHold,CursorMoved,TextChanged
|
|||
|
\,InsertLeave
|
|||
|
|
|||
|
" Call python function
|
|||
|
call s:MundoPython(a:fn)
|
|||
|
|
|||
|
" Restore view data
|
|||
|
execute currentWin .'wincmd w'
|
|||
|
call winrestview(winView)
|
|||
|
exec 'set eventignore='.eventignoreBack
|
|||
|
|
|||
|
" Re-select visual selection
|
|||
|
if currentmode == 'v' || currentmode == 'V' || currentmode == ''
|
|||
|
execute 'normal! gv'
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
" Accepts an optional integer that forces rendering if nonzero.
|
|||
|
function! s:MundoRenderPreview(...)"{{{
|
|||
|
if !s:preview_outdated && (a:0 < 1 || !a:1)
|
|||
|
return
|
|||
|
endif
|
|||
|
|
|||
|
call s:MundoPythonRestoreView('MundoRenderPreview()')
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
"}}}
|
|||
|
|
|||
|
"{{{ Misc
|
|||
|
|
|||
|
" automatically reload Mundo buffer if open
|
|||
|
function! s:MundoRefresh()"{{{
|
|||
|
" abort if Mundo is closed or cursor is in the preview window
|
|||
|
let mundoWin = bufwinnr('__Mundo__')
|
|||
|
let mundoPreWin = bufwinnr('__Mundo_Preview__')
|
|||
|
let currentWin = bufwinnr('%')
|
|||
|
|
|||
|
if mundoWin == -1 || mundoPreWin == -1 || mundoPreWin == currentWin
|
|||
|
return
|
|||
|
endif
|
|||
|
|
|||
|
" Disable the automatic preview delay if vim lacks support for timers
|
|||
|
if g:mundo_auto_preview_delay > 0 && !s:has_timers
|
|||
|
let g:mundo_auto_preview_delay = 0
|
|||
|
call mundo#util#Echo('WarningMsg',
|
|||
|
\ 'The "g:mundo_auto_preview_delay" option requires'
|
|||
|
\ .' support for timers. Please upgrade to either vim 8.0+'
|
|||
|
\ .' (with +timers) or neovim to use this feature. Press '
|
|||
|
\ .'any key to continue.')
|
|||
|
|
|||
|
" Prevent the warning being cleared
|
|||
|
call getchar()
|
|||
|
endif
|
|||
|
|
|||
|
" Handle normal refresh
|
|||
|
if g:mundo_auto_preview_delay <= 0
|
|||
|
call s:MundoPythonRestoreView('MundoRenderGraph()')
|
|||
|
|
|||
|
if g:mundo_auto_preview && currentWin == mundoWin && mode() == 'n'
|
|||
|
call s:MundoRenderPreview()
|
|||
|
endif
|
|||
|
return
|
|||
|
endif
|
|||
|
|
|||
|
" Handle delayed refresh
|
|||
|
call s:MundoRestartRefreshTimer()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoRestartRefreshTimer()"{{{
|
|||
|
call s:MundoStopRefreshTimer()
|
|||
|
let s:auto_preview_timer = timer_start(
|
|||
|
\ get(g:, 'mundo_auto_preview_delay', 0),
|
|||
|
\ function('s:MundoRefreshDelayed')
|
|||
|
\ )
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoStopRefreshTimer()"{{{
|
|||
|
if s:auto_preview_timer != -1
|
|||
|
call timer_stop(s:auto_preview_timer)
|
|||
|
let s:auto_preview_timer = -1
|
|||
|
endif
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! s:MundoRefreshDelayed(...)"{{{
|
|||
|
" abort if Mundo is closed or cursor is in the preview window
|
|||
|
let mundoWin = bufwinnr('__Mundo__')
|
|||
|
let mundoPreWin = bufwinnr('__Mundo_Preview__')
|
|||
|
let currentWin = bufwinnr('%')
|
|||
|
|
|||
|
if mundoWin == -1 || mundoPreWin == -1 || mundoPreWin == currentWin
|
|||
|
return
|
|||
|
endif
|
|||
|
|
|||
|
" Update graph
|
|||
|
call s:MundoPythonRestoreView('MundoRenderGraph()')
|
|||
|
|
|||
|
" Update preview
|
|||
|
if currentWin != mundoWin || !g:mundo_auto_preview
|
|||
|
return
|
|||
|
endif
|
|||
|
|
|||
|
if mode() != 'n'
|
|||
|
call s:MundoRestartRefreshTimer()
|
|||
|
return
|
|||
|
endif
|
|||
|
|
|||
|
call s:MundoRenderPreview()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
" Mark the preview as being up-to-date (0) or outdated (1)
|
|||
|
function! mundo#MundoPreviewOutdated(outdated)"{{{
|
|||
|
if s:preview_outdated && !a:outdated
|
|||
|
call s:MundoStopRefreshTimer()
|
|||
|
endif
|
|||
|
|
|||
|
let s:preview_outdated = a:outdated
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
augroup MundoAug
|
|||
|
autocmd!
|
|||
|
autocmd BufEnter __Mundo__ call mundo#MundoPreviewOutdated(1)
|
|||
|
autocmd BufLeave __Mundo__
|
|||
|
\ if g:mundo_auto_preview |
|
|||
|
\ call s:MundoRenderPreview() |
|
|||
|
\ call s:MundoStopRefreshTimer() |
|
|||
|
\ endif |
|
|||
|
autocmd BufEnter __Mundo__ call s:MundoSettingsGraph()
|
|||
|
autocmd BufEnter __Mundo_Preview__ call s:MundoSettingsPreview()
|
|||
|
autocmd CursorHold,CursorMoved,TextChanged,InsertLeave *
|
|||
|
\ call s:MundoRefresh()
|
|||
|
augroup END
|
|||
|
|
|||
|
"}}}
|
|||
|
|
|||
|
" Exposed functions{{{
|
|||
|
|
|||
|
function! mundo#MundoToggle()"{{{
|
|||
|
call s:MundoToggle()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! mundo#MundoShow()"{{{
|
|||
|
call s:MundoShow()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
function! mundo#MundoHide()"{{{
|
|||
|
call s:MundoHide()
|
|||
|
endfunction"}}}
|
|||
|
|
|||
|
"}}}
|
|||
|
|
|||
|
let &cpoptions = s:save_cpo
|
|||
|
unlet s:save_cpo
|