comparison plugin/lawrencium.vim @ 31:3a0f7bb6ea64

Hgstatus window improvements and bug fixes: - `addremove` command replaces `add`, and can run on a selection range. - Lawrencium commands are available (along with in the diff windows). - Default mappings are optional. - Updated documentation.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 25 Dec 2011 22:40:30 -0800
parents 0cdfdab43907
children 799c7b57e19a
comparison
equal deleted inserted replaced
29:1ce59d5aa5e9 31:3a0f7bb6ea64
20 let g:lawrencium_hg_executable = 'hg' 20 let g:lawrencium_hg_executable = 'hg'
21 endif 21 endif
22 22
23 if !exists('g:lawrencium_trace') 23 if !exists('g:lawrencium_trace')
24 let g:lawrencium_trace = 0 24 let g:lawrencium_trace = 0
25 endif
26
27 if !exists('g:lawrencium_define_mappings')
28 let g:lawrencium_define_mappings = 1
25 endif 29 endif
26 30
27 " }}} 31 " }}}
28 32
29 " Utility {{{ 33 " Utility {{{
136 return l:matches 140 return l:matches
137 endfunction 141 endfunction
138 142
139 " Runs a Mercurial command in the repo 143 " Runs a Mercurial command in the repo
140 function! s:HgRepo.RunCommand(command, ...) abort 144 function! s:HgRepo.RunCommand(command, ...) abort
145 " If there's only one argument, and it's a list, then use that as the
146 " argument list.
147 let l:arg_list = a:000
148 if a:0 == 1 && type(a:1) == type([])
149 let l:arg_list = a:1
150 endif
141 let l:hg_command = g:lawrencium_hg_executable . ' --repository ' . shellescape(s:stripslash(self.root_dir)) 151 let l:hg_command = g:lawrencium_hg_executable . ' --repository ' . shellescape(s:stripslash(self.root_dir))
142 let l:hg_command = l:hg_command . ' ' . a:command . ' ' . join(a:000, ' ') 152 let l:hg_command = l:hg_command . ' ' . a:command . ' ' . join(l:arg_list, ' ')
143 call s:trace("Running Mercurial command: " . l:hg_command) 153 call s:trace("Running Mercurial command: " . l:hg_command)
144 return system(l:hg_command) 154 return system(l:hg_command)
145 endfunction 155 endfunction
146 156
147 " Repo cache map 157 " Repo cache map
335 let l:status_lines = split(l:status_text, '\n') 345 let l:status_lines = split(l:status_text, '\n')
336 execute "setlocal previewheight=" . (len(l:status_lines) + 1) 346 execute "setlocal previewheight=" . (len(l:status_lines) + 1)
337 execute "pedit " . l:temp_file 347 execute "pedit " . l:temp_file
338 wincmd p 348 wincmd p
339 call append(0, l:status_lines) 349 call append(0, l:status_lines)
350 call cursor(1, 1)
340 " Make it a nice size. 351 " Make it a nice size.
341 execute "setlocal previewheight=" . l:preview_height 352 execute "setlocal previewheight=" . l:preview_height
342 " Make sure it's deleted when we exit the window. 353 " Make sure it's deleted when we exit the window.
343 setlocal bufhidden=delete 354 setlocal bufhidden=delete
344 355
345 " Setup the buffer correctly: readonly, and with the correct repo linked 356 " Setup the buffer correctly: readonly, and with the correct repo linked
346 " to it. 357 " to it.
347 let b:mercurial_dir = l:repo.root_dir 358 let b:mercurial_dir = l:repo.root_dir
348 setlocal buftype=nofile
349 setlocal nomodified 359 setlocal nomodified
350 setlocal nomodifiable 360 setlocal nomodifiable
351 setlocal readonly 361 setlocal readonly
362 setlocal buftype=nofile
352 setlocal syntax=hgstatus 363 setlocal syntax=hgstatus
353 364
365 " Make commands available.
366 call s:DefineMainCommands()
367
368 " Add some nice commands.
369 command! -buffer Hgstatusedit :call s:HgStatus_FileEdit()
370 command! -buffer -range Hgstatusaddremove :call s:HgStatus_AddRemove(<line1>, <line2>)
371 command! -buffer Hgstatusdiff :call s:HgStatus_Diff(0)
372 command! -buffer Hgstatusvdiff :call s:HgStatus_Diff(1)
373 command! -buffer Hgstatusrefresh :call s:HgStatus_Refresh()
374
354 " Add some handy mappings. 375 " Add some handy mappings.
355 nnoremap <buffer> <silent> <C-N> :call search('^[MARC\!\?I ]\s.', 'We')<cr> 376 if g:lawrencium_define_mappings
356 nnoremap <buffer> <silent> <C-P> :call search('^[MARC\!\?I ]\s.','Wbe')<cr> 377 nnoremap <buffer> <silent> <cr> :Hgstatusedit<cr>
357 nnoremap <buffer> <silent> <cr> :call <SID>HgStatus_FileEdit()<cr> 378 nnoremap <buffer> <silent> <C-N> :call search('^[MARC\!\?I ]\s.', 'We')<cr>
358 nnoremap <buffer> <silent> <C-D> :call <SID>HgStatus_FileDiff(0)<cr> 379 nnoremap <buffer> <silent> <C-P> :call search('^[MARC\!\?I ]\s.', 'Wbe')<cr>
359 nnoremap <buffer> <silent> <C-V> :call <SID>HgStatus_FileDiff(1)<cr> 380 nnoremap <buffer> <silent> <C-D> :Hgstatusdiff<cr>
360 nnoremap <buffer> <silent> <C-A> :call <SID>HgStatus_FileAdd()<cr> 381 nnoremap <buffer> <silent> <C-V> :Hgstatusvdiff<cr>
361 nnoremap <buffer> <silent> <C-R> :call <SID>HgStatus_Refresh()<cr> 382 nnoremap <buffer> <silent> <C-A> :Hgstatusaddremove<cr>
362 nnoremap <buffer> <silent> q :bdelete<cr> 383 nnoremap <buffer> <silent> <C-R> :Hgstatusrefresh<cr>
384 nnoremap <buffer> <silent> q :bdelete!<cr>
385 endif
363 386
364 " Make sure the file is deleted with the buffer. 387 " Make sure the file is deleted with the buffer.
365 autocmd BufDelete <buffer> call s:HgStatus_CleanUp(expand('<afile>:p')) 388 autocmd BufDelete <buffer> call s:HgStatus_CleanUp(expand('<afile>:p'))
366 endfunction 389 endfunction
367 390
387 edit 410 edit
388 endfunction 411 endfunction
389 412
390 function! s:HgStatus_FileEdit() abort 413 function! s:HgStatus_FileEdit() abort
391 " Get the path of the file the cursor is on. 414 " Get the path of the file the cursor is on.
392 let l:filename = s:HgStatus_GetSelectedPath() 415 let l:filename = s:HgStatus_GetSelectedFile()
393 416
394 " If the file is already open in a window, jump to that window. 417 " If the file is already open in a window, jump to that window.
395 " Otherwise, jump to the previous window and open it there. 418 " Otherwise, jump to the previous window and open it there.
396 for nr in range(1, winnr('$')) 419 for nr in range(1, winnr('$'))
397 let l:br = winbufnr(nr) 420 let l:br = winbufnr(nr)
403 endfor 426 endfor
404 wincmd p 427 wincmd p
405 execute 'edit ' . l:filename 428 execute 'edit ' . l:filename
406 endfunction 429 endfunction
407 430
408 function! s:HgStatus_FileAdd() abort 431 function! s:HgStatus_AddRemove(linestart, lineend) abort
409 " Get the path of the file the cursor is on, and its status. 432 " Get the selected filenames.
410 let l:filename = s:HgStatus_GetSelectedPath() 433 let l:filenames = s:HgStatus_GetSelectedFiles(a:linestart, a:lineend, ['!', '?'])
411 let l:status = s:HgStatus_GetSelectedStatus() 434 if len(l:filenames) == 0
412 if l:status !=# '?' 435 call s:error("No files to add or remove in selection or current line.")
413 call s:error("Not an untracked file: " . l:filename) 436 endif
414 endif 437
415 438 " Run `addremove` on those paths.
416 " Add the file.
417 let l:repo = s:hg_repo() 439 let l:repo = s:hg_repo()
418 call l:repo.RunCommand('add', l:filename) 440 call l:repo.RunCommand('addremove', l:filenames)
419 441
420 " Refresh the status window. 442 " Refresh the status window.
421 call s:HgStatus_Refresh() 443 call s:HgStatus_Refresh()
422 endfunction 444 endfunction
423 445
424 function! s:HgStatus_FileDiff(vertical) abort 446 function! s:HgStatus_Diff(vertical) abort
425 " Open the file and run `Hgdiff` on it. 447 " Open the file and run `Hgdiff` on it.
426 call s:HgStatus_FileEdit() 448 call s:HgStatus_FileEdit()
427 call s:HgDiff('%:p', a:vertical) 449 call s:HgDiff('%:p', a:vertical)
428 endfunction 450 endfunction
429 451
430 function! s:HgStatus_GetSelectedPath() abort 452 function! s:HgStatus_GetSelectedFile() abort
453 let l:filenames = s:HgStatus_GetSelectedFiles()
454 return l:filenames[0]
455 endfunction
456
457 function! s:HgStatus_GetSelectedFiles(...) abort
458 if a:0 >= 2
459 let l:lines = getline(a:1, a:2)
460 else
461 let l:lines = []
462 call add(l:lines, getline('.'))
463 endif
464 let l:filenames = []
431 let l:repo = s:hg_repo() 465 let l:repo = s:hg_repo()
432 let l:line = getline('.') 466 for line in l:lines
433 " Yay, awesome, Vim's regex syntax is fucked up like shit, especially for 467 if a:0 >= 3
434 " look-aheads and look-behinds. See for yourself: 468 let l:status = s:HgStatus_GetFileStatus(line)
435 let l:filename = matchstr(l:line, '\v(^[MARC\!\?I ]\s)@<=.*') 469 if index(a:3, l:status) < 0
436 let l:filename = l:repo.GetFullPath(l:filename) 470 continue
437 return l:filename 471 endif
438 endfunction 472 endif
439 473 " Yay, awesome, Vim's regex syntax is fucked up like shit, especially for
440 function! s:HgStatus_GetSelectedStatus() abort 474 " look-aheads and look-behinds. See for yourself:
441 let l:line = getline('.') 475 let l:filename = matchstr(l:line, '\v(^[MARC\!\?I ]\s)@<=.*')
476 let l:filename = l:repo.GetFullPath(l:filename)
477 call add(l:filenames, l:filename)
478 endfor
479 return l:filenames
480 endfunction
481
482 function! s:HgStatus_GetFileStatus(...) abort
483 let l:line = a:0 ? a:1 : getline('.')
442 return matchstr(l:line, '\v^[MARC\!\?I ]') 484 return matchstr(l:line, '\v^[MARC\!\?I ]')
443 endfunction 485 endfunction
444 486
445 call s:AddMainCommand("Hgstatus :call s:HgStatus()") 487 call s:AddMainCommand("Hgstatus :call s:HgStatus()")
446 488
510 call s:HgDiff_DiffThis() 552 call s:HgDiff_DiffThis()
511 " Remember the repo it belongs to. 553 " Remember the repo it belongs to.
512 let b:mercurial_dir = l:repo.root_dir 554 let b:mercurial_dir = l:repo.root_dir
513 " Make sure it's deleted when we move away from it. 555 " Make sure it's deleted when we move away from it.
514 setlocal bufhidden=delete 556 setlocal bufhidden=delete
557 " Make commands available.
558 call s:DefineMainCommands()
515 endif 559 endif
516 560
517 " Get the second file and open it too. 561 " Get the second file and open it too.
518 let l:diffsplit = 'diffsplit' 562 let l:diffsplit = 'diffsplit'
519 if a:vertical 563 if a:vertical
527 execute l:diffsplit . ' ' . fnameescape(l:temp_file) 571 execute l:diffsplit . ' ' . fnameescape(l:temp_file)
528 " Remember the repo it belongs to. 572 " Remember the repo it belongs to.
529 let b:mercurial_dir = l:repo.root_dir 573 let b:mercurial_dir = l:repo.root_dir
530 " Make sure it's deleted when we move away from it. 574 " Make sure it's deleted when we move away from it.
531 setlocal bufhidden=delete 575 setlocal bufhidden=delete
576 " Make commands available.
577 call s:DefineMainCommands()
532 endif 578 endif
533 endfunction 579 endfunction
534 580
535 function! s:HgDiff_DiffThis() abort 581 function! s:HgDiff_DiffThis() abort
536 " Store some commands to run when we exit diff mode. 582 " Store some commands to run when we exit diff mode.
631 if a:bang 677 if a:bang
632 autocmd BufDelete <buffer> call s:HgCommit_Execute(expand('<afile>:p'), 0) 678 autocmd BufDelete <buffer> call s:HgCommit_Execute(expand('<afile>:p'), 0)
633 else 679 else
634 autocmd BufDelete <buffer> call s:HgCommit_Execute(expand('<afile>:p'), 1) 680 autocmd BufDelete <buffer> call s:HgCommit_Execute(expand('<afile>:p'), 1)
635 endif 681 endif
682 " Make commands available.
683 call s:DefineMainCommands()
636 endfunction 684 endfunction
637 685
638 let s:hg_status_messages = { 686 let s:hg_status_messages = {
639 \'M': 'modified', 687 \'M': 'modified',
640 \'A': 'added', 688 \'A': 'added',