Mercurial > vim-lawrencium
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', |