| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- " ============================================================================
- " 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.
- "
- " ============================================================================
- "{{{ Init
- let s:save_cpo = &cpo
- set cpo&vim
- if v:version < '703'"{{{
- function! s:MundoDidNotLoad()
- echohl WarningMsg|echomsg "Mundo unavailable: requires Vim 7.3+"|echohl None
- endfunction
- command! -nargs=0 MundoToggle call s:MundoDidNotLoad()
- finish
- endif"}}}
- call mundo#util#init()
- let s:has_supported_python = 0
- if g:mundo_prefer_python3 && has('python3')"{{{
- let s:has_supported_python = 2
- elseif has('python')"
- let s:has_supported_python = 1
- endif
- if !s:has_supported_python
- function! s:MundoDidNotLoad()
- echohl WarningMsg|echomsg "Mundo requires Vim to be compiled with Python 2.4+"|echohl None
- endfunction
- command! -nargs=0 MundoToggle call s:MundoDidNotLoad()
- finish
- endif"}}}
- let s:plugin_path = escape(expand('<sfile>:p:h'), '\')
- "}}}
- "{{{ Mundo utility functions
- function! s:MundoGoToWindowForBufferName(name)"{{{
- if bufwinnr(bufnr(a:name)) != -1
- exe bufwinnr(bufnr(a:name)) . "wincmd w"
- return 1
- else
- return 0
- endif
- endfunction"}}}
- function! s:MundoIsVisible()"{{{
- if bufwinnr(bufnr("__Mundo__")) != -1 || bufwinnr(bufnr("__Mundo_Preview__")) != -1
- return 1
- else
- return 0
- endif
- endfunction"}}}
- function! s:MundoInlineHelpLength()"{{{
- if g:mundo_help
- return 10
- else
- return 0
- endif
- endfunction"}}}
- "}}}
- "{{{ Mundo buffer settings
- function! s:MundoMapGraph()"{{{
- exec 'nnoremap <script> <silent> <buffer> ' . g:mundo_map_move_older . " :<C-u>call <sid>MundoPython('MundoMove(1,'. v:count .')')<CR>"
- exec 'nnoremap <script> <silent> <buffer> ' . g:mundo_map_move_newer . " :<C-u>call <sid>MundoPython('MundoMove(-1,'. v:count .')')<CR>"
- nnoremap <script> <silent> <buffer> <CR> :call <sid>MundoPython('MundoRevert()')<CR>
- nnoremap <script> <silent> <buffer> o :call <sid>MundoPython('MundoRevert()')<CR>
- nnoremap <script> <silent> <buffer> <down> :<C-u>call <sid>MundoPython('MundoMove(1,'. v:count .')')<CR>
- nnoremap <script> <silent> <buffer> <up> :<C-u>call <sid>MundoPython('MundoMove(-1,'. v:count .')')<CR>
- nnoremap <script> <silent> <buffer> J :<C-u>call <sid>MundoPython('MundoMove(1,'. v:count .',True,True)')<CR>
- nnoremap <script> <silent> <buffer> K :<C-u>call <sid>MundoPython('MundoMove(-1,'. v:count .',True,True)')<CR>
- nnoremap <script> <silent> <buffer> gg gg:<C-u>call <sid>MundoPython('MundoMove(1,'. v:count .')')<CR>
- nnoremap <script> <silent> <buffer> P :call <sid>MundoPython('MundoPlayTo()')<CR>
- nnoremap <script> <silent> <buffer> d :call <sid>MundoPython('MundoRenderPatchdiff()')<CR>
- nnoremap <script> <silent> <buffer> i :call <sid>MundoPython('MundoRenderToggleInlineDiff()')<CR>
- nnoremap <script> <silent> <buffer> / :call <sid>MundoPython('MundoSearch()')<CR>
- nnoremap <script> <silent> <buffer> n :call <sid>MundoPython('MundoNextMatch()')<CR>
- nnoremap <script> <silent> <buffer> N :call <sid>MundoPython('MundoPrevMatch()')<CR>
- nnoremap <script> <silent> <buffer> p :call <sid>MundoPython('MundoRenderChangePreview()')<CR>
- nnoremap <script> <silent> <buffer> r :call <sid>MundoPython('MundoRenderPreview()')<CR>
- nnoremap <script> <silent> <buffer> ? :call <sid>MundoPython('MundoToggleHelp()')<CR>
- nnoremap <script> <silent> <buffer> q :call <sid>MundoClose()<CR>
- cabbrev <script> <silent> <buffer> q call <sid>MundoClose()
- cabbrev <script> <silent> <buffer> quit call <sid>MundoClose()
- nnoremap <script> <silent> <buffer> <2-LeftMouse> :call <sid>MundoMouseDoubleClick()<CR>
- endfunction"}}}
- function! s:MundoMapPreview()"{{{
- nnoremap <script> <silent> <buffer> q :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=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 s:MundoGoToWindowForBufferName('__Mundo__')
- exe "vertical resize " . g:mundo_width
- call s:MundoGoToWindowForBufferName('__Mundo_Preview__')
- exe "resize " . g:mundo_preview_height
- exe a:backto . "wincmd w"
- endfunction"}}}
- function! s:MundoOpenGraph()"{{{
- let existing_mundo_buffer = bufnr("__Mundo__")
- if existing_mundo_buffer == -1
- call s:MundoGoToWindowForBufferName('__Mundo_Preview__')
- exe "new __Mundo__"
- set fdm=manual
- if g:mundo_preview_bottom
- if g:mundo_right
- wincmd L
- else
- wincmd H
- endif
- endif
- call s:MundoResizeBuffers(winnr())
- else
- let existing_mundo_window = bufwinnr(existing_mundo_buffer)
- if existing_mundo_window != -1
- if winnr() != existing_mundo_window
- exe existing_mundo_window . "wincmd w"
- endif
- else
- call s:MundoGoToWindowForBufferName('__Mundo_Preview__')
- if g:mundo_preview_bottom
- if g:mundo_right
- exe "botright vsplit +buffer" . existing_mundo_buffer
- else
- exe "topleft vsplit +buffer" . existing_mundo_buffer
- endif
- else
- exe "split +buffer" . existing_mundo_buffer
- endif
- call s:MundoResizeBuffers(winnr())
- endif
- endif
- if exists("g:mundo_tree_statusline")
- let &l:statusline = g:mundo_tree_statusline
- endif
- endfunction"}}}
- function! s:MundoOpenPreview()"{{{
- let existing_preview_buffer = bufnr("__Mundo_Preview__")
- if existing_preview_buffer == -1
- if g:mundo_preview_bottom
- exe "botright keepalt new __Mundo_Preview__"
- else
- if g:mundo_right
- exe "botright keepalt vnew __Mundo_Preview__"
- else
- exe "topleft keepalt vnew __Mundo_Preview__"
- endif
- endif
- else
- let existing_preview_window = bufwinnr(existing_preview_buffer)
- if existing_preview_window != -1
- if winnr() != existing_preview_window
- exe existing_preview_window . "wincmd w"
- endif
- else
- if g:mundo_preview_bottom
- exe "botright keepalt split +buffer" . existing_preview_buffer
- else
- if g:mundo_right
- exe "botright keepalt vsplit +buffer" . existing_preview_buffer
- else
- exe "topleft keepalt vsplit +buffer" . existing_preview_buffer
- endif
- endif
- endif
- endif
- if exists("g:mundo_preview_statusline")
- let &l:statusline = g:mundo_preview_statusline
- endif
- endfunction"}}}
- function! s:MundoClose()"{{{
- if s:MundoGoToWindowForBufferName('__Mundo__')
- quit
- endif
- if s:MundoGoToWindowForBufferName('__Mundo_Preview__')
- quit
- endif
- exe bufwinnr(g:mundo_target_n) . "wincmd w"
- endfunction"}}}
- function! s:MundoOpen()"{{{
- if !exists('g:mundo_py_loaded')
- if s:has_supported_python == 2 && g:mundo_prefer_python3
- exe 'py3file ' . escape(s:plugin_path, ' ') . '/mundo.py'
- python3 initPythonModule()
- else
- exe 'pyfile ' . escape(s:plugin_path, ' ') . '/mundo.py'
- python initPythonModule()
- endif
- if !s:has_supported_python
- function! s:MundoDidNotLoad()
- echohl WarningMsg|echomsg "Mundo unavailable: requires Vim 7.3+"|echohl None
- endfunction
- command! -nargs=0 MundoToggle call s:MundoDidNotLoad()
- call s:MundoDidNotLoad()
- return
- endif
- let g:mundo_py_loaded = 1
- endif
- " Save `splitbelow` value and set it to default to avoid problems with
- " positioning new windows.
- let saved_splitbelow = &splitbelow
- let &splitbelow = 0
- call s:MundoOpenPreview()
- exe bufwinnr(g:mundo_target_n) . "wincmd w"
- call s:MundoOpenGraph()
- call s:MundoPython('MundoRenderGraph()')
- call s:MundoPython('MundoRenderPreview()')
- " Restore `splitbelow` value.
- let &splitbelow = saved_splitbelow
- endfunction"}}}
- " This has to be outside of a function otherwise it just picks up the CWD
- let s:mundo_path = escape( expand( '<sfile>:p:h' ), '\' )
- function! s:MundoToggle()"{{{
- if g:mundo_python_path_setup == 0
- let g:mundo_python_path_setup = 1
- call s:MundoPython('sys.path.insert(1, "'. s:mundo_path .'")')
- call s:MundoPython('sys.path.insert(1, "'. s:mundo_path .'/mundo")')
- end
- if s:MundoIsVisible()
- call s:MundoClose()
- else
- let g:mundo_target_n = bufnr('')
- let g:mundo_target_f = @%
- call s:MundoOpen()
- endif
- endfunction"}}}
- function! s:MundoShow()"{{{
- if !s:MundoIsVisible()
- let g:mundo_target_n = bufnr('')
- let g:mundo_target_f = @%
- call s:MundoOpen()
- endif
- endfunction"}}}
- function! s:MundoHide()"{{{
- 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>MundoPython('MundoRevert()')
- endif
- endfunction"}}}
- "}}}
- "{{{ Mundo rendering
- function! s:MundoPython(fn)"{{{
- if s:has_supported_python == 2 && g:mundo_prefer_python3
- exec "python3 ". a:fn
- else
- exec "python ". a:fn
- endif
- endfunction"}}}
- "}}}
- "{{{ Misc
- function! mundo#MundoToggle()"{{{
- call s:MundoToggle()
- endfunction"}}}
- function! mundo#MundoShow()"{{{
- call s:MundoShow()
- endfunction"}}}
- function! mundo#MundoHide()"{{{
- call s:MundoHide()
- endfunction"}}}
- function! mundo#MundoRenderGraph()"{{{
- call s:MundoPython('MundoRenderGraph()')
- endfunction"}}}
- " automatically reload Mundo buffer if open
- function! s:MundoRefresh()"{{{
- " abort when there were no changes
- let mundoWin = bufwinnr('__Mundo__')
- let mundoPreWin = bufwinnr('__Mundo_Preview__')
- let currentWin = bufwinnr('%')
- " abort if Mundo is closed or is current window
- if (mundoWin == -1) || (mundoPreWin == -1) || (mundoPreWin == currentWin)
- return
- endif
- let winView = winsaveview()
- :MundoRenderGraph
- " switch back to previous window
- execute currentWin .'wincmd w'
- call winrestview(winView)
- endfunction"}}}
- augroup MundoAug
- autocmd!
- autocmd BufNewFile __Mundo__ call s:MundoSettingsGraph()
- autocmd BufNewFile __Mundo_Preview__ call s:MundoSettingsPreview()
- autocmd CursorHold * call s:MundoRefresh()
- autocmd CursorMoved * call s:MundoRefresh()
- autocmd BufEnter * let b:mundoChangedtick = 0
- augroup END
- "}}}
- let &cpo = s:save_cpo
- unlet s:save_cpo
|