Mercurial > vim-lawrencium
diff 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 |
line wrap: on
line diff
--- a/plugin/lawrencium.vim Sat Nov 09 13:20:17 2013 -0800 +++ b/plugin/lawrencium.vim Sun Feb 16 16:00:16 2014 -0800 @@ -243,6 +243,19 @@ endif endfunction +" Clean up all the 'HG:' lines from a commit message, and see if there's +" any message left (Mercurial does this automatically, usually, but +" apparently not when you feed it a log file...). +function! s:clean_commit_file(log_file) abort + let l:lines = readfile(a:log_file) + call filter(l:lines, "v:val !~# '\\v^HG:'") + if len(filter(copy(l:lines), "v:val !~# '\\v^\\s*$'")) == 0 + return 0 + endif + call writefile(l:lines, a:log_file) + return 1 +endfunction + " }}} " Mercurial Repository Object {{{ @@ -548,7 +561,10 @@ else call a:repo.ReadCommandOutput('status', a:full_path) endif + setlocal nomodified setlocal filetype=hgstatus + setlocal bufhidden=delete + setlocal buftype=nofile endfunction " Log (`hg log`) @@ -595,13 +611,38 @@ call a:repo.ReadCommandOutput('annotate', '-c', '-n', '-u', '-d', '-q', a:full_path) endfunction +" MQ series +function! s:read_lawrencium_qseries(repo, path_parts, full_path) abort + let l:names = split(a:repo.RunCommand('qseries'), '\n') + let l:head = split(a:repo.RunCommand('qapplied', '-s'), '\n') + let l:tail = split(a:repo.RunCommand('qunapplied', '-s'), '\n') + + let l:idx = 0 + let l:curbuffer = bufname('%') + for line in l:head + call setbufvar(l:curbuffer, 'lawrencium_patchname_' . (l:idx + 1), l:names[l:idx]) + call append(l:idx, "*" . line) + let l:idx = l:idx + 1 + endfor + for line in l:tail + call setbufvar(l:curbuffer, 'lawrencium_patchname_' . (l:idx + 1), l:names[l:idx]) + call append(l:idx, line) + let l:idx = l:idx + 1 + endfor + set filetype=hgqseries +endfunction + " Generic read let s:lawrencium_file_readers = { \'rev': function('s:read_lawrencium_rev'), \'log': function('s:read_lawrencium_log'), \'diff': function('s:read_lawrencium_diff'), \'status': function('s:read_lawrencium_status'), - \'annotate': function('s:read_lawrencium_annotate') + \'annotate': function('s:read_lawrencium_annotate'), + \'qseries': function('s:read_lawrencium_qseries') + \} +let s:lawrencium_file_customoptions = { + \'status': 1 \} function! s:ReadLawrenciumFile(path) abort @@ -621,10 +662,12 @@ call LawrenciumFileReader(l:repo, l:path_parts, l:full_path) " Setup the new buffer. - setlocal readonly - setlocal nomodified - setlocal bufhidden=delete - setlocal buftype=nofile + if !has_key(s:lawrencium_file_customoptions, l:path_parts['action']) + setlocal readonly + setlocal nomodified + setlocal bufhidden=delete + setlocal buftype=nofile + endif goto " Remember the repo it belongs to and make @@ -1290,16 +1333,12 @@ call s:trace("Committing with log file: " . a:log_file) - " Clean up all the 'HG:' lines from the commit message, and see if there's - " any message left (Mercurial does this automatically, usually, but - " apparently not when you feed it a log file...). - let l:lines = readfile(a:log_file) - call filter(l:lines, "v:val !~# '\\v^HG:'") - if len(filter(copy(l:lines), "v:val !~# '\\v^\\s*$'")) == 0 + " Clean all the 'HG: ' lines. + let l:is_valid = s:clean_commit_file(a:log_file) + if !l:is_valid call s:error("abort: Empty commit message") return endif - call writefile(l:lines, a:log_file) " Get the repo and commit with the given message. let l:repo = s:hg_repo() @@ -1561,6 +1600,111 @@ " }}} +" Hgqseries {{{ + +function! s:HgQSeries() abort + " Open the MQ series in the preview window and jump to it. + let l:repo = s:hg_repo() + let l:path = l:repo.GetLawrenciumPath('', 'qseries', '') + execute 'pedit ' . l:path + wincmd P + + " Make the series buffer a Lawrencium buffer. + let b:mercurial_dir = l:repo.root_dir + call s:DefineMainCommands() + + " Add some commands and mappings. + command! -buffer Hgqseriesgoto :call s:HgQSeries_Goto() + command! -buffer Hgqserieseditmessage :call s:HgQSeries_EditMessage() + command! -buffer -nargs=+ Hgqseriesrename :call s:HgQSeries_Rename(<f-args>) + if g:lawrencium_define_mappings + nnoremap <buffer> <silent> <C-g> :Hgqseriesgoto<cr> + nnoremap <buffer> <silent> <C-e> :Hgqserieseditmessage<cr> + nnoremap <buffer> <silent> q :bdelete!<cr> + endif +endfunction + +function! s:HgQSeries_GetCurrentPatchName() abort + let l:pos = getpos('.') + return getbufvar('%', 'lawrencium_patchname_' . l:pos[1]) +endfunction + +function! s:HgQSeries_Goto() abort + let l:repo = s:hg_repo() + let l:patchname = HgQSeries_GetCurrentPatchName() + if len(l:patchname) == 0 + call s:error("No patch to go to here.") + return + endif + call l:repo.RunCommand('qgoto', l:patchname) + edit +endfunction + +function! s:HgQSeries_Rename(...) abort + let l:repo = s:hg_repo() + let l:current_name = HgQSeries_GetCurrentPatchName() + if len(l:current_name) == 0 + call s:error("No patch to rename here.") + return + endif + let l:new_name = '"' . join(a:000, ' ') . '"' + call l:repo.RunCommand('qrename', l:current_name, l:new_name) + edit +endfunction + +function! s:HgQSeries_EditMessage() abort + let l:repo = s:hg_repo() + let l:patchname = getbufvar('%', 'lawrencium_patchname_1') + if len(l:patchname) == 0 + call s:error("No patch to edit here.") + return + endif + let l:current = split(l:repo.RunCommand('qheader', l:patchname), '\n') + + " Open a temp file to write the commit message. + let l:temp_file = s:tempname('hg-qrefedit-', '.txt') + split + execute 'edit ' . l:temp_file + call append(0, 'HG: Enter the new commit message for patch "' . l:patchname . '" here.\n') + call append(0, '') + call append(0, l:current) + call cursor(1, 1) + + " Make it a temp buffer that will actually change the commit message + " when it is saved and closed. + let b:mercurial_dir = l:repo.root_dir + let b:lawrencium_patchname = l:patchname + setlocal bufhidden=delete + setlocal filetype=hgcommit + autocmd BufDelete <buffer> call s:HgQSeries_EditMessage_Execute(expand('<afile>:p')) + + call s:DefineMainCommands() +endfunction + +function! s:HgQSeries_EditMessage_Execute(log_file) abort + if !filereadable(a:log_file) + call s:error("abort: Commit message not saved") + return + endif + + " Clean all the 'HG:' lines. + let l:is_valid = s:clean_commit_file(a:log_file) + if !l:is_valid + call s:error("abort: Empty commit message") + return + endif + + " Get the repo and edit the given patch. + let l:repo = s:hg_repo() + let l:hg_args = ['-s', '-l', a:log_file] + call l:repo.RunCommand('qref', l:hg_args) +endfunction + + +call s:AddMainCommand("Hgqseries call s:HgQSeries()") + +" }}} + " Autoload Functions {{{ " Prints a summary of the current repo (if any) that's appropriate for