comparison plugin/lawrencium.vim @ 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 e66df94ebceb
comparison
equal deleted inserted replaced
107:6846e12f8ec8 108:497f7a481599
44 let g:lawrencium_status_win_split_above = 0 44 let g:lawrencium_status_win_split_above = 0
45 endif 45 endif
46 46
47 if !exists('g:lawrencium_status_win_split_even') 47 if !exists('g:lawrencium_status_win_split_even')
48 let g:lawrencium_status_win_split_even = 0 48 let g:lawrencium_status_win_split_even = 0
49 endif
50
51 if !exists('g:lawrencium_record_start_in_working_buffer')
52 let g:lawrencium_record_start_in_working_buffer = 0
49 endif 53 endif
50 54
51 " }}} 55 " }}}
52 56
53 " Utility {{{ 57 " Utility {{{
2097 let l:repo = s:hg_repo() 2101 let l:repo = s:hg_repo()
2098 let l:hg_args = ['-s', '-l', a:log_file] 2102 let l:hg_args = ['-s', '-l', a:log_file]
2099 call l:repo.RunCommand('qref', l:hg_args) 2103 call l:repo.RunCommand('qref', l:hg_args)
2100 endfunction 2104 endfunction
2101 2105
2102
2103 call s:AddMainCommand("Hgqseries call s:HgQSeries()") 2106 call s:AddMainCommand("Hgqseries call s:HgQSeries()")
2107
2108 " }}}
2109
2110 " Hgrecord {{{
2111
2112 function! s:HgRecord(split) abort
2113 let l:repo = s:hg_repo()
2114 let l:orig_buf = s:buffer_obj()
2115 let l:tmp_path = l:orig_buf.GetName(':p') . '~record'
2116 let l:diff_id = localtime()
2117
2118 " Start diffing on the current file, enable some commands.
2119 call l:orig_buf.DefineCommand('Hgrecordabort', ':call s:HgRecord_Abort()')
2120 call l:orig_buf.DefineCommand('Hgrecordcommit', ':call s:HgRecord_Execute()')
2121 call s:HgDiff_DiffThis(l:diff_id)
2122 setlocal foldmethod=marker
2123
2124 " Split the window and open the parent revision in the right or bottom
2125 " window. Keep the current buffer in the left or top window... we're going
2126 " to 'move' those changes into the parent revision.
2127 let l:cmd = 'keepalt rightbelow split '
2128 if a:split == 1
2129 let l:cmd = 'keepalt rightbelow vsplit '
2130 endif
2131 let l:rev_path = l:repo.GetLawrenciumPath(expand('%'), 'rev', '')
2132 execute l:cmd . fnameescape(l:rev_path)
2133
2134 " This new buffer with the parent revision is set as a Lawrencium buffer.
2135 " Let's save it to an actual file and reopen it like that (somehow we
2136 " could probably do it with `:saveas` instead but we'd need to reset a
2137 " bunch of other buffer settings, and Vim weirdly creates another backup
2138 " buffer when you do that).
2139 execute 'keepalt write! ' . fnameescape(l:tmp_path)
2140 execute 'keepalt edit! ' . fnameescape(l:tmp_path)
2141 setlocal bufhidden=delete
2142 let b:mercurial_dir = l:repo.root_dir
2143 let b:lawrencium_record_for = l:orig_buf.GetName(':p')
2144 let b:lawrencium_record_other_nr = l:orig_buf.nr
2145 let b:lawrencium_record_commit_split = !a:split
2146 call setbufvar(l:orig_buf.nr, 'lawrencium_record_for', '%')
2147 call setbufvar(l:orig_buf.nr, 'lawrencium_record_other_nr', bufnr('%'))
2148
2149 " Hookup the commit and abort commands.
2150 let l:rec_buf = s:buffer_obj()
2151 call l:rec_buf.OnDelete('call s:HgRecord_Execute()')
2152 call l:rec_buf.DefineCommand('Hgrecordcommit', ':quit')
2153 call l:rec_buf.DefineCommand('Hgrecordabort', ':call s:HgRecord_Abort()')
2154 call s:DefineMainCommands()
2155
2156 " Make it the other part of the diff.
2157 call s:HgDiff_DiffThis(l:diff_id)
2158 setlocal foldmethod=marker
2159 call l:rec_buf.SetVar('&filetype', l:orig_buf.GetVar('&filetype'))
2160
2161 if g:lawrencium_record_start_in_working_buffer
2162 wincmd p
2163 endif
2164 endfunction
2165
2166 function! s:HgRecord_Execute() abort
2167 if exists('b:lawrencium_record_abort')
2168 " Abort flag is set, let's just cleanup.
2169 let l:buf_nr = b:lawrencium_record_for == '%' ? bufnr('%') :
2170 \b:lawrencium_record_other_nr
2171 call s:HgRecord_CleanUp(l:buf_nr)
2172 call s:error("abort: User requested aborting the record operation.")
2173 return
2174 endif
2175
2176 if !exists('b:lawrencium_record_for')
2177 call s:throw("This doesn't seem like a record buffer, something's wrong!")
2178 endif
2179 if b:lawrencium_record_for == '%'
2180 " Switch to the 'recording' buffer's window.
2181 let l:buf_obj = s:buffer_obj(b:lawrencium_record_other_nr)
2182 call l:buf_obj.MoveToFirstWindow()
2183 endif
2184
2185 " Setup the commit operation.
2186 let l:split = b:lawrencium_record_commit_split
2187 let l:working_bufnr = b:lawrencium_record_other_nr
2188 let l:working_path = fnameescape(b:lawrencium_record_for)
2189 let l:record_path = fnameescape(expand('%:p'))
2190 let l:callbacks = [
2191 \'call s:HgRecord_PostExecutePre('.l:working_bufnr.', "'.
2192 \escape(l:working_path, '\').'", "'.
2193 \escape(l:record_path, '\').'")',
2194 \'call s:HgRecord_PostExecutePost('.l:working_bufnr.', "'.
2195 \escape(l:working_path, '\').'")',
2196 \'call s:HgRecord_PostExecuteAbort('.l:working_bufnr.', "'.
2197 \escape(l:record_path, '\').'")'
2198 \]
2199 call s:trace("Starting commit flow with callbacks: ".string(l:callbacks))
2200 call s:HgCommit(0, l:split, l:callbacks, b:lawrencium_record_for)
2201 endfunction
2202
2203 function! s:HgRecord_PostExecutePre(working_bufnr, working_path, record_path) abort
2204 " Just before committing, we switch the original file with the record
2205 " file... we'll restore things in the post-callback below.
2206 " We also switch on 'autoread' temporarily on the working buffer so that
2207 " we don't have an annoying popup in gVim.
2208 if has('dialog_gui')
2209 call setbufvar(a:working_bufnr, '&autoread', 1)
2210 endif
2211 call s:trace("Backuping original file: ".a:working_path)
2212 silent call rename(a:working_path, a:working_path.'~working')
2213 call s:trace("Committing recorded changes using: ".a:record_path)
2214 silent call rename(a:record_path, a:working_path)
2215 sleep 200m
2216 endfunction
2217
2218 function! s:HgRecord_PostExecutePost(working_bufnr, working_path) abort
2219 " Recover the back-up file from underneath the buffer.
2220 call s:trace("Recovering original file: ".a:working_path)
2221 silent call rename(a:working_path.'~working', a:working_path)
2222
2223 " Clean up!
2224 call s:HgRecord_CleanUp(a:working_bufnr)
2225
2226 " Restore default 'autoread'.
2227 if has('dialog_gui')
2228 set autoread<
2229 endif
2230 endfunction
2231
2232 function! s:HgRecord_PostExecuteAbort(working_bufnr, record_path) abort
2233 call s:HgRecord_CleanUp(a:working_bufnr)
2234 call s:trace("Delete discarded record file: ".a:record_path)
2235 silent call delete(a:record_path)
2236 endfunction
2237
2238 function! s:HgRecord_Abort() abort
2239 if b:lawrencium_record_for == '%'
2240 " We're in the working directory buffer. Switch to the 'recording'
2241 " buffer and quit.
2242 let l:buf_obj = s:buffer_obj(b:lawrencium_record_other_nr)
2243 call l:buf_obj.MoveToFirstWindow()
2244 endif
2245 " We're now in the 'recording' buffer... set the abort flag and quit,
2246 " which will run the execution (it will early out and clean things up).
2247 let b:lawrencium_record_abort = 1
2248 quit!
2249 endfunction
2250
2251 function! s:HgRecord_CleanUp(buf_nr) abort
2252 " Get in the original buffer and clean the local commands/variables.
2253 let l:buf_obj = s:buffer_obj(a:buf_nr)
2254 call l:buf_obj.MoveToFirstWindow()
2255 if !exists('b:lawrencium_record_for') || b:lawrencium_record_for != '%'
2256 call s:throw("Cleaning up something else than the original buffer ".
2257 \"for a record operation. That's suspiciously incorrect! ".
2258 \"Aborting.")
2259 endif
2260 call l:buf_obj.DeleteCommand('Hgrecordabort')
2261 call l:buf_obj.DeleteCommand('Hgrecordcommit')
2262 unlet b:lawrencium_record_for
2263 unlet b:lawrencium_record_other_nr
2264 endfunction
2265
2266 call s:AddMainCommand("Hgrecord call s:HgRecord(0)")
2267 call s:AddMainCommand("Hgvrecord call s:HgRecord(1)")
2104 2268
2105 " }}} 2269 " }}}
2106 2270
2107 " Autoload Functions {{{ 2271 " Autoload Functions {{{
2108 2272