Mercurial > vim-lawrencium
comparison plugin/lawrencium.vim @ 71:1fbba48019b5
MQ support:
- Added `Hgqseries` command to navigate MQ series.
- Ability to go to, rename, and edit the message of a patch.
- Wrote documentation.
Fixed a bug with the `Hgstatus` being `readonly`.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 16 Feb 2014 16:00:16 -0800 |
parents | 16e873b2a4a8 |
children | a987094d5ae6 |
comparison
equal
deleted
inserted
replaced
70:16e873b2a4a8 | 71:1fbba48019b5 |
---|---|
241 call s:trace("Returning to window " . l:cur_winnr) | 241 call s:trace("Returning to window " . l:cur_winnr) |
242 execute l:cur_winnr . "wincmd w" | 242 execute l:cur_winnr . "wincmd w" |
243 endif | 243 endif |
244 endfunction | 244 endfunction |
245 | 245 |
246 " Clean up all the 'HG:' lines from a commit message, and see if there's | |
247 " any message left (Mercurial does this automatically, usually, but | |
248 " apparently not when you feed it a log file...). | |
249 function! s:clean_commit_file(log_file) abort | |
250 let l:lines = readfile(a:log_file) | |
251 call filter(l:lines, "v:val !~# '\\v^HG:'") | |
252 if len(filter(copy(l:lines), "v:val !~# '\\v^\\s*$'")) == 0 | |
253 return 0 | |
254 endif | |
255 call writefile(l:lines, a:log_file) | |
256 return 1 | |
257 endfunction | |
258 | |
246 " }}} | 259 " }}} |
247 | 260 |
248 " Mercurial Repository Object {{{ | 261 " Mercurial Repository Object {{{ |
249 | 262 |
250 " Let's define a Mercurial repo 'class' using prototype-based object-oriented | 263 " Let's define a Mercurial repo 'class' using prototype-based object-oriented |
546 if a:path_parts['path'] == '' | 559 if a:path_parts['path'] == '' |
547 call a:repo.ReadCommandOutput('status') | 560 call a:repo.ReadCommandOutput('status') |
548 else | 561 else |
549 call a:repo.ReadCommandOutput('status', a:full_path) | 562 call a:repo.ReadCommandOutput('status', a:full_path) |
550 endif | 563 endif |
564 setlocal nomodified | |
551 setlocal filetype=hgstatus | 565 setlocal filetype=hgstatus |
566 setlocal bufhidden=delete | |
567 setlocal buftype=nofile | |
552 endfunction | 568 endfunction |
553 | 569 |
554 " Log (`hg log`) | 570 " Log (`hg log`) |
555 let s:log_style_file = expand("<sfile>:h:h") . "/resources/hg_log.style" | 571 let s:log_style_file = expand("<sfile>:h:h") . "/resources/hg_log.style" |
556 | 572 |
593 " Annotate file | 609 " Annotate file |
594 function! s:read_lawrencium_annotate(repo, path_parts, full_path) abort | 610 function! s:read_lawrencium_annotate(repo, path_parts, full_path) abort |
595 call a:repo.ReadCommandOutput('annotate', '-c', '-n', '-u', '-d', '-q', a:full_path) | 611 call a:repo.ReadCommandOutput('annotate', '-c', '-n', '-u', '-d', '-q', a:full_path) |
596 endfunction | 612 endfunction |
597 | 613 |
614 " MQ series | |
615 function! s:read_lawrencium_qseries(repo, path_parts, full_path) abort | |
616 let l:names = split(a:repo.RunCommand('qseries'), '\n') | |
617 let l:head = split(a:repo.RunCommand('qapplied', '-s'), '\n') | |
618 let l:tail = split(a:repo.RunCommand('qunapplied', '-s'), '\n') | |
619 | |
620 let l:idx = 0 | |
621 let l:curbuffer = bufname('%') | |
622 for line in l:head | |
623 call setbufvar(l:curbuffer, 'lawrencium_patchname_' . (l:idx + 1), l:names[l:idx]) | |
624 call append(l:idx, "*" . line) | |
625 let l:idx = l:idx + 1 | |
626 endfor | |
627 for line in l:tail | |
628 call setbufvar(l:curbuffer, 'lawrencium_patchname_' . (l:idx + 1), l:names[l:idx]) | |
629 call append(l:idx, line) | |
630 let l:idx = l:idx + 1 | |
631 endfor | |
632 set filetype=hgqseries | |
633 endfunction | |
634 | |
598 " Generic read | 635 " Generic read |
599 let s:lawrencium_file_readers = { | 636 let s:lawrencium_file_readers = { |
600 \'rev': function('s:read_lawrencium_rev'), | 637 \'rev': function('s:read_lawrencium_rev'), |
601 \'log': function('s:read_lawrencium_log'), | 638 \'log': function('s:read_lawrencium_log'), |
602 \'diff': function('s:read_lawrencium_diff'), | 639 \'diff': function('s:read_lawrencium_diff'), |
603 \'status': function('s:read_lawrencium_status'), | 640 \'status': function('s:read_lawrencium_status'), |
604 \'annotate': function('s:read_lawrencium_annotate') | 641 \'annotate': function('s:read_lawrencium_annotate'), |
642 \'qseries': function('s:read_lawrencium_qseries') | |
643 \} | |
644 let s:lawrencium_file_customoptions = { | |
645 \'status': 1 | |
605 \} | 646 \} |
606 | 647 |
607 function! s:ReadLawrenciumFile(path) abort | 648 function! s:ReadLawrenciumFile(path) abort |
608 call s:trace("Reading Lawrencium file: " . a:path) | 649 call s:trace("Reading Lawrencium file: " . a:path) |
609 let l:path_parts = s:parse_lawrencium_path(a:path) | 650 let l:path_parts = s:parse_lawrencium_path(a:path) |
619 let l:full_path = l:repo.root_dir . l:path_parts['path'] | 660 let l:full_path = l:repo.root_dir . l:path_parts['path'] |
620 let LawrenciumFileReader = s:lawrencium_file_readers[l:path_parts['action']] | 661 let LawrenciumFileReader = s:lawrencium_file_readers[l:path_parts['action']] |
621 call LawrenciumFileReader(l:repo, l:path_parts, l:full_path) | 662 call LawrenciumFileReader(l:repo, l:path_parts, l:full_path) |
622 | 663 |
623 " Setup the new buffer. | 664 " Setup the new buffer. |
624 setlocal readonly | 665 if !has_key(s:lawrencium_file_customoptions, l:path_parts['action']) |
625 setlocal nomodified | 666 setlocal readonly |
626 setlocal bufhidden=delete | 667 setlocal nomodified |
627 setlocal buftype=nofile | 668 setlocal bufhidden=delete |
669 setlocal buftype=nofile | |
670 endif | |
628 goto | 671 goto |
629 | 672 |
630 " Remember the repo it belongs to and make | 673 " Remember the repo it belongs to and make |
631 " the Lawrencium commands available. | 674 " the Lawrencium commands available. |
632 let b:mercurial_dir = l:repo.root_dir | 675 let b:mercurial_dir = l:repo.root_dir |
1288 return | 1331 return |
1289 endif | 1332 endif |
1290 | 1333 |
1291 call s:trace("Committing with log file: " . a:log_file) | 1334 call s:trace("Committing with log file: " . a:log_file) |
1292 | 1335 |
1293 " Clean up all the 'HG:' lines from the commit message, and see if there's | 1336 " Clean all the 'HG: ' lines. |
1294 " any message left (Mercurial does this automatically, usually, but | 1337 let l:is_valid = s:clean_commit_file(a:log_file) |
1295 " apparently not when you feed it a log file...). | 1338 if !l:is_valid |
1296 let l:lines = readfile(a:log_file) | |
1297 call filter(l:lines, "v:val !~# '\\v^HG:'") | |
1298 if len(filter(copy(l:lines), "v:val !~# '\\v^\\s*$'")) == 0 | |
1299 call s:error("abort: Empty commit message") | 1339 call s:error("abort: Empty commit message") |
1300 return | 1340 return |
1301 endif | 1341 endif |
1302 call writefile(l:lines, a:log_file) | |
1303 | 1342 |
1304 " Get the repo and commit with the given message. | 1343 " Get the repo and commit with the given message. |
1305 let l:repo = s:hg_repo() | 1344 let l:repo = s:hg_repo() |
1306 let l:hg_args = ['-l', a:log_file] | 1345 let l:hg_args = ['-l', a:log_file] |
1307 call extend(l:hg_args, b:lawrencium_commit_files) | 1346 call extend(l:hg_args, b:lawrencium_commit_files) |
1559 | 1598 |
1560 call s:AddMainCommand("Hgannotate :call s:HgAnnotate()") | 1599 call s:AddMainCommand("Hgannotate :call s:HgAnnotate()") |
1561 | 1600 |
1562 " }}} | 1601 " }}} |
1563 | 1602 |
1603 " Hgqseries {{{ | |
1604 | |
1605 function! s:HgQSeries() abort | |
1606 " Open the MQ series in the preview window and jump to it. | |
1607 let l:repo = s:hg_repo() | |
1608 let l:path = l:repo.GetLawrenciumPath('', 'qseries', '') | |
1609 execute 'pedit ' . l:path | |
1610 wincmd P | |
1611 | |
1612 " Make the series buffer a Lawrencium buffer. | |
1613 let b:mercurial_dir = l:repo.root_dir | |
1614 call s:DefineMainCommands() | |
1615 | |
1616 " Add some commands and mappings. | |
1617 command! -buffer Hgqseriesgoto :call s:HgQSeries_Goto() | |
1618 command! -buffer Hgqserieseditmessage :call s:HgQSeries_EditMessage() | |
1619 command! -buffer -nargs=+ Hgqseriesrename :call s:HgQSeries_Rename(<f-args>) | |
1620 if g:lawrencium_define_mappings | |
1621 nnoremap <buffer> <silent> <C-g> :Hgqseriesgoto<cr> | |
1622 nnoremap <buffer> <silent> <C-e> :Hgqserieseditmessage<cr> | |
1623 nnoremap <buffer> <silent> q :bdelete!<cr> | |
1624 endif | |
1625 endfunction | |
1626 | |
1627 function! s:HgQSeries_GetCurrentPatchName() abort | |
1628 let l:pos = getpos('.') | |
1629 return getbufvar('%', 'lawrencium_patchname_' . l:pos[1]) | |
1630 endfunction | |
1631 | |
1632 function! s:HgQSeries_Goto() abort | |
1633 let l:repo = s:hg_repo() | |
1634 let l:patchname = HgQSeries_GetCurrentPatchName() | |
1635 if len(l:patchname) == 0 | |
1636 call s:error("No patch to go to here.") | |
1637 return | |
1638 endif | |
1639 call l:repo.RunCommand('qgoto', l:patchname) | |
1640 edit | |
1641 endfunction | |
1642 | |
1643 function! s:HgQSeries_Rename(...) abort | |
1644 let l:repo = s:hg_repo() | |
1645 let l:current_name = HgQSeries_GetCurrentPatchName() | |
1646 if len(l:current_name) == 0 | |
1647 call s:error("No patch to rename here.") | |
1648 return | |
1649 endif | |
1650 let l:new_name = '"' . join(a:000, ' ') . '"' | |
1651 call l:repo.RunCommand('qrename', l:current_name, l:new_name) | |
1652 edit | |
1653 endfunction | |
1654 | |
1655 function! s:HgQSeries_EditMessage() abort | |
1656 let l:repo = s:hg_repo() | |
1657 let l:patchname = getbufvar('%', 'lawrencium_patchname_1') | |
1658 if len(l:patchname) == 0 | |
1659 call s:error("No patch to edit here.") | |
1660 return | |
1661 endif | |
1662 let l:current = split(l:repo.RunCommand('qheader', l:patchname), '\n') | |
1663 | |
1664 " Open a temp file to write the commit message. | |
1665 let l:temp_file = s:tempname('hg-qrefedit-', '.txt') | |
1666 split | |
1667 execute 'edit ' . l:temp_file | |
1668 call append(0, 'HG: Enter the new commit message for patch "' . l:patchname . '" here.\n') | |
1669 call append(0, '') | |
1670 call append(0, l:current) | |
1671 call cursor(1, 1) | |
1672 | |
1673 " Make it a temp buffer that will actually change the commit message | |
1674 " when it is saved and closed. | |
1675 let b:mercurial_dir = l:repo.root_dir | |
1676 let b:lawrencium_patchname = l:patchname | |
1677 setlocal bufhidden=delete | |
1678 setlocal filetype=hgcommit | |
1679 autocmd BufDelete <buffer> call s:HgQSeries_EditMessage_Execute(expand('<afile>:p')) | |
1680 | |
1681 call s:DefineMainCommands() | |
1682 endfunction | |
1683 | |
1684 function! s:HgQSeries_EditMessage_Execute(log_file) abort | |
1685 if !filereadable(a:log_file) | |
1686 call s:error("abort: Commit message not saved") | |
1687 return | |
1688 endif | |
1689 | |
1690 " Clean all the 'HG:' lines. | |
1691 let l:is_valid = s:clean_commit_file(a:log_file) | |
1692 if !l:is_valid | |
1693 call s:error("abort: Empty commit message") | |
1694 return | |
1695 endif | |
1696 | |
1697 " Get the repo and edit the given patch. | |
1698 let l:repo = s:hg_repo() | |
1699 let l:hg_args = ['-s', '-l', a:log_file] | |
1700 call l:repo.RunCommand('qref', l:hg_args) | |
1701 endfunction | |
1702 | |
1703 | |
1704 call s:AddMainCommand("Hgqseries call s:HgQSeries()") | |
1705 | |
1706 " }}} | |
1707 | |
1564 " Autoload Functions {{{ | 1708 " Autoload Functions {{{ |
1565 | 1709 |
1566 " Prints a summary of the current repo (if any) that's appropriate for | 1710 " Prints a summary of the current repo (if any) that's appropriate for |
1567 " displaying on the status line. | 1711 " displaying on the status line. |
1568 function! lawrencium#statusline(...) | 1712 function! lawrencium#statusline(...) |