hgcommand.vim
1703 lines
| 57.0 KiB
| text/x-vim
|
VimLexer
|
r2591 | " vim600: set foldmethod=marker: | ||
" | ||||
|
r2592 | " Vim plugin to assist in working with HG-controlled files. | ||
|
r2591 | " | ||
" Last Change: 2006/02/22 | ||||
|
r2759 | " Version: 1.77 | ||
|
r2592 | " Maintainer: Mathieu Clabaut <mathieu.clabaut@gmail.com> | ||
|
r2591 | " License: This file is placed in the public domain. | ||
|
r2604 | " Credits: | ||
|
r2592 | " Bob Hiestand <bob.hiestand@gmail.com> for the fabulous | ||
" cvscommand.vim from which this script was directly created by | ||||
" means of sed commands and minor tweaks. | ||||
|
r19023 | " Note: | ||
|
r7021 | " For Vim7 the use of Bob Hiestand's vcscommand.vim | ||
" <http://www.vim.org/scripts/script.php?script_id=90> | ||||
" in conjunction with Vladmir Marek's Hg backend | ||||
" <http://www.vim.org/scripts/script.php?script_id=1898> | ||||
" is recommended. | ||||
|
r2591 | |||
|
r2603 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | ||
" | ||||
|
r2759 | " Section: Documentation | ||
|
r2603 | "---------------------------- | ||
" | ||||
" Documentation should be available by ":help hgcommand" command, once the | ||||
" script has been copied in you .vim/plugin directory. | ||||
" | ||||
" You still can read the documentation at the end of this file. Locate it by | ||||
" searching the "hgcommand-contents" string (and set ft=help to have | ||||
|
r17522 | " appropriate syntactic coloration). | ||
|
r2604 | |||
|
r2591 | " Section: Plugin header {{{1 | ||
|
r2592 | " loaded_hgcommand is set to 1 when the initialization begins, and 2 when it | ||
|
r2591 | " completes. This allows various actions to only be taken by functions after | ||
" system initialization. | ||||
|
r3546 | if exists("g:loaded_hgcommand") | ||
|
r2591 | finish | ||
endif | ||||
|
r3546 | let g:loaded_hgcommand = 1 | ||
|
r2591 | |||
|
r2759 | " store 'compatible' settings | ||
let s:save_cpo = &cpo | ||||
set cpo&vim | ||||
" run checks | ||||
let s:script_name = expand("<sfile>:t:r") | ||||
function! s:HGCleanupOnFailure(err) | ||||
echohl WarningMsg | ||||
echomsg s:script_name . ":" a:err "Plugin not loaded" | ||||
echohl None | ||||
|
r3546 | let g:loaded_hgcommand = "no" | ||
|
r2759 | unlet s:save_cpo s:script_name | ||
endfunction | ||||
|
r2591 | if v:version < 602 | ||
|
r2759 | call <SID>HGCleanupOnFailure("VIM 6.2 or later required.") | ||
|
r2591 | finish | ||
endif | ||||
|
r2759 | if !exists("*system") | ||
call <SID>HGCleanupOnFailure("builtin system() function required.") | ||||
finish | ||||
endif | ||||
let s:script_version = "v0.2" | ||||
|
r2591 | " Section: Event group setup {{{1 | ||
|
r2592 | augroup HGCommand | ||
|
r2591 | augroup END | ||
" Section: Plugin initialization {{{1 | ||||
|
r2592 | silent do HGCommand User HGPluginInit | ||
|
r2591 | |||
" Section: Script variable initialization {{{1 | ||||
|
r2592 | let s:HGCommandEditFileRunning = 0 | ||
|
r2591 | unlet! s:vimDiffRestoreCmd | ||
unlet! s:vimDiffSourceBuffer | ||||
unlet! s:vimDiffBufferCount | ||||
unlet! s:vimDiffScratchList | ||||
" Section: Utility functions {{{1 | ||||
|
r2592 | " Function: s:HGResolveLink() {{{2 | ||
|
r2591 | " Fully resolve the given file name to remove shortcuts or symbolic links. | ||
|
r2592 | function! s:HGResolveLink(fileName) | ||
|
r2591 | let resolved = resolve(a:fileName) | ||
if resolved != a:fileName | ||||
|
r2759 | let resolved = <SID>HGResolveLink(resolved) | ||
|
r2591 | endif | ||
return resolved | ||||
endfunction | ||||
|
r2592 | " Function: s:HGChangeToCurrentFileDir() {{{2 | ||
" Go to the directory in which the current HG-controlled file is located. | ||||
" If this is a HG command buffer, first switch to the original file. | ||||
|
r2591 | |||
|
r2592 | function! s:HGChangeToCurrentFileDir(fileName) | ||
|
r2591 | let oldCwd=getcwd() | ||
|
r2759 | let fileName=<SID>HGResolveLink(a:fileName) | ||
|
r2591 | let newCwd=fnamemodify(fileName, ':h') | ||
if strlen(newCwd) > 0 | ||||
|
r21629 | try | execute 'cd' escape(newCwd, ' ') | catch | | endtry | ||
|
r2591 | endif | ||
return oldCwd | ||||
endfunction | ||||
|
r2759 | " Function: <SID>HGGetOption(name, default) {{{2 | ||
|
r2591 | " Grab a user-specified option to override the default provided. Options are | ||
" searched in the window, buffer, then global spaces. | ||||
|
r2592 | function! s:HGGetOption(name, default) | ||
|
r2591 | if exists("s:" . a:name . "Override") | ||
execute "return s:".a:name."Override" | ||||
elseif exists("w:" . a:name) | ||||
execute "return w:".a:name | ||||
elseif exists("b:" . a:name) | ||||
execute "return b:".a:name | ||||
elseif exists("g:" . a:name) | ||||
execute "return g:".a:name | ||||
else | ||||
return a:default | ||||
endif | ||||
endfunction | ||||
|
r2592 | " Function: s:HGEditFile(name, origBuffNR) {{{2 | ||
|
r2591 | " Wrapper around the 'edit' command to provide some helpful error text if the | ||
" current buffer can't be abandoned. If name is provided, it is used; | ||||
" otherwise, a nameless scratch buffer is used. | ||||
" Returns: 0 if successful, -1 if an error occurs. | ||||
|
r2592 | function! s:HGEditFile(name, origBuffNR) | ||
|
r2591 | "Name parameter will be pasted into expression. | ||
let name = escape(a:name, ' *?\') | ||||
|
r2759 | let editCommand = <SID>HGGetOption('HGCommandEdit', 'edit') | ||
|
r2591 | if editCommand != 'edit' | ||
|
r2759 | if <SID>HGGetOption('HGCommandSplit', 'horizontal') == 'horizontal' | ||
|
r2591 | if name == "" | ||
let editCommand = 'rightbelow new' | ||||
else | ||||
let editCommand = 'rightbelow split ' . name | ||||
endif | ||||
else | ||||
if name == "" | ||||
let editCommand = 'vert rightbelow new' | ||||
else | ||||
let editCommand = 'vert rightbelow split ' . name | ||||
endif | ||||
endif | ||||
else | ||||
if name == "" | ||||
let editCommand = 'enew' | ||||
else | ||||
let editCommand = 'edit ' . name | ||||
endif | ||||
endif | ||||
" Protect against useless buffer set-up | ||||
|
r2592 | let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1 | ||
|
r2591 | try | ||
execute editCommand | ||||
finally | ||||
|
r2592 | let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1 | ||
|
r2591 | endtry | ||
|
r2592 | let b:HGOrigBuffNR=a:origBuffNR | ||
let b:HGCommandEdit='split' | ||||
|
r2591 | endfunction | ||
|
r2592 | " Function: s:HGCreateCommandBuffer(cmd, cmdName, statusText, filename) {{{2 | ||
|
r2591 | " Creates a new scratch buffer and captures the output from execution of the | ||
" given command. The name of the scratch buffer is returned. | ||||
|
r2592 | function! s:HGCreateCommandBuffer(cmd, cmdName, statusText, origBuffNR) | ||
|
r2591 | let fileName=bufname(a:origBuffNR) | ||
let resultBufferName='' | ||||
|
r2759 | if <SID>HGGetOption("HGCommandNameResultBuffers", 0) | ||
let nameMarker = <SID>HGGetOption("HGCommandNameMarker", '_') | ||||
|
r2591 | if strlen(a:statusText) > 0 | ||
let bufName=a:cmdName . ' -- ' . a:statusText | ||||
else | ||||
let bufName=a:cmdName | ||||
endif | ||||
let bufName=fileName . ' ' . nameMarker . bufName . nameMarker | ||||
let counter=0 | ||||
let resultBufferName = bufName | ||||
while buflisted(resultBufferName) | ||||
let counter=counter + 1 | ||||
let resultBufferName=bufName . ' (' . counter . ')' | ||||
endwhile | ||||
endif | ||||
|
r2759 | let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " " . a:cmd | ||
|
r2634 | "echomsg "DBG :".hgCommand | ||
|
r2592 | let hgOut = system(hgCommand) | ||
|
r2591 | " HACK: diff command does not return proper error codes | ||
|
r2592 | if v:shell_error && a:cmdName != 'hgdiff' | ||
if strlen(hgOut) == 0 | ||||
echoerr "HG command failed" | ||||
|
r2591 | else | ||
|
r2592 | echoerr "HG command failed: " . hgOut | ||
|
r2591 | endif | ||
return -1 | ||||
endif | ||||
|
r2592 | if strlen(hgOut) == 0 | ||
|
r2591 | " Handle case of no output. In this case, it is important to check the | ||
|
r2592 | " file status, especially since hg edit/unedit may change the attributes | ||
|
r2591 | " of the file with no visible output. | ||
|
r2592 | echomsg "No output from HG command" | ||
|
r2591 | checktime | ||
return -1 | ||||
endif | ||||
|
r2759 | if <SID>HGEditFile(resultBufferName, a:origBuffNR) == -1 | ||
|
r2591 | return -1 | ||
endif | ||||
set buftype=nofile | ||||
set noswapfile | ||||
set filetype= | ||||
|
r2759 | if <SID>HGGetOption("HGCommandDeleteOnHide", 0) | ||
|
r2591 | set bufhidden=delete | ||
endif | ||||
|
r2592 | silent 0put=hgOut | ||
|
r2591 | |||
" The last command left a blank line at the end of the buffer. If the | ||||
" last line is folded (a side effect of the 'put') then the attempt to | ||||
" remove the blank line will kill the last fold. | ||||
" | ||||
" This could be fixed by explicitly detecting whether the last line is | ||||
" within a fold, but I prefer to simply unfold the result buffer altogether. | ||||
|
r2759 | if has("folding") | ||
setlocal nofoldenable | ||||
|
r2591 | endif | ||
$d | ||||
1 | ||||
" Define the environment and execute user-defined hooks. | ||||
|
r2592 | let b:HGSourceFile=fileName | ||
let b:HGCommand=a:cmdName | ||||
|
r2591 | if a:statusText != "" | ||
|
r2592 | let b:HGStatusText=a:statusText | ||
|
r2591 | endif | ||
|
r2592 | silent do HGCommand User HGBufferCreated | ||
|
r2591 | return bufnr("%") | ||
endfunction | ||||
|
r2592 | " Function: s:HGBufferCheck(hgBuffer) {{{2 | ||
" Attempts to locate the original file to which HG operations were applied | ||||
|
r2591 | " for a given buffer. | ||
|
r2592 | function! s:HGBufferCheck(hgBuffer) | ||
let origBuffer = getbufvar(a:hgBuffer, "HGOrigBuffNR") | ||||
|
r2591 | if origBuffer | ||
if bufexists(origBuffer) | ||||
return origBuffer | ||||
else | ||||
" Original buffer no longer exists. | ||||
|
r2759 | return -1 | ||
|
r2591 | endif | ||
else | ||||
" No original buffer | ||||
|
r2592 | return a:hgBuffer | ||
|
r2591 | endif | ||
endfunction | ||||
|
r2592 | " Function: s:HGCurrentBufferCheck() {{{2 | ||
" Attempts to locate the original file to which HG operations were applied | ||||
|
r2591 | " for the current buffer. | ||
|
r2592 | function! s:HGCurrentBufferCheck() | ||
|
r2759 | return <SID>HGBufferCheck(bufnr("%")) | ||
|
r2591 | endfunction | ||
|
r2592 | " Function: s:HGToggleDeleteOnHide() {{{2 | ||
" Toggles on and off the delete-on-hide behavior of HG buffers | ||||
|
r2591 | |||
|
r2592 | function! s:HGToggleDeleteOnHide() | ||
if exists("g:HGCommandDeleteOnHide") | ||||
unlet g:HGCommandDeleteOnHide | ||||
|
r2591 | else | ||
|
r2592 | let g:HGCommandDeleteOnHide=1 | ||
|
r2591 | endif | ||
endfunction | ||||
|
r2592 | " Function: s:HGDoCommand(hgcmd, cmdName, statusText) {{{2 | ||
" General skeleton for HG function execution. | ||||
|
r2591 | " Returns: name of the new command buffer containing the command results | ||
|
r2592 | function! s:HGDoCommand(cmd, cmdName, statusText) | ||
|
r2759 | let hgBufferCheck=<SID>HGCurrentBufferCheck() | ||
if hgBufferCheck == -1 | ||||
|
r2591 | echo "Original buffer no longer exists, aborting." | ||
return -1 | ||||
endif | ||||
|
r2592 | let fileName=bufname(hgBufferCheck) | ||
|
r2591 | if isdirectory(fileName) | ||
let fileName=fileName . "/" . getline(".") | ||||
endif | ||||
|
r2759 | let realFileName = fnamemodify(<SID>HGResolveLink(fileName), ':t') | ||
let oldCwd=<SID>HGChangeToCurrentFileDir(fileName) | ||||
|
r2591 | try | ||
|
r2592 | " TODO | ||
"if !filereadable('HG/Root') | ||||
"throw fileName . ' is not a HG-controlled file.' | ||||
"endif | ||||
|
r2591 | let fullCmd = a:cmd . ' "' . realFileName . '"' | ||
|
r2592 | "echomsg "DEBUG".fullCmd | ||
|
r2759 | let resultBuffer=<SID>HGCreateCommandBuffer(fullCmd, a:cmdName, a:statusText, hgBufferCheck) | ||
|
r2591 | return resultBuffer | ||
catch | ||||
echoerr v:exception | ||||
return -1 | ||||
finally | ||||
execute 'cd' escape(oldCwd, ' ') | ||||
endtry | ||||
endfunction | ||||
|
r2592 | " Function: s:HGGetStatusVars(revision, branch, repository) {{{2 | ||
|
r2591 | " | ||
|
r2592 | " Obtains a HG revision number and branch name. The 'revisionVar', | ||
|
r2591 | " 'branchVar'and 'repositoryVar' arguments, if non-empty, contain the names of variables to hold | ||
" the corresponding results. | ||||
" | ||||
" Returns: string to be exec'd that sets the multiple return values. | ||||
|
r2592 | function! s:HGGetStatusVars(revisionVar, branchVar, repositoryVar) | ||
|
r2759 | let hgBufferCheck=<SID>HGCurrentBufferCheck() | ||
|
r2636 | "echomsg "DBG : in HGGetStatusVars" | ||
|
r2759 | if hgBufferCheck == -1 | ||
|
r2591 | return "" | ||
endif | ||||
|
r2592 | let fileName=bufname(hgBufferCheck) | ||
|
r2759 | let fileNameWithoutLink=<SID>HGResolveLink(fileName) | ||
|
r2634 | let realFileName = fnamemodify(fileNameWithoutLink, ':t') | ||
|
r2759 | let oldCwd=<SID>HGChangeToCurrentFileDir(realFileName) | ||
|
r2591 | try | ||
|
r2759 | let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " root " | ||
|
r2634 | let roottext=system(hgCommand) | ||
" Suppress ending null char ! Does it work in window ? | ||||
|
r2636 | let roottext=substitute(roottext,'^.*/\([^/\n\r]*\)\n\_.*$','\1','') | ||
|
r2634 | if match(getcwd()."/".fileNameWithoutLink, roottext) == -1 | ||
return "" | ||||
endif | ||||
|
r2636 | let returnExpression = "" | ||
|
r2637 | if a:repositoryVar != "" | ||
let returnExpression=returnExpression . " | let " . a:repositoryVar . "='" . roottext . "'" | ||||
endif | ||||
|
r2759 | let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " status -mardui " . realFileName | ||
|
r2592 | let statustext=system(hgCommand) | ||
|
r2591 | if(v:shell_error) | ||
return "" | ||||
endif | ||||
|
r2759 | if match(statustext, '^[?I]') >= 0 | ||
|
r2591 | let revision="NEW" | ||
|
r2759 | elseif match(statustext, '^[R]') >= 0 | ||
|
r2592 | let revision="REMOVED" | ||
|
r2759 | elseif match(statustext, '^[D]') >= 0 | ||
|
r2592 | let revision="DELETED" | ||
|
r2759 | elseif match(statustext, '^[A]') >= 0 | ||
|
r2592 | let revision="ADDED" | ||
|
r2636 | else | ||
" The file is tracked, we can try to get is revision number | ||||
|
r3542 | let hgCommand = <SID>HGGetOption("HGCommandHGExec", "hg") . " parents " | ||
|
r2636 | let statustext=system(hgCommand) | ||
if(v:shell_error) | ||||
|
r2734 | return "" | ||
|
r2636 | endif | ||
let revision=substitute(statustext, '^changeset:\s*\(\d\+\):.*\_$\_.*$', '\1', "") | ||||
|
r2591 | |||
|
r2636 | if a:branchVar != "" && match(statustext, '^\_.*\_^branch:') >= 0 | ||
|
r2734 | let branch=substitute(statustext, '^\_.*\_^branch:\s*\(\S\+\)\n\_.*$', '\1', "") | ||
let returnExpression=returnExpression . " | let " . a:branchVar . "='" . branch . "'" | ||||
|
r2636 | endif | ||
|
r2592 | endif | ||
|
r2636 | if (exists('revision')) | ||
let returnExpression = "let " . a:revisionVar . "='" . revision . "' " . returnExpression | ||||
|
r2591 | endif | ||
|
r2592 | |||
|
r2591 | return returnExpression | ||
finally | ||||
|
r21629 | try | execute 'cd' escape(oldCwd, ' ') | catch | | endtry | ||
|
r2591 | endtry | ||
endfunction | ||||
|
r2592 | " Function: s:HGSetupBuffer() {{{2 | ||
" Attempts to set the b:HGBranch, b:HGRevision and b:HGRepository variables. | ||||
|
r2591 | |||
|
r2607 | function! s:HGSetupBuffer(...) | ||
if (exists("b:HGBufferSetup") && b:HGBufferSetup && !exists('a:1')) | ||||
|
r2591 | " This buffer is already set up. | ||
return | ||||
endif | ||||
|
r2759 | if !<SID>HGGetOption("HGCommandEnableBufferSetup", 0) | ||
|
r2591 | \ || @% == "" | ||
|
r2592 | \ || s:HGCommandEditFileRunning > 0 | ||
\ || exists("b:HGOrigBuffNR") | ||||
unlet! b:HGRevision | ||||
unlet! b:HGBranch | ||||
unlet! b:HGRepository | ||||
|
r2591 | return | ||
endif | ||||
if !filereadable(expand("%")) | ||||
return -1 | ||||
endif | ||||
let revision="" | ||||
let branch="" | ||||
let repository="" | ||||
|
r2759 | exec <SID>HGGetStatusVars('revision', 'branch', 'repository') | ||
|
r2592 | "echomsg "DBG ".revision."#".branch."#".repository | ||
|
r2591 | if revision != "" | ||
|
r2592 | let b:HGRevision=revision | ||
|
r2591 | else | ||
|
r2592 | unlet! b:HGRevision | ||
|
r2591 | endif | ||
if branch != "" | ||||
|
r2592 | let b:HGBranch=branch | ||
|
r2591 | else | ||
|
r2592 | unlet! b:HGBranch | ||
|
r2591 | endif | ||
if repository != "" | ||||
|
r2592 | let b:HGRepository=repository | ||
|
r2591 | else | ||
|
r2592 | unlet! b:HGRepository | ||
|
r2591 | endif | ||
|
r2592 | silent do HGCommand User HGBufferSetup | ||
let b:HGBufferSetup=1 | ||||
|
r2591 | endfunction | ||
|
r2592 | " Function: s:HGMarkOrigBufferForSetup(hgbuffer) {{{2 | ||
" Resets the buffer setup state of the original buffer for a given HG buffer. | ||||
" Returns: The HG buffer number in a passthrough mode. | ||||
|
r2591 | |||
|
r2592 | function! s:HGMarkOrigBufferForSetup(hgBuffer) | ||
|
r2591 | checktime | ||
|
r2592 | if a:hgBuffer != -1 | ||
|
r2759 | let origBuffer = <SID>HGBufferCheck(a:hgBuffer) | ||
|
r2591 | "This should never not work, but I'm paranoid | ||
|
r2592 | if origBuffer != a:hgBuffer | ||
call setbufvar(origBuffer, "HGBufferSetup", 0) | ||||
|
r2591 | endif | ||
|
r2636 | else | ||
"We are presumably in the original buffer | ||||
let b:HGBufferSetup = 0 | ||||
"We do the setup now as now event will be triggered allowing it later. | ||||
|
r2759 | call <SID>HGSetupBuffer() | ||
|
r2591 | endif | ||
|
r2592 | return a:hgBuffer | ||
|
r2591 | endfunction | ||
|
r2592 | " Function: s:HGOverrideOption(option, [value]) {{{2 | ||
" Provides a temporary override for the given HG option. If no value is | ||||
|
r2591 | " passed, the override is disabled. | ||
|
r2592 | function! s:HGOverrideOption(option, ...) | ||
|
r2591 | if a:0 == 0 | ||
unlet! s:{a:option}Override | ||||
else | ||||
let s:{a:option}Override = a:1 | ||||
endif | ||||
endfunction | ||||
|
r2592 | " Function: s:HGWipeoutCommandBuffers() {{{2 | ||
" Clears all current HG buffers of the specified type for a given source. | ||||
|
r2591 | |||
|
r2592 | function! s:HGWipeoutCommandBuffers(originalBuffer, hgCommand) | ||
|
r2591 | let buffer = 1 | ||
while buffer <= bufnr('$') | ||||
|
r2592 | if getbufvar(buffer, 'HGOrigBuffNR') == a:originalBuffer | ||
if getbufvar(buffer, 'HGCommand') == a:hgCommand | ||||
|
r2591 | execute 'bw' buffer | ||
endif | ||||
endif | ||||
let buffer = buffer + 1 | ||||
endwhile | ||||
endfunction | ||||
|
r2603 | " Function: s:HGInstallDocumentation(full_name, revision) {{{2 | ||
" Install help documentation. | ||||
" Arguments: | ||||
" full_name: Full name of this vim plugin script, including path name. | ||||
" revision: Revision of the vim script. #version# mark in the document file | ||||
" will be replaced with this string with 'v' prefix. | ||||
" Return: | ||||
" 1 if new document installed, 0 otherwise. | ||||
" Note: Cleaned and generalized by guo-peng Wen | ||||
"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | ||||
|
r2734 | " Helper function to make mkdir as portable as possible | ||
function! s:HGFlexiMkdir(dir) | ||||
if exists("*mkdir") " we can use Vim's own mkdir() | ||||
call mkdir(a:dir) | ||||
elseif !exists("+shellslash") | ||||
|
r2759 | call system("mkdir -p '".a:dir."'") | ||
|
r2734 | else " M$ | ||
let l:ssl = &shellslash | ||||
try | ||||
set shellslash | ||||
|
r2759 | " no single quotes? | ||
|
r2734 | call system('mkdir "'.a:dir.'"') | ||
finally | ||||
let &shellslash = l:ssl | ||||
endtry | ||||
endif | ||||
endfunction | ||||
|
r2603 | |||
|
r2759 | function! s:HGInstallDocumentation(full_name) | ||
|
r2734 | " Figure out document path based on full name of this script: | ||
|
r2759 | let l:vim_doc_path = fnamemodify(a:full_name, ":h:h") . "/doc" | ||
|
r2734 | if filewritable(l:vim_doc_path) != 2 | ||
|
r2759 | echomsg s:script_name . ": Trying to update docs at" l:vim_doc_path | ||
|
r2734 | silent! call <SID>HGFlexiMkdir(l:vim_doc_path) | ||
if filewritable(l:vim_doc_path) != 2 | ||||
" Try first item in 'runtimepath': | ||||
|
r2759 | let l:vim_doc_path = | ||
\ substitute(&runtimepath, '^\([^,]*\).*', '\1/doc', 'e') | ||||
|
r2734 | if filewritable(l:vim_doc_path) != 2 | ||
|
r2759 | echomsg s:script_name . ": Trying to update docs at" l:vim_doc_path | ||
|
r2734 | silent! call <SID>HGFlexiMkdir(l:vim_doc_path) | ||
if filewritable(l:vim_doc_path) != 2 | ||||
" Put a warning: | ||||
echomsg "Unable to open documentation directory" | ||||
echomsg " type `:help add-local-help' for more information." | ||||
return 0 | ||||
endif | ||||
endif | ||||
|
r2603 | endif | ||
|
r2734 | endif | ||
|
r2603 | |||
|
r2759 | " Full name of documentation file: | ||
let l:doc_file = | ||||
\ l:vim_doc_path . "/" . s:script_name . ".txt" | ||||
|
r2734 | " Bail out if document file is still up to date: | ||
|
r2759 | if filereadable(l:doc_file) && | ||
\ getftime(a:full_name) < getftime(l:doc_file) | ||||
|
r2734 | return 0 | ||
endif | ||||
|
r2603 | |||
|
r2759 | " temporary global settings | ||
let l:lz = &lazyredraw | ||||
let l:hls = &hlsearch | ||||
set lazyredraw nohlsearch | ||||
|
r2734 | " Create a new buffer & read in the plugin file (me): | ||
|
r2759 | 1 new | ||
setlocal noswapfile modifiable nomodeline | ||||
if has("folding") | ||||
setlocal nofoldenable | ||||
endif | ||||
silent execute "read" escape(a:full_name, " ") | ||||
let l:doc_buf = bufnr("%") | ||||
|
r2603 | |||
|
r2759 | 1 | ||
|
r2734 | " Delete from first line to a line starts with | ||
" === START_DOC | ||||
|
r3546 | silent 1,/^=\{3,}\s\+START_DOC\C/ delete _ | ||
|
r2734 | " Delete from a line starts with | ||
" === END_DOC | ||||
" to the end of the documents: | ||||
|
r3546 | silent /^=\{3,}\s\+END_DOC\C/,$ delete _ | ||
|
r2603 | |||
|
r2734 | " Add modeline for help doc: the modeline string is mangled intentionally | ||
" to avoid it be recognized by VIM: | ||||
|
r2759 | call append(line("$"), "") | ||
call append(line("$"), " v" . "im:tw=78:ts=8:ft=help:norl:") | ||||
|
r2603 | |||
|
r2734 | " Replace revision: | ||
|
r2759 | silent execute "normal :1s/#version#/" . s:script_version . "/\<CR>" | ||
|
r2734 | " Save the help document and wipe out buffer: | ||
|
r2759 | silent execute "wq!" escape(l:doc_file, " ") "| bw" l:doc_buf | ||
|
r2734 | " Build help tags: | ||
|
r2759 | silent execute "helptags" l:vim_doc_path | ||
|
r2603 | |||
|
r2759 | let &hlsearch = l:hls | ||
let &lazyredraw = l:lz | ||||
|
r2734 | return 1 | ||
|
r2603 | endfunction | ||
|
r2591 | " Section: Public functions {{{1 | ||
|
r2592 | " Function: HGGetRevision() {{{2 | ||
" Global function for retrieving the current buffer's HG revision number. | ||||
|
r2591 | " Returns: Revision number or an empty string if an error occurs. | ||
|
r2592 | function! HGGetRevision() | ||
|
r2591 | let revision="" | ||
|
r2759 | exec <SID>HGGetStatusVars('revision', '', '') | ||
|
r2591 | return revision | ||
endfunction | ||||
|
r2592 | " Function: HGDisableBufferSetup() {{{2 | ||
|
r2591 | " Global function for deactivating the buffer autovariables. | ||
|
r2592 | function! HGDisableBufferSetup() | ||
let g:HGCommandEnableBufferSetup=0 | ||||
silent! augroup! HGCommandPlugin | ||||
|
r2591 | endfunction | ||
|
r2592 | " Function: HGEnableBufferSetup() {{{2 | ||
|
r2591 | " Global function for activating the buffer autovariables. | ||
|
r2592 | function! HGEnableBufferSetup() | ||
let g:HGCommandEnableBufferSetup=1 | ||||
augroup HGCommandPlugin | ||||
|
r2591 | au! | ||
|
r2759 | au BufEnter * call <SID>HGSetupBuffer() | ||
au BufWritePost * call <SID>HGSetupBuffer() | ||||
|
r2607 | " Force resetting up buffer on external file change (HG update) | ||
|
r2759 | au FileChangedShell * call <SID>HGSetupBuffer(1) | ||
|
r2591 | augroup END | ||
" Only auto-load if the plugin is fully loaded. This gives other plugins a | ||||
" chance to run. | ||||
|
r2592 | if g:loaded_hgcommand == 2 | ||
|
r2759 | call <SID>HGSetupBuffer() | ||
|
r2591 | endif | ||
endfunction | ||||
|
r2592 | " Function: HGGetStatusLine() {{{2 | ||
" Default (sample) status line entry for HG files. This is only useful if | ||||
" HG-managed buffer mode is on (see the HGCommandEnableBufferSetup variable | ||||
|
r2591 | " for how to do this). | ||
|
r2592 | function! HGGetStatusLine() | ||
if exists('b:HGSourceFile') | ||||
|
r2591 | " This is a result buffer | ||
|
r2592 | let value='[' . b:HGCommand . ' ' . b:HGSourceFile | ||
if exists('b:HGStatusText') | ||||
let value=value . ' ' . b:HGStatusText | ||||
|
r2591 | endif | ||
let value = value . ']' | ||||
return value | ||||
endif | ||||
|
r2592 | if exists('b:HGRevision') | ||
\ && b:HGRevision != '' | ||||
\ && exists('b:HGRepository') | ||||
\ && b:HGRepository != '' | ||||
\ && exists('g:HGCommandEnableBufferSetup') | ||||
\ && g:HGCommandEnableBufferSetup | ||||
|
r2606 | if !exists('b:HGBranch') | ||
let l:branch='' | ||||
else | ||||
let l:branch=b:HGBranch | ||||
endif | ||||
return '[HG ' . b:HGRepository . '/' . l:branch .'/' . b:HGRevision . ']' | ||||
|
r2591 | else | ||
return '' | ||||
endif | ||||
endfunction | ||||
|
r2592 | " Section: HG command functions {{{1 | ||
|
r2591 | |||
|
r2592 | " Function: s:HGAdd() {{{2 | ||
function! s:HGAdd() | ||||
|
r2759 | return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('add', 'hgadd', '')) | ||
|
r2591 | endfunction | ||
|
r2592 | " Function: s:HGAnnotate(...) {{{2 | ||
function! s:HGAnnotate(...) | ||||
|
r2591 | if a:0 == 0 | ||
|
r2592 | if &filetype == "HGAnnotate" | ||
" This is a HGAnnotate buffer. Perform annotation of the version | ||||
|
r2591 | " indicated by the current line. | ||
|
r2592 | let revision = substitute(getline("."),'\(^[0-9]*\):.*','\1','') | ||
|
r2759 | if <SID>HGGetOption('HGCommandAnnotateParent', 0) != 0 && revision > 0 | ||
|
r2592 | let revision = revision - 1 | ||
|
r2591 | endif | ||
else | ||||
|
r2592 | let revision=HGGetRevision() | ||
|
r2591 | if revision == "" | ||
|
r2592 | echoerr "Unable to obtain HG version information." | ||
|
r2591 | return -1 | ||
endif | ||||
endif | ||||
else | ||||
let revision=a:1 | ||||
endif | ||||
if revision == "NEW" | ||||
echo "No annotatation available for new file." | ||||
return -1 | ||||
endif | ||||
|
r2759 | let resultBuffer=<SID>HGDoCommand('annotate -ndu -r ' . revision, 'hgannotate', revision) | ||
|
r2634 | "echomsg "DBG: ".resultBuffer | ||
|
r2591 | if resultBuffer != -1 | ||
|
r2592 | set filetype=HGAnnotate | ||
|
r2591 | endif | ||
return resultBuffer | ||||
endfunction | ||||
|
r2592 | " Function: s:HGCommit() {{{2 | ||
function! s:HGCommit(...) | ||||
|
r2591 | " Handle the commit message being specified. If a message is supplied, it | ||
" is used; if bang is supplied, an empty message is used; otherwise, the | ||||
" user is provided a buffer from which to edit the commit message. | ||||
if a:2 != "" || a:1 == "!" | ||||
|
r2759 | return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('commit -m "' . a:2 . '"', 'hgcommit', '')) | ||
|
r2591 | endif | ||
|
r2759 | let hgBufferCheck=<SID>HGCurrentBufferCheck() | ||
|
r2592 | if hgBufferCheck == -1 | ||
|
r2591 | echo "Original buffer no longer exists, aborting." | ||
return -1 | ||||
endif | ||||
" Protect against windows' backslashes in paths. They confuse exec'd | ||||
" commands. | ||||
let shellSlashBak = &shellslash | ||||
try | ||||
set shellslash | ||||
let messageFileName = tempname() | ||||
|
r2592 | let fileName=bufname(hgBufferCheck) | ||
|
r2759 | let realFilePath=<SID>HGResolveLink(fileName) | ||
|
r2591 | let newCwd=fnamemodify(realFilePath, ':h') | ||
if strlen(newCwd) == 0 | ||||
" Account for autochdir being in effect, which will make this blank, but | ||||
" we know we'll be in the current directory for the original file. | ||||
let newCwd = getcwd() | ||||
endif | ||||
let realFileName=fnamemodify(realFilePath, ':t') | ||||
|
r2759 | if <SID>HGEditFile(messageFileName, hgBufferCheck) == -1 | ||
|
r2591 | return | ||
endif | ||||
" Protect against case and backslash issues in Windows. | ||||
let autoPattern = '\c' . messageFileName | ||||
|
r17491 | " Ensure existence of group | ||
|
r2592 | augroup HGCommit | ||
|
r2591 | augroup END | ||
|
r2592 | execute 'au HGCommit BufDelete' autoPattern 'call delete("' . messageFileName . '")' | ||
execute 'au HGCommit BufDelete' autoPattern 'au! HGCommit * ' autoPattern | ||||
|
r2591 | |||
" Create a commit mapping. The mapping must clear all autocommands in case | ||||
|
r2592 | " it is invoked when HGCommandCommitOnWrite is active, as well as to not | ||
|
r2591 | " invoke the buffer deletion autocommand. | ||
|
r2592 | execute 'nnoremap <silent> <buffer> <Plug>HGCommit '. | ||
\ ':au! HGCommit * ' . autoPattern . '<CR>'. | ||||
\ ':g/^HG:/d<CR>'. | ||||
|
r2591 | \ ':update<CR>'. | ||
|
r2592 | \ ':call <SID>HGFinishCommit("' . messageFileName . '",' . | ||
|
r2591 | \ '"' . newCwd . '",' . | ||
\ '"' . realFileName . '",' . | ||||
|
r2636 | \ hgBufferCheck . ')<CR>' | ||
|
r2591 | |||
|
r2592 | silent 0put ='HG: ----------------------------------------------------------------------' | ||
silent put =\"HG: Enter Log. Lines beginning with `HG:' are removed automatically\" | ||||
silent put ='HG: Type <leader>cc (or your own <Plug>HGCommit mapping)' | ||||
|
r2591 | |||
|
r2759 | if <SID>HGGetOption('HGCommandCommitOnWrite', 1) == 1 | ||
|
r2592 | execute 'au HGCommit BufWritePre' autoPattern 'g/^HG:/d' | ||
|
r2759 | execute 'au HGCommit BufWritePost' autoPattern 'call <SID>HGFinishCommit("' . messageFileName . '", "' . newCwd . '", "' . realFileName . '", ' . hgBufferCheck . ') | au! * ' autoPattern | ||
|
r2592 | silent put ='HG: or write this buffer' | ||
|
r2591 | endif | ||
|
r2592 | silent put ='HG: to finish this commit operation' | ||
silent put ='HG: ----------------------------------------------------------------------' | ||||
|
r2591 | $ | ||
|
r2592 | let b:HGSourceFile=fileName | ||
let b:HGCommand='HGCommit' | ||||
set filetype=hg | ||||
|
r2591 | finally | ||
let &shellslash = shellSlashBak | ||||
endtry | ||||
endfunction | ||||
|
r2592 | " Function: s:HGDiff(...) {{{2 | ||
function! s:HGDiff(...) | ||||
|
r2591 | if a:0 == 1 | ||
let revOptions = '-r' . a:1 | ||||
let caption = a:1 . ' -> current' | ||||
elseif a:0 == 2 | ||||
let revOptions = '-r' . a:1 . ' -r' . a:2 | ||||
let caption = a:1 . ' -> ' . a:2 | ||||
else | ||||
let revOptions = '' | ||||
let caption = '' | ||||
endif | ||||
|
r2759 | let hgdiffopt=<SID>HGGetOption('HGCommandDiffOpt', 'w') | ||
|
r2591 | |||
|
r2592 | if hgdiffopt == "" | ||
|
r2591 | let diffoptionstring="" | ||
else | ||||
|
r2592 | let diffoptionstring=" -" . hgdiffopt . " " | ||
|
r2591 | endif | ||
|
r2759 | let resultBuffer = <SID>HGDoCommand('diff ' . diffoptionstring . revOptions , 'hgdiff', caption) | ||
if resultBuffer != -1 | ||||
|
r2591 | set filetype=diff | ||
endif | ||||
return resultBuffer | ||||
endfunction | ||||
|
r2592 | " Function: s:HGGotoOriginal(["!]) {{{2 | ||
function! s:HGGotoOriginal(...) | ||||
|
r2759 | let origBuffNR = <SID>HGCurrentBufferCheck() | ||
|
r2591 | if origBuffNR > 0 | ||
let origWinNR = bufwinnr(origBuffNR) | ||||
if origWinNR == -1 | ||||
execute 'buffer' origBuffNR | ||||
else | ||||
execute origWinNR . 'wincmd w' | ||||
endif | ||||
if a:0 == 1 | ||||
if a:1 == "!" | ||||
let buffnr = 1 | ||||
let buffmaxnr = bufnr("$") | ||||
while buffnr <= buffmaxnr | ||||
|
r2592 | if getbufvar(buffnr, "HGOrigBuffNR") == origBuffNR | ||
|
r2591 | execute "bw" buffnr | ||
endif | ||||
let buffnr = buffnr + 1 | ||||
endwhile | ||||
endif | ||||
endif | ||||
endif | ||||
endfunction | ||||
|
r2592 | " Function: s:HGFinishCommit(messageFile, targetDir, targetFile) {{{2 | ||
function! s:HGFinishCommit(messageFile, targetDir, targetFile, origBuffNR) | ||||
|
r2591 | if filereadable(a:messageFile) | ||
let oldCwd=getcwd() | ||||
if strlen(a:targetDir) > 0 | ||||
execute 'cd' escape(a:targetDir, ' ') | ||||
endif | ||||
|
r2759 | let resultBuffer=<SID>HGCreateCommandBuffer('commit -l "' . a:messageFile . '" "'. a:targetFile . '"', 'hgcommit', '', a:origBuffNR) | ||
|
r2591 | execute 'cd' escape(oldCwd, ' ') | ||
execute 'bw' escape(a:messageFile, ' *?\') | ||||
silent execute 'call delete("' . a:messageFile . '")' | ||||
|
r2759 | return <SID>HGMarkOrigBufferForSetup(resultBuffer) | ||
|
r2591 | else | ||
echoerr "Can't read message file; no commit is possible." | ||||
return -1 | ||||
endif | ||||
endfunction | ||||
|
r2592 | " Function: s:HGLog() {{{2 | ||
function! s:HGLog(...) | ||||
|
r2591 | if a:0 == 0 | ||
let versionOption = "" | ||||
let caption = '' | ||||
else | ||||
let versionOption=" -r" . a:1 | ||||
let caption = a:1 | ||||
endif | ||||
|
r2759 | let resultBuffer=<SID>HGDoCommand('log' . versionOption, 'hglog', caption) | ||
|
r2591 | if resultBuffer != "" | ||
set filetype=rcslog | ||||
endif | ||||
return resultBuffer | ||||
endfunction | ||||
|
r2592 | " Function: s:HGRevert() {{{2 | ||
function! s:HGRevert() | ||||
|
r2759 | return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('revert', 'hgrevert', '')) | ||
|
r2591 | endfunction | ||
|
r2592 | " Function: s:HGReview(...) {{{2 | ||
function! s:HGReview(...) | ||||
|
r2591 | if a:0 == 0 | ||
let versiontag="" | ||||
|
r2759 | if <SID>HGGetOption('HGCommandInteractive', 0) | ||
|
r2591 | let versiontag=input('Revision: ') | ||
endif | ||||
if versiontag == "" | ||||
let versiontag="(current)" | ||||
let versionOption="" | ||||
else | ||||
let versionOption=" -r " . versiontag . " " | ||||
endif | ||||
else | ||||
let versiontag=a:1 | ||||
let versionOption=" -r " . versiontag . " " | ||||
endif | ||||
|
r2759 | let resultBuffer = <SID>HGDoCommand('cat' . versionOption, 'hgreview', versiontag) | ||
|
r2591 | if resultBuffer > 0 | ||
|
r2592 | let &filetype=getbufvar(b:HGOrigBuffNR, '&filetype') | ||
|
r2591 | endif | ||
return resultBuffer | ||||
endfunction | ||||
|
r2592 | " Function: s:HGStatus() {{{2 | ||
function! s:HGStatus() | ||||
|
r2759 | return <SID>HGDoCommand('status', 'hgstatus', '') | ||
|
r2591 | endfunction | ||
|
r2592 | |||
" Function: s:HGUpdate() {{{2 | ||||
function! s:HGUpdate() | ||||
|
r2759 | return <SID>HGMarkOrigBufferForSetup(<SID>HGDoCommand('update', 'update', '')) | ||
|
r2591 | endfunction | ||
|
r2592 | " Function: s:HGVimDiff(...) {{{2 | ||
function! s:HGVimDiff(...) | ||||
|
r2759 | let originalBuffer = <SID>HGCurrentBufferCheck() | ||
|
r2592 | let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1 | ||
|
r2591 | try | ||
" If there's already a VimDiff'ed window, restore it. | ||||
|
r2592 | " There may only be one HGVimDiff original window at a time. | ||
|
r2591 | |||
if exists("s:vimDiffSourceBuffer") && s:vimDiffSourceBuffer != originalBuffer | ||||
" Clear the existing vimdiff setup by removing the result buffers. | ||||
|
r2759 | call <SID>HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff') | ||
|
r2591 | endif | ||
" Split and diff | ||||
if(a:0 == 2) | ||||
" Reset the vimdiff system, as 2 explicit versions were provided. | ||||
if exists('s:vimDiffSourceBuffer') | ||||
|
r2759 | call <SID>HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff') | ||
|
r2591 | endif | ||
|
r2759 | let resultBuffer = <SID>HGReview(a:1) | ||
|
r2591 | if resultBuffer < 0 | ||
|
r2592 | echomsg "Can't open HG revision " . a:1 | ||
|
r2591 | return resultBuffer | ||
endif | ||||
|
r2592 | let b:HGCommand = 'vimdiff' | ||
|
r2591 | diffthis | ||
let s:vimDiffBufferCount = 1 | ||||
let s:vimDiffScratchList = '{'. resultBuffer . '}' | ||||
" If no split method is defined, cheat, and set it to vertical. | ||||
try | ||||
|
r2759 | call <SID>HGOverrideOption('HGCommandSplit', <SID>HGGetOption('HGCommandDiffSplit', <SID>HGGetOption('HGCommandSplit', 'vertical'))) | ||
let resultBuffer=<SID>HGReview(a:2) | ||||
|
r2591 | finally | ||
|
r2759 | call <SID>HGOverrideOption('HGCommandSplit') | ||
|
r2591 | endtry | ||
if resultBuffer < 0 | ||||
|
r2592 | echomsg "Can't open HG revision " . a:1 | ||
|
r2591 | return resultBuffer | ||
endif | ||||
|
r2592 | let b:HGCommand = 'vimdiff' | ||
|
r2591 | diffthis | ||
let s:vimDiffBufferCount = 2 | ||||
let s:vimDiffScratchList = s:vimDiffScratchList . '{'. resultBuffer . '}' | ||||
else | ||||
" Add new buffer | ||||
try | ||||
" Force splitting behavior, otherwise why use vimdiff? | ||||
|
r2759 | call <SID>HGOverrideOption("HGCommandEdit", "split") | ||
call <SID>HGOverrideOption("HGCommandSplit", <SID>HGGetOption('HGCommandDiffSplit', <SID>HGGetOption('HGCommandSplit', 'vertical'))) | ||||
|
r2591 | if(a:0 == 0) | ||
|
r2759 | let resultBuffer=<SID>HGReview() | ||
|
r2591 | else | ||
|
r2759 | let resultBuffer=<SID>HGReview(a:1) | ||
|
r2591 | endif | ||
finally | ||||
|
r2759 | call <SID>HGOverrideOption("HGCommandEdit") | ||
call <SID>HGOverrideOption("HGCommandSplit") | ||||
|
r2591 | endtry | ||
if resultBuffer < 0 | ||||
|
r2592 | echomsg "Can't open current HG revision" | ||
|
r2591 | return resultBuffer | ||
endif | ||||
|
r2592 | let b:HGCommand = 'vimdiff' | ||
|
r2591 | diffthis | ||
if !exists('s:vimDiffBufferCount') | ||||
" New instance of vimdiff. | ||||
let s:vimDiffBufferCount = 2 | ||||
let s:vimDiffScratchList = '{' . resultBuffer . '}' | ||||
|
r2592 | " This could have been invoked on a HG result buffer, not the | ||
|
r2591 | " original buffer. | ||
wincmd W | ||||
execute 'buffer' originalBuffer | ||||
" Store info for later original buffer restore | ||||
|
r2759 | let s:vimDiffRestoreCmd = | ||
|
r2591 | \ "call setbufvar(".originalBuffer.", \"&diff\", ".getbufvar(originalBuffer, '&diff').")" | ||
\ . "|call setbufvar(".originalBuffer.", \"&foldcolumn\", ".getbufvar(originalBuffer, '&foldcolumn').")" | ||||
\ . "|call setbufvar(".originalBuffer.", \"&foldenable\", ".getbufvar(originalBuffer, '&foldenable').")" | ||||
\ . "|call setbufvar(".originalBuffer.", \"&foldmethod\", '".getbufvar(originalBuffer, '&foldmethod')."')" | ||||
\ . "|call setbufvar(".originalBuffer.", \"&scrollbind\", ".getbufvar(originalBuffer, '&scrollbind').")" | ||||
\ . "|call setbufvar(".originalBuffer.", \"&wrap\", ".getbufvar(originalBuffer, '&wrap').")" | ||||
|
r2759 | \ . "|if &foldmethod=='manual'|execute 'normal! zE'|endif" | ||
|
r2591 | diffthis | ||
wincmd w | ||||
else | ||||
" Adding a window to an existing vimdiff | ||||
let s:vimDiffBufferCount = s:vimDiffBufferCount + 1 | ||||
let s:vimDiffScratchList = s:vimDiffScratchList . '{' . resultBuffer . '}' | ||||
endif | ||||
endif | ||||
let s:vimDiffSourceBuffer = originalBuffer | ||||
" Avoid executing the modeline in the current buffer after the autocommand. | ||||
let currentBuffer = bufnr('%') | ||||
let saveModeline = getbufvar(currentBuffer, '&modeline') | ||||
try | ||||
call setbufvar(currentBuffer, '&modeline', 0) | ||||
|
r2592 | silent do HGCommand User HGVimDiffFinish | ||
|
r2591 | finally | ||
call setbufvar(currentBuffer, '&modeline', saveModeline) | ||||
endtry | ||||
return resultBuffer | ||||
finally | ||||
|
r2592 | let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1 | ||
|
r2591 | endtry | ||
endfunction | ||||
" Section: Command definitions {{{1 | ||||
" Section: Primary commands {{{2 | ||||
|
r2759 | com! HGAdd call <SID>HGAdd() | ||
com! -nargs=? HGAnnotate call <SID>HGAnnotate(<f-args>) | ||||
com! -bang -nargs=? HGCommit call <SID>HGCommit(<q-bang>, <q-args>) | ||||
com! -nargs=* HGDiff call <SID>HGDiff(<f-args>) | ||||
com! -bang HGGotoOriginal call <SID>HGGotoOriginal(<q-bang>) | ||||
com! -nargs=? HGLog call <SID>HGLog(<f-args>) | ||||
com! HGRevert call <SID>HGRevert() | ||||
com! -nargs=? HGReview call <SID>HGReview(<f-args>) | ||||
com! HGStatus call <SID>HGStatus() | ||||
com! HGUpdate call <SID>HGUpdate() | ||||
com! -nargs=* HGVimDiff call <SID>HGVimDiff(<f-args>) | ||||
|
r2591 | |||
|
r2592 | " Section: HG buffer management commands {{{2 | ||
com! HGDisableBufferSetup call HGDisableBufferSetup() | ||||
com! HGEnableBufferSetup call HGEnableBufferSetup() | ||||
|
r2591 | |||
|
r2592 | " Allow reloading hgcommand.vim | ||
|
r3546 | com! HGReload unlet! g:loaded_hgcommand | runtime plugin/hgcommand.vim | ||
|
r2591 | |||
" Section: Plugin command mappings {{{1 | ||||
|
r2592 | nnoremap <silent> <Plug>HGAdd :HGAdd<CR> | ||
nnoremap <silent> <Plug>HGAnnotate :HGAnnotate<CR> | ||||
nnoremap <silent> <Plug>HGCommit :HGCommit<CR> | ||||
nnoremap <silent> <Plug>HGDiff :HGDiff<CR> | ||||
nnoremap <silent> <Plug>HGGotoOriginal :HGGotoOriginal<CR> | ||||
nnoremap <silent> <Plug>HGClearAndGotoOriginal :HGGotoOriginal!<CR> | ||||
nnoremap <silent> <Plug>HGLog :HGLog<CR> | ||||
nnoremap <silent> <Plug>HGRevert :HGRevert<CR> | ||||
nnoremap <silent> <Plug>HGReview :HGReview<CR> | ||||
nnoremap <silent> <Plug>HGStatus :HGStatus<CR> | ||||
nnoremap <silent> <Plug>HGUpdate :HGUpdate<CR> | ||||
nnoremap <silent> <Plug>HGVimDiff :HGVimDiff<CR> | ||||
|
r2591 | |||
" Section: Default mappings {{{1 | ||||
|
r2592 | if !hasmapto('<Plug>HGAdd') | ||
nmap <unique> <Leader>hga <Plug>HGAdd | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGAnnotate') | ||
nmap <unique> <Leader>hgn <Plug>HGAnnotate | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGClearAndGotoOriginal') | ||
nmap <unique> <Leader>hgG <Plug>HGClearAndGotoOriginal | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGCommit') | ||
nmap <unique> <Leader>hgc <Plug>HGCommit | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGDiff') | ||
nmap <unique> <Leader>hgd <Plug>HGDiff | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGGotoOriginal') | ||
nmap <unique> <Leader>hgg <Plug>HGGotoOriginal | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGLog') | ||
nmap <unique> <Leader>hgl <Plug>HGLog | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGRevert') | ||
nmap <unique> <Leader>hgq <Plug>HGRevert | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGReview') | ||
nmap <unique> <Leader>hgr <Plug>HGReview | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGStatus') | ||
nmap <unique> <Leader>hgs <Plug>HGStatus | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGUpdate') | ||
nmap <unique> <Leader>hgu <Plug>HGUpdate | ||||
|
r2591 | endif | ||
|
r2592 | if !hasmapto('<Plug>HGVimDiff') | ||
nmap <unique> <Leader>hgv <Plug>HGVimDiff | ||||
|
r2591 | endif | ||
" Section: Menu items {{{1 | ||||
|
r2592 | silent! aunmenu Plugin.HG | ||
amenu <silent> &Plugin.HG.&Add <Plug>HGAdd | ||||
amenu <silent> &Plugin.HG.A&nnotate <Plug>HGAnnotate | ||||
amenu <silent> &Plugin.HG.&Commit <Plug>HGCommit | ||||
amenu <silent> &Plugin.HG.&Diff <Plug>HGDiff | ||||
amenu <silent> &Plugin.HG.&Log <Plug>HGLog | ||||
amenu <silent> &Plugin.HG.Revert <Plug>HGRevert | ||||
amenu <silent> &Plugin.HG.&Review <Plug>HGReview | ||||
amenu <silent> &Plugin.HG.&Status <Plug>HGStatus | ||||
amenu <silent> &Plugin.HG.&Update <Plug>HGUpdate | ||||
amenu <silent> &Plugin.HG.&VimDiff <Plug>HGVimDiff | ||||
|
r2591 | |||
" Section: Autocommands to restore vimdiff state {{{1 | ||||
|
r2592 | function! s:HGVimDiffRestore(vimDiffBuff) | ||
let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1 | ||||
|
r2591 | try | ||
if exists("s:vimDiffSourceBuffer") | ||||
if a:vimDiffBuff == s:vimDiffSourceBuffer | ||||
" Original file is being removed. | ||||
unlet! s:vimDiffSourceBuffer | ||||
unlet! s:vimDiffBufferCount | ||||
unlet! s:vimDiffRestoreCmd | ||||
unlet! s:vimDiffScratchList | ||||
elseif match(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}') >= 0 | ||||
let s:vimDiffScratchList = substitute(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}', '', '') | ||||
let s:vimDiffBufferCount = s:vimDiffBufferCount - 1 | ||||
if s:vimDiffBufferCount == 1 && exists('s:vimDiffRestoreCmd') | ||||
" All scratch buffers are gone, reset the original. | ||||
" Only restore if the source buffer is still in Diff mode | ||||
let sourceWinNR=bufwinnr(s:vimDiffSourceBuffer) | ||||
if sourceWinNR != -1 | ||||
" The buffer is visible in at least one window | ||||
let currentWinNR = winnr() | ||||
while winbufnr(sourceWinNR) != -1 | ||||
if winbufnr(sourceWinNR) == s:vimDiffSourceBuffer | ||||
execute sourceWinNR . 'wincmd w' | ||||
if getwinvar('', "&diff") | ||||
execute s:vimDiffRestoreCmd | ||||
endif | ||||
endif | ||||
let sourceWinNR = sourceWinNR + 1 | ||||
endwhile | ||||
execute currentWinNR . 'wincmd w' | ||||
else | ||||
" The buffer is hidden. It must be visible in order to set the | ||||
" diff option. | ||||
let currentBufNR = bufnr('') | ||||
execute "hide buffer" s:vimDiffSourceBuffer | ||||
if getwinvar('', "&diff") | ||||
execute s:vimDiffRestoreCmd | ||||
endif | ||||
execute "hide buffer" currentBufNR | ||||
endif | ||||
unlet s:vimDiffRestoreCmd | ||||
unlet s:vimDiffSourceBuffer | ||||
unlet s:vimDiffBufferCount | ||||
unlet s:vimDiffScratchList | ||||
elseif s:vimDiffBufferCount == 0 | ||||
" All buffers are gone. | ||||
unlet s:vimDiffSourceBuffer | ||||
unlet s:vimDiffBufferCount | ||||
unlet s:vimDiffScratchList | ||||
endif | ||||
endif | ||||
endif | ||||
finally | ||||
|
r2592 | let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1 | ||
|
r2591 | endtry | ||
endfunction | ||||
|
r2592 | augroup HGVimDiffRestore | ||
|
r2591 | au! | ||
|
r2759 | au BufUnload * call <SID>HGVimDiffRestore(expand("<abuf>")) | ||
|
r2591 | augroup END | ||
" Section: Optional activation of buffer management {{{1 | ||||
|
r2607 | if s:HGGetOption('HGCommandEnableBufferSetup', 1) | ||
|
r2592 | call HGEnableBufferSetup() | ||
|
r2591 | endif | ||
|
r2603 | " Section: Doc installation {{{1 | ||
|
r2759 | if <SID>HGInstallDocumentation(expand("<sfile>:p")) | ||
echomsg s:script_name s:script_version . ": updated documentation" | ||||
endif | ||||
|
r2603 | |||
|
r2591 | " Section: Plugin completion {{{1 | ||
|
r2759 | " delete one-time vars and functions | ||
delfunction <SID>HGInstallDocumentation | ||||
delfunction <SID>HGFlexiMkdir | ||||
delfunction <SID>HGCleanupOnFailure | ||||
unlet s:script_version s:script_name | ||||
|
r3546 | let g:loaded_hgcommand=2 | ||
|
r2592 | silent do HGCommand User HGPluginFinish | ||
|
r2759 | |||
let &cpo = s:save_cpo | ||||
unlet s:save_cpo | ||||
|
r2592 | " vim:se expandtab sts=2 sw=2: | ||
|
r2603 | finish | ||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | ||||
" Section: Documentation content {{{1 | ||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | ||||
=== START_DOC | ||||
*hgcommand.txt* Mercurial vim integration #version# | ||||
HGCOMMAND REFERENCE MANUAL~ | ||||
Author: Mathieu Clabaut <mathieu.clabaut@gmail.com> | ||||
Credits: Bob Hiestand <bob.hiestand@gmail.com> | ||||
|
r8936 | Mercurial: http://mercurial.selenic.com/ | ||
|
r2603 | Mercurial (noted Hg) is a fast, lightweight Source Control Management | ||
system designed for efficient handling of very large distributed projects. | ||||
============================================================================== | ||||
|
r2604 | 1. Contents *hgcommand-contents* | ||
|
r2603 | |||
Installation : |hgcommand-install| | ||||
HGCommand Intro : |hgcommand| | ||||
HGCommand Manual : |hgcommand-manual| | ||||
Customization : |hgcommand-customize| | ||||
Bugs : |hgcommand-bugs| | ||||
============================================================================== | ||||
|
r2604 | 2. HGCommand Installation *hgcommand-install* | ||
|
r2603 | |||
|
r2759 | In order to install the plugin, place the hgcommand.vim file into a plugin' | ||
directory in your runtime path (please see |add-global-plugin| and | ||||
|
r2603 | |'runtimepath'|. | ||
|
r2759 | HGCommand may be customized by setting variables, creating maps, and | ||
|
r2603 | specifying event handlers. Please see |hgcommand-customize| for more | ||
details. | ||||
*hgcommand-auto-help* | ||||
|
r2759 | The help file is automagically generated when the |hgcommand| script is | ||
|
r2603 | loaded for the first time. | ||
============================================================================== | ||||
|
r2604 | 3. HGCommand Intro *hgcommand* | ||
*hgcommand-intro* | ||||
|
r2603 | |||
|
r2759 | The HGCommand plugin provides global ex commands for manipulating | ||
HG-controlled source files. In general, each command operates on the | ||||
current buffer and accomplishes a separate hg function, such as update, | ||||
|
r2604 | commit, log, and others (please see |hgcommand-commands| for a list of all | ||
|
r2759 | available commands). The results of each operation are displayed in a | ||
scratch buffer. Several buffer variables are defined for those scratch | ||||
|
r2604 | buffers (please see |hgcommand-buffer-variables|). | ||
|
r2603 | |||
|
r2759 | The notion of "current file" means either the current buffer, or, in the | ||
|
r2604 | case of a directory buffer, the file on the current line within the buffer. | ||
|
r2603 | |||
|
r2759 | For convenience, any HGCommand invoked on a HGCommand scratch buffer acts | ||
as though it was invoked on the original file and splits the screen so that | ||||
|
r2604 | the output appears in a new window. | ||
|
r2603 | |||
|
r2759 | Many of the commands accept revisions as arguments. By default, most | ||
operate on the most recent revision on the current branch if no revision is | ||||
|
r2604 | specified (though see |HGCommandInteractive| to prompt instead). | ||
|
r2603 | |||
|
r2759 | Each HGCommand is mapped to a key sequence starting with the <Leader> | ||
keystroke. The default mappings may be overridden by supplying different | ||||
mappings before the plugin is loaded, such as in the vimrc, in the standard | ||||
fashion for plugin mappings. For examples, please see | ||||
|
r2604 | |hgcommand-mappings-override|. | ||
|
r2603 | |||
|
r2759 | The HGCommand plugin may be configured in several ways. For more details, | ||
|
r2604 | please see |hgcommand-customize|. | ||
|
r2603 | |||
============================================================================== | ||||
|
r2604 | 4. HGCommand Manual *hgcommand-manual* | ||
|
r2603 | |||
|
r2604 | 4.1 HGCommand commands *hgcommand-commands* | ||
|
r2603 | |||
|
r2604 | HGCommand defines the following commands: | ||
|
r2603 | |||
|
r2604 | |:HGAdd| | ||
|:HGAnnotate| | ||||
|:HGCommit| | ||||
|:HGDiff| | ||||
|:HGGotoOriginal| | ||||
|:HGLog| | ||||
|:HGRevert| | ||||
|:HGReview| | ||||
|:HGStatus| | ||||
|:HGUpdate| | ||||
|:HGVimDiff| | ||||
|
r2603 | |||
|
r2604 | :HGAdd *:HGAdd* | ||
|
r2603 | |||
|
r2759 | This command performs "hg add" on the current file. Please note, this does | ||
|
r2604 | not commit the newly-added file. | ||
|
r2603 | |||
|
r2604 | :HGAnnotate *:HGAnnotate* | ||
|
r2603 | |||
|
r2759 | This command performs "hg annotate" on the current file. If an argument is | ||
given, the argument is used as a revision number to display. If not given | ||||
an argument, it uses the most recent version of the file on the current | ||||
branch. Additionally, if the current buffer is a HGAnnotate buffer | ||||
|
r2604 | already, the version number on the current line is used. | ||
|
r2603 | |||
|
r2759 | If the |HGCommandAnnotateParent| variable is set to a non-zero value, the | ||
version previous to the one on the current line is used instead. This | ||||
|
r2604 | allows one to navigate back to examine the previous version of a line. | ||
|
r2603 | |||
|
r2759 | The filetype of the HGCommand scratch buffer is set to 'HGAnnotate', to | ||
|
r2604 | take advantage of the bundled syntax file. | ||
|
r2603 | |||
|
r2604 | :HGCommit[!] *:HGCommit* | ||
|
r2603 | |||
|
r2759 | If called with arguments, this performs "hg commit" using the arguments as | ||
|
r2604 | the log message. | ||
|
r2603 | |||
|
r2604 | If '!' is used with no arguments, an empty log message is committed. | ||
|
r2603 | |||
|
r2759 | If called with no arguments, this is a two-step command. The first step | ||
opens a buffer to accept a log message. When that buffer is written, it is | ||||
automatically closed and the file is committed using the information from | ||||
that log message. The commit can be abandoned if the log message buffer is | ||||
|
r2604 | deleted or wiped before being written. | ||
|
r2603 | |||
|
r2759 | Alternatively, the mapping that is used to invoke :HGCommit (by default | ||
<Leader>hgc) can be used in the log message buffer to immediately commit. | ||||
This is useful if the |HGCommandCommitOnWrite| variable is set to 0 to | ||||
|
r2604 | disable the normal commit-on-write behavior. | ||
|
r2603 | |||
|
r2604 | :HGDiff *:HGDiff* | ||
|
r2759 | With no arguments, this performs "hg diff" on the current file against the | ||
|
r2604 | current repository version. | ||
|
r2603 | |||
|
r2759 | With one argument, "hg diff" is performed on the current file against the | ||
|
r2604 | specified revision. | ||
|
r2603 | |||
|
r2759 | With two arguments, hg diff is performed between the specified revisions of | ||
|
r2604 | the current file. | ||
|
r2603 | |||
|
r2759 | This command uses the 'HGCommandDiffOpt' variable to specify diff options. | ||
If that variable does not exist, then 'wbBc' is assumed. If you wish to | ||||
|
r2604 | have no options, then set it to the empty string. | ||
|
r2603 | |||
|
r2604 | :HGGotoOriginal *:HGGotoOriginal* | ||
|
r2603 | |||
|
r2759 | This command returns the current window to the source buffer, if the | ||
|
r2604 | current buffer is a HG command output buffer. | ||
|
r2603 | |||
:HGGotoOriginal! | ||||
|
r2759 | Like ":HGGotoOriginal" but also executes :bufwipeout on all HG command | ||
|
r2604 | output buffers for the source buffer. | ||
|
r2603 | |||
|
r2604 | :HGLog *:HGLog* | ||
|
r2603 | |||
|
r2604 | Performs "hg log" on the current file. | ||
|
r2603 | |||
|
r2759 | If an argument is given, it is passed as an argument to the "-r" option of | ||
|
r2604 | "hg log". | ||
|
r2603 | |||
|
r2604 | :HGRevert *:HGRevert* | ||
|
r2603 | |||
|
r2759 | Replaces the current file with the most recent version from the repository | ||
|
r2604 | in order to wipe out any undesired changes. | ||
|
r2759 | |||
|
r2604 | :HGReview *:HGReview* | ||
|
r2603 | |||
|
r2759 | Retrieves a particular version of the current file. If no argument is | ||
given, the most recent version of the file on the current branch is | ||||
|
r2604 | retrieved. Otherwise, the specified version is retrieved. | ||
|
r2603 | |||
|
r2604 | :HGStatus *:HGStatus* | ||
|
r2603 | |||
|
r2604 | Performs "hg status" on the current file. | ||
|
r2603 | |||
|
r2604 | :HGUpdate *:HGUpdate* | ||
|
r2603 | |||
|
r2759 | Performs "hg update" on the current file. This intentionally does not | ||
automatically reload the current buffer, though vim should prompt the user | ||||
|
r2604 | to do so if the underlying file is altered by this command. | ||
|
r2603 | |||
|
r2604 | :HGVimDiff *:HGVimDiff* | ||
|
r2603 | |||
|
r2759 | With no arguments, this prompts the user for a revision and then uses | ||
vimdiff to display the differences between the current file and the | ||||
specified revision. If no revision is specified, the most recent version | ||||
|
r2604 | of the file on the current branch is used. | ||
|
r2603 | |||
|
r2759 | With one argument, that argument is used as the revision as above. With | ||
two arguments, the differences between the two revisions is displayed using | ||||
|
r2604 | vimdiff. | ||
|
r2603 | |||
|
r2759 | With either zero or one argument, the original buffer is used to perform | ||
the vimdiff. When the other buffer is closed, the original buffer will be | ||||
|
r2604 | returned to normal mode. | ||
|
r2603 | |||
|
r2759 | Once vimdiff mode is started using the above methods, additional vimdiff | ||
buffers may be added by passing a single version argument to the command. | ||||
|
r2604 | There may be up to 4 vimdiff buffers total. | ||
|
r2603 | |||
|
r2759 | Using the 2-argument form of the command resets the vimdiff to only those 2 | ||
versions. Additionally, invoking the command on a different file will | ||||
|
r2604 | close the previous vimdiff buffers. | ||
|
r2603 | |||
|
r2604 | 4.2 Mappings *hgcommand-mappings* | ||
|
r2603 | |||
|
r2759 | By default, a mapping is defined for each command. These mappings execute | ||
|
r2604 | the default (no-argument) form of each command. | ||
|
r2603 | |||
|
r2604 | <Leader>hga HGAdd | ||
<Leader>hgn HGAnnotate | ||||
<Leader>hgc HGCommit | ||||
<Leader>hgd HGDiff | ||||
<Leader>hgg HGGotoOriginal | ||||
<Leader>hgG HGGotoOriginal! | ||||
<Leader>hgl HGLog | ||||
<Leader>hgr HGReview | ||||
<Leader>hgs HGStatus | ||||
<Leader>hgu HGUpdate | ||||
<Leader>hgv HGVimDiff | ||||
|
r2603 | |||
|
r2604 | *hgcommand-mappings-override* | ||
|
r2603 | |||
|
r17424 | The default mappings can be overridden by user-provided instead by mapping | ||
|
r2759 | to <Plug>CommandName. This is especially useful when these mappings | ||
collide with other existing mappings (vim will warn of this during plugin | ||||
|
r2604 | initialization, but will not clobber the existing mappings). | ||
|
r2603 | |||
|
r2759 | For instance, to override the default mapping for :HGAdd to set it to | ||
|
r2604 | '\add', add the following to the vimrc: > | ||
|
r2603 | |||
|
r2604 | nmap \add <Plug>HGAdd | ||
< | ||||
4.3 Automatic buffer variables *hgcommand-buffer-variables* | ||||
|
r2603 | |||
|
r2759 | Several buffer variables are defined in each HGCommand result buffer. | ||
These may be useful for additional customization in callbacks defined in | ||||
|
r2604 | the event handlers (please see |hgcommand-events|). | ||
|
r2603 | |||
|
r2604 | The following variables are automatically defined: | ||
|
r2603 | |||
|
r2604 | b:hgOrigBuffNR *b:hgOrigBuffNR* | ||
|
r2603 | |||
|
r2604 | This variable is set to the buffer number of the source file. | ||
|
r2603 | |||
|
r2604 | b:hgcmd *b:hgcmd* | ||
|
r2603 | |||
|
r2759 | This variable is set to the name of the hg command that created the result | ||
|
r2604 | buffer. | ||
|
r2603 | ============================================================================== | ||
|
r2604 | 5. Configuration and customization *hgcommand-customize* | ||
*hgcommand-config* | ||||
|
r2603 | |||
|
r2759 | The HGCommand plugin can be configured in two ways: by setting | ||
configuration variables (see |hgcommand-options|) or by defining HGCommand | ||||
event handlers (see |hgcommand-events|). Additionally, the HGCommand | ||||
plugin provides several option for naming the HG result buffers (see | ||||
|hgcommand-naming|) and supported a customized status line (see | ||||
|
r2604 | |hgcommand-statusline| and |hgcommand-buffer-management|). | ||
|
r2603 | |||
|
r2604 | 5.1 HGCommand configuration variables *hgcommand-options* | ||
|
r2603 | |||
|
r2759 | Several variables affect the plugin's behavior. These variables are | ||
checked at time of execution, and may be defined at the window, buffer, or | ||||
|
r2604 | global level and are checked in that order of precedence. | ||
|
r2603 | |||
|
r2604 | The following variables are available: | ||
|
r2603 | |||
|
r2604 | |HGCommandAnnotateParent| | ||
|HGCommandCommitOnWrite| | ||||
|HGCommandHGExec| | ||||
|HGCommandDeleteOnHide| | ||||
|HGCommandDiffOpt| | ||||
|HGCommandDiffSplit| | ||||
|HGCommandEdit| | ||||
|HGCommandEnableBufferSetup| | ||||
|HGCommandInteractive| | ||||
|HGCommandNameMarker| | ||||
|HGCommandNameResultBuffers| | ||||
|HGCommandSplit| | ||||
HGCommandAnnotateParent *HGCommandAnnotateParent* | ||||
|
r2603 | |||
|
r2759 | This variable, if set to a non-zero value, causes the zero-argument form of | ||
HGAnnotate when invoked on a HGAnnotate buffer to go to the version | ||||
previous to that displayed on the current line. If not set, it defaults to | ||||
|
r2604 | 0. | ||
|
r2603 | |||
|
r2604 | HGCommandCommitOnWrite *HGCommandCommitOnWrite* | ||
|
r2603 | |||
|
r2759 | This variable, if set to a non-zero value, causes the pending hg commit to | ||
take place immediately as soon as the log message buffer is written. If | ||||
set to zero, only the HGCommit mapping will cause the pending commit to | ||||
|
r2604 | occur. If not set, it defaults to 1. | ||
|
r2603 | |||
|
r2604 | HGCommandHGExec *HGCommandHGExec* | ||
|
r2603 | |||
|
r2759 | This variable controls the executable used for all HG commands. If not | ||
|
r2604 | set, it defaults to "hg". | ||
|
r2603 | |||
|
r2604 | HGCommandDeleteOnHide *HGCommandDeleteOnHide* | ||
|
r2603 | |||
|
r2759 | This variable, if set to a non-zero value, causes the temporary HG result | ||
|
r2604 | buffers to automatically delete themselves when hidden. | ||
|
r2603 | |||
|
r2604 | HGCommandDiffOpt *HGCommandDiffOpt* | ||
|
r2603 | |||
|
r2759 | This variable, if set, determines the options passed to the diff command of | ||
|
r2604 | HG. If not set, it defaults to 'w'. | ||
|
r2603 | |||
|
r2604 | HGCommandDiffSplit *HGCommandDiffSplit* | ||
|
r2603 | |||
|
r2759 | This variable overrides the |HGCommandSplit| variable, but only for buffers | ||
|
r2604 | created with |:HGVimDiff|. | ||
|
r2603 | |||
|
r2604 | HGCommandEdit *HGCommandEdit* | ||
|
r2603 | |||
|
r2759 | This variable controls whether the original buffer is replaced ('edit') or | ||
|
r2604 | split ('split'). If not set, it defaults to 'edit'. | ||
|
r2603 | |||
|
r2604 | HGCommandEnableBufferSetup *HGCommandEnableBufferSetup* | ||
|
r2603 | |||
|
r2759 | This variable, if set to a non-zero value, activates HG buffer management | ||
mode see (|hgcommand-buffer-management|). This mode means that three | ||||
buffer variables, 'HGRepository', 'HGRevision' and 'HGBranch', are set if | ||||
the file is HG-controlled. This is useful for displaying version | ||||
|
r2604 | information in the status bar. | ||
|
r2603 | |||
|
r2604 | HGCommandInteractive *HGCommandInteractive* | ||
|
r2603 | |||
|
r2759 | This variable, if set to a non-zero value, causes appropriate commands (for | ||
the moment, only |:HGReview|) to query the user for a revision to use | ||||
|
r2604 | instead of the current revision if none is specified. | ||
|
r2603 | |||
|
r2604 | HGCommandNameMarker *HGCommandNameMarker* | ||
|
r2603 | |||
|
r2759 | This variable, if set, configures the special attention-getting characters | ||
that appear on either side of the hg buffer type in the buffer name. This | ||||
has no effect unless |HGCommandNameResultBuffers| is set to a true value. | ||||
If not set, it defaults to '_'. | ||||
|
r2603 | |||
|
r2604 | HGCommandNameResultBuffers *HGCommandNameResultBuffers* | ||
|
r2603 | |||
|
r2759 | This variable, if set to a true value, causes the hg result buffers to be | ||
named in the old way ('<source file name> _<hg command>_'). If not set or | ||||
|
r2604 | set to a false value, the result buffer is nameless. | ||
|
r2603 | |||
|
r2604 | HGCommandSplit *HGCommandSplit* | ||
|
r2603 | |||
|
r2759 | This variable controls the orientation of the various window splits that | ||
may occur (such as with HGVimDiff, when using a HG command on a HG command | ||||
buffer, or when the |HGCommandEdit| variable is set to 'split'. If set to | ||||
'horizontal', the resulting windows will be on stacked on top of one | ||||
another. If set to 'vertical', the resulting windows will be side-by-side. | ||||
|
r2604 | If not set, it defaults to 'horizontal' for all but HGVimDiff windows. | ||
|
r2603 | |||
|
r2604 | 5.2 HGCommand events *hgcommand-events* | ||
|
r2603 | |||
|
r2759 | For additional customization, HGCommand can trigger user-defined events. | ||
Event handlers are provided by defining User event autocommands (see | ||||
|autocommand|, |User|) in the HGCommand group with patterns matching the | ||||
|
r2604 | event name. | ||
|
r2603 | |||
|
r2759 | For instance, the following could be added to the vimrc to provide a 'q' | ||
|
r2604 | mapping to quit a HGCommand scratch buffer: > | ||
|
r2603 | |||
|
r2604 | augroup HGCommand | ||
au HGCommand User HGBufferCreated silent! nmap <unique> <buffer> q: | ||||
bwipeout<cr> | ||||
augroup END | ||||
< | ||||
The following hooks are available: | ||||
|
r2603 | |||
|
r2604 | HGBufferCreated This event is fired just after a hg command result | ||
|
r2759 | buffer is created and filled with the result of a hg | ||
command. It is executed within the context of the HG | ||||
command buffer. The HGCommand buffer variables may be | ||||
useful for handlers of this event (please see | ||||
|
r2604 | |hgcommand-buffer-variables|). | ||
|
r2603 | |||
|
r2604 | HGBufferSetup This event is fired just after HG buffer setup occurs, | ||
if enabled. | ||||
|
r2603 | |||
|
r2604 | HGPluginInit This event is fired when the HGCommand plugin first | ||
loads. | ||||
|
r2603 | |||
|
r2604 | HGPluginFinish This event is fired just after the HGCommand plugin | ||
loads. | ||||
|
r2603 | |||
|
r2604 | HGVimDiffFinish This event is fired just after the HGVimDiff command | ||
|
r2759 | executes to allow customization of, for instance, | ||
|
r2604 | window placement and focus. | ||
|
r2603 | |||
|
r2604 | 5.3 HGCommand buffer naming *hgcommand-naming* | ||
|
r2603 | |||
|
r2759 | By default, the buffers containing the result of HG commands are nameless | ||
scratch buffers. It is intended that buffer variables of those buffers be | ||||
used to customize the statusline option so that the user may fully control | ||||
|
r2604 | the display of result buffers. | ||
|
r2759 | If the old-style naming is desired, please enable the | ||
|HGCommandNameResultBuffers| variable. Then, each result buffer will | ||||
receive a unique name that includes the source file name, the HG command, | ||||
and any extra data (such as revision numbers) that were part of the | ||||
|
r2604 | command. | ||
|
r2603 | |||
5.4 HGCommand status line support *hgcommand-statusline* | ||||
|
r2759 | It is intended that the user will customize the |'statusline'| option to | ||
include HG result buffer attributes. A sample function that may be used in | ||||
the |'statusline'| option is provided by the plugin, HGGetStatusLine(). In | ||||
order to use that function in the status line, do something like the | ||||
|
r2604 | following: > | ||
set statusline=%<%f\ %{HGGetStatusLine()}\ %h%m%r%=%l,%c%V\ %P | ||||
< | ||||
of which %{HGGetStatusLine()} is the relevant portion. | ||||
|
r2603 | |||
|
r2759 | The sample HGGetStatusLine() function handles both HG result buffers and | ||
HG-managed files if HGCommand buffer management is enabled (please see | ||||
|
r2604 | |hgcommand-buffer-management|). | ||
|
r2603 | |||
|
r2604 | 5.5 HGCommand buffer management *hgcommand-buffer-management* | ||
|
r2603 | |||
|
r2759 | The HGCommand plugin can operate in buffer management mode, which means | ||
that it attempts to set two buffer variables ('HGRevision' and 'HGBranch') | ||||
upon entry into a buffer. This is rather slow because it means that 'hg | ||||
status' will be invoked at each entry into a buffer (during the |BufEnter| | ||||
|
r2604 | autocommand). | ||
|
r2603 | |||
|
r2759 | This mode is enabled by default. In order to disable it, set the | ||
|HGCommandEnableBufferSetup| variable to a false (zero) value. Enabling | ||||
this mode simply provides the buffer variables mentioned above. The user | ||||
must explicitly include those in the |'statusline'| option if they are to | ||||
|
r2604 | appear in the status line (but see |hgcommand-statusline| for a simple way | ||
to do that). | ||||
============================================================================== | ||||
9. Tips *hgcommand-tips* | ||||
9.1 Split window annotation, by Michael Anderson > | ||||
|
r2603 | |||
|
r2604 | :nmap <Leader>hgN :vs<CR><C-w>h<Leader>hgn:vertical res 40<CR> | ||
\ggdddd:set scb<CR>:set nowrap<CR><C-w>lgg:set scb<CR> | ||||
\:set nowrap<CR> | ||||
< | ||||
|
r2603 | |||
|
r2759 | This splits the buffer vertically, puts an annotation on the left (minus | ||
the header) with the width set to 40. An editable/normal copy is placed on | ||||
the right. The two versions are scroll locked so they move as one. and | ||||
wrapping is turned off so that the lines line up correctly. The advantages | ||||
|
r2604 | are... | ||
1) You get a versioning on the right. | ||||
2) You can still edit your own code. | ||||
3) Your own code still has syntax highlighting. | ||||
|
r2603 | |||
============================================================================== | ||||
|
r2604 | 8. Known bugs *hgcommand-bugs* | ||
|
r2603 | |||
|
r2604 | Please let me know if you run across any. | ||
|
r2603 | |||
|
r2759 | HGVimDiff, when using the original (real) source buffer as one of the diff | ||
buffers, uses some hacks to try to restore the state of the original buffer | ||||
when the scratch buffer containing the other version is destroyed. There | ||||
|
r2604 | may still be bugs in here, depending on many configuration details. | ||
|
r2603 | |||
============================================================================== | ||||
|
r2637 | |||
9. TODO *hgcommand-todo* | ||||
Integrate symlink tracking once HG will support them. | ||||
============================================================================== | ||||
|
r2603 | === END_DOC | ||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | ||||
" v im:tw=78:ts=8:ft=help:norl: | ||||
" vim600: set foldmethod=marker tabstop=8 shiftwidth=2 softtabstop=2 smartindent smarttab : | ||||
|
r2759 | "fileencoding=iso-8859-15 | ||