Mercurial > vim-lawrencium
changeset 108:497f7a481599
Added new `Hgrecord` command.
(actually, the last few commits were submitted with it ^_^)
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 15 Aug 2014 17:12:49 -0700 |
parents | 6846e12f8ec8 |
children | 8ec747b13dc1 |
files | plugin/lawrencium.vim |
diffstat | 1 files changed, 165 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/plugin/lawrencium.vim Fri Aug 15 17:11:28 2014 -0700 +++ b/plugin/lawrencium.vim Fri Aug 15 17:12:49 2014 -0700 @@ -48,6 +48,10 @@ let g:lawrencium_status_win_split_even = 0 endif +if !exists('g:lawrencium_record_start_in_working_buffer') + let g:lawrencium_record_start_in_working_buffer = 0 +endif + " }}} " Utility {{{ @@ -2099,8 +2103,168 @@ call l:repo.RunCommand('qref', l:hg_args) endfunction +call s:AddMainCommand("Hgqseries call s:HgQSeries()") -call s:AddMainCommand("Hgqseries call s:HgQSeries()") +" }}} + +" Hgrecord {{{ + +function! s:HgRecord(split) abort + let l:repo = s:hg_repo() + let l:orig_buf = s:buffer_obj() + let l:tmp_path = l:orig_buf.GetName(':p') . '~record' + let l:diff_id = localtime() + + " Start diffing on the current file, enable some commands. + call l:orig_buf.DefineCommand('Hgrecordabort', ':call s:HgRecord_Abort()') + call l:orig_buf.DefineCommand('Hgrecordcommit', ':call s:HgRecord_Execute()') + call s:HgDiff_DiffThis(l:diff_id) + setlocal foldmethod=marker + + " Split the window and open the parent revision in the right or bottom + " window. Keep the current buffer in the left or top window... we're going + " to 'move' those changes into the parent revision. + let l:cmd = 'keepalt rightbelow split ' + if a:split == 1 + let l:cmd = 'keepalt rightbelow vsplit ' + endif + let l:rev_path = l:repo.GetLawrenciumPath(expand('%'), 'rev', '') + execute l:cmd . fnameescape(l:rev_path) + + " This new buffer with the parent revision is set as a Lawrencium buffer. + " Let's save it to an actual file and reopen it like that (somehow we + " could probably do it with `:saveas` instead but we'd need to reset a + " bunch of other buffer settings, and Vim weirdly creates another backup + " buffer when you do that). + execute 'keepalt write! ' . fnameescape(l:tmp_path) + execute 'keepalt edit! ' . fnameescape(l:tmp_path) + setlocal bufhidden=delete + let b:mercurial_dir = l:repo.root_dir + let b:lawrencium_record_for = l:orig_buf.GetName(':p') + let b:lawrencium_record_other_nr = l:orig_buf.nr + let b:lawrencium_record_commit_split = !a:split + call setbufvar(l:orig_buf.nr, 'lawrencium_record_for', '%') + call setbufvar(l:orig_buf.nr, 'lawrencium_record_other_nr', bufnr('%')) + + " Hookup the commit and abort commands. + let l:rec_buf = s:buffer_obj() + call l:rec_buf.OnDelete('call s:HgRecord_Execute()') + call l:rec_buf.DefineCommand('Hgrecordcommit', ':quit') + call l:rec_buf.DefineCommand('Hgrecordabort', ':call s:HgRecord_Abort()') + call s:DefineMainCommands() + + " Make it the other part of the diff. + call s:HgDiff_DiffThis(l:diff_id) + setlocal foldmethod=marker + call l:rec_buf.SetVar('&filetype', l:orig_buf.GetVar('&filetype')) + + if g:lawrencium_record_start_in_working_buffer + wincmd p + endif +endfunction + +function! s:HgRecord_Execute() abort + if exists('b:lawrencium_record_abort') + " Abort flag is set, let's just cleanup. + let l:buf_nr = b:lawrencium_record_for == '%' ? bufnr('%') : + \b:lawrencium_record_other_nr + call s:HgRecord_CleanUp(l:buf_nr) + call s:error("abort: User requested aborting the record operation.") + return + endif + + if !exists('b:lawrencium_record_for') + call s:throw("This doesn't seem like a record buffer, something's wrong!") + endif + if b:lawrencium_record_for == '%' + " Switch to the 'recording' buffer's window. + let l:buf_obj = s:buffer_obj(b:lawrencium_record_other_nr) + call l:buf_obj.MoveToFirstWindow() + endif + + " Setup the commit operation. + let l:split = b:lawrencium_record_commit_split + let l:working_bufnr = b:lawrencium_record_other_nr + let l:working_path = fnameescape(b:lawrencium_record_for) + let l:record_path = fnameescape(expand('%:p')) + let l:callbacks = [ + \'call s:HgRecord_PostExecutePre('.l:working_bufnr.', "'. + \escape(l:working_path, '\').'", "'. + \escape(l:record_path, '\').'")', + \'call s:HgRecord_PostExecutePost('.l:working_bufnr.', "'. + \escape(l:working_path, '\').'")', + \'call s:HgRecord_PostExecuteAbort('.l:working_bufnr.', "'. + \escape(l:record_path, '\').'")' + \] + call s:trace("Starting commit flow with callbacks: ".string(l:callbacks)) + call s:HgCommit(0, l:split, l:callbacks, b:lawrencium_record_for) +endfunction + +function! s:HgRecord_PostExecutePre(working_bufnr, working_path, record_path) abort + " Just before committing, we switch the original file with the record + " file... we'll restore things in the post-callback below. + " We also switch on 'autoread' temporarily on the working buffer so that + " we don't have an annoying popup in gVim. + if has('dialog_gui') + call setbufvar(a:working_bufnr, '&autoread', 1) + endif + call s:trace("Backuping original file: ".a:working_path) + silent call rename(a:working_path, a:working_path.'~working') + call s:trace("Committing recorded changes using: ".a:record_path) + silent call rename(a:record_path, a:working_path) + sleep 200m +endfunction + +function! s:HgRecord_PostExecutePost(working_bufnr, working_path) abort + " Recover the back-up file from underneath the buffer. + call s:trace("Recovering original file: ".a:working_path) + silent call rename(a:working_path.'~working', a:working_path) + + " Clean up! + call s:HgRecord_CleanUp(a:working_bufnr) + + " Restore default 'autoread'. + if has('dialog_gui') + set autoread< + endif +endfunction + +function! s:HgRecord_PostExecuteAbort(working_bufnr, record_path) abort + call s:HgRecord_CleanUp(a:working_bufnr) + call s:trace("Delete discarded record file: ".a:record_path) + silent call delete(a:record_path) +endfunction + +function! s:HgRecord_Abort() abort + if b:lawrencium_record_for == '%' + " We're in the working directory buffer. Switch to the 'recording' + " buffer and quit. + let l:buf_obj = s:buffer_obj(b:lawrencium_record_other_nr) + call l:buf_obj.MoveToFirstWindow() + endif + " We're now in the 'recording' buffer... set the abort flag and quit, + " which will run the execution (it will early out and clean things up). + let b:lawrencium_record_abort = 1 + quit! +endfunction + +function! s:HgRecord_CleanUp(buf_nr) abort + " Get in the original buffer and clean the local commands/variables. + let l:buf_obj = s:buffer_obj(a:buf_nr) + call l:buf_obj.MoveToFirstWindow() + if !exists('b:lawrencium_record_for') || b:lawrencium_record_for != '%' + call s:throw("Cleaning up something else than the original buffer ". + \"for a record operation. That's suspiciously incorrect! ". + \"Aborting.") + endif + call l:buf_obj.DeleteCommand('Hgrecordabort') + call l:buf_obj.DeleteCommand('Hgrecordcommit') + unlet b:lawrencium_record_for + unlet b:lawrencium_record_other_nr +endfunction + +call s:AddMainCommand("Hgrecord call s:HgRecord(0)") +call s:AddMainCommand("Hgvrecord call s:HgRecord(1)") " }}}