fix undo restore failing when empty undo history

Fix #339
This commit is contained in:
haya14busa 2017-07-15 04:49:37 +00:00
parent d55e7bf515
commit 3f844bcfd0
2 changed files with 54 additions and 29 deletions

View File

@ -739,14 +739,6 @@ function! s:GetVisualStartPosition(c_pos, v_start, v_end, search_direction) "{{{
endfunction "}}} endfunction "}}}
" -- Others ------------------------------ " -- Others ------------------------------
function! s:is_cmdwin() "{{{
return bufname('%') ==# '[Command Line]'
endfunction "}}}
function! s:should_use_wundo() "{{{
" wundu cannot use in command-line window and
" unless undolist is not empty
return ! s:is_cmdwin() && undotree().seq_last != 0
endfunction "}}}
function! s:handleEmpty(input, visualmode) "{{{ function! s:handleEmpty(input, visualmode) "{{{
" if empty, reselect and return 1 " if empty, reselect and return 1
if empty(a:input) if empty(a:input)
@ -1104,12 +1096,8 @@ function! s:PromptUser(groups) "{{{
" }}} " }}}
" -- Put labels on targets & Get User Input & Restore all {{{ " -- Put labels on targets & Get User Input & Restore all {{{
" Save undo tree {{{ " Save undo tree
let s:undo_file = tempname() let undo_lock = EasyMotion#undo#save()
if s:should_use_wundo()
execute "wundo" s:undo_file
endif
"}}}
try try
" Set lines with markers {{{ " Set lines with markers {{{
call s:SetLines(lines_items, 'marker') call s:SetLines(lines_items, 'marker')
@ -1156,21 +1144,8 @@ function! s:PromptUser(groups) "{{{
\ ) \ )
" }}} " }}}
" Restore undo tree {{{ " Restore undo tree
if s:should_use_wundo() && filereadable(s:undo_file) call undo_lock.restore()
silent execute "rundo" s:undo_file
call delete(s:undo_file)
unlet s:undo_file
else
" Break undo history (undobreak)
let old_undolevels = &undolevels
set undolevels=-1
keepjumps call setline('.', getline('.'))
let &undolevels = old_undolevels
unlet old_undolevels
" FIXME: Error occur by GundoToggle for undo number 2 is empty
keepjumps call setline('.', getline('.'))
endif "}}}
redraw redraw
endtry "}}} endtry "}}}

View File

@ -0,0 +1,50 @@
let s:Buffer = vital#easymotion#import('Vim.Buffer')
function! EasyMotion#undo#save() abort
return s:undo_lock.save()
endfunction
let s:undo_lock = {}
function! s:undo_lock.save() abort
let undo = deepcopy(self)
call undo._save()
return undo
endfunction
function! s:undo_lock._save() abort
if undotree().seq_last == 0
" if there are no undo history, disable undo feature by setting
" 'undolevels' to -1 and restore it.
let self.save_undolevels = &l:undolevels
let &l:undolevels = -1
elseif !s:Buffer.is_cmdwin()
" command line window doesn't support :wundo.
let self.undofile = tempname()
execute 'wundo!' self.undofile
else
let self.is_cmdwin = s:TRUE
endif
endfunction
function! s:undo_lock.restore() abort
if has_key(self, 'save_undolevels')
let &l:undolevels = self.save_undolevels
endif
if has_key(self, 'undofile') && filereadable(self.undofile)
silent execute 'rundo' self.undofile
call delete(self.undofile)
endif
if has_key(self, 'is_cmdwin')
" XXX: it breaks undo history. AFAIK, there are no way to save and restore
" undo history in commandline window.
call self.undobreak()
endif
endfunction
function! s:undo_lock.undobreak() abort
let old_undolevels = &l:undolevels
setlocal undolevels=-1
keepjumps call setline('.', getline('.'))
let &l:undolevels = old_undolevels
endfunction