1" vim600: set foldmethod=marker: 2" 3" Vim plugin to assist in working with HG-controlled files. 4" 5" Last Change: 2006/02/22 6" Version: 1.76 7" Maintainer: Mathieu Clabaut <mathieu.clabaut@gmail.com> 8" License: This file is placed in the public domain. 9" Credits: 10" Bob Hiestand <bob.hiestand@gmail.com> for the fabulous 11" cvscommand.vim from which this script was directly created by 12" means of sed commands and minor tweaks. 13 14""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 15" 16" Section: Documentation 17"---------------------------- 18" 19" Documentation should be available by ":help hgcommand" command, once the 20" script has been copied in you .vim/plugin directory. 21" 22" You still can read the documentation at the end of this file. Locate it by 23" searching the "hgcommand-contents" string (and set ft=help to have 24" appropriate syntaxic coloration). 25 26" Section: Plugin header {{{1 27 28" loaded_hgcommand is set to 1 when the initialization begins, and 2 when it 29" completes. This allows various actions to only be taken by functions after 30" system initialization. 31 32if exists("loaded_hgcommand") 33 finish 34endif 35let loaded_hgcommand = 1 36 37if v:version < 602 38 echohl WarningMsg|echomsg "HGCommand 1.69 or later requires VIM 6.2 or later"|echohl None 39 finish 40endif 41 42" Section: Event group setup {{{1 43 44augroup HGCommand 45augroup END 46 47" Section: Plugin initialization {{{1 48silent do HGCommand User HGPluginInit 49 50" Section: Script variable initialization {{{1 51 52let s:HGCommandEditFileRunning = 0 53unlet! s:vimDiffRestoreCmd 54unlet! s:vimDiffSourceBuffer 55unlet! s:vimDiffBufferCount 56unlet! s:vimDiffScratchList 57 58" Section: Utility functions {{{1 59 60" Function: s:HGResolveLink() {{{2 61" Fully resolve the given file name to remove shortcuts or symbolic links. 62 63function! s:HGResolveLink(fileName) 64 let resolved = resolve(a:fileName) 65 if resolved != a:fileName 66 let resolved = s:HGResolveLink(resolved) 67 endif 68 return resolved 69endfunction 70 71" Function: s:HGChangeToCurrentFileDir() {{{2 72" Go to the directory in which the current HG-controlled file is located. 73" If this is a HG command buffer, first switch to the original file. 74 75function! s:HGChangeToCurrentFileDir(fileName) 76 let oldCwd=getcwd() 77 let fileName=s:HGResolveLink(a:fileName) 78 let newCwd=fnamemodify(fileName, ':h') 79 if strlen(newCwd) > 0 80 execute 'cd' escape(newCwd, ' ') 81 endif 82 return oldCwd 83endfunction 84 85" Function: s:HGGetOption(name, default) {{{2 86" Grab a user-specified option to override the default provided. Options are 87" searched in the window, buffer, then global spaces. 88 89function! s:HGGetOption(name, default) 90 if exists("s:" . a:name . "Override") 91 execute "return s:".a:name."Override" 92 elseif exists("w:" . a:name) 93 execute "return w:".a:name 94 elseif exists("b:" . a:name) 95 execute "return b:".a:name 96 elseif exists("g:" . a:name) 97 execute "return g:".a:name 98 else 99 return a:default 100 endif 101endfunction 102 103" Function: s:HGEditFile(name, origBuffNR) {{{2 104" Wrapper around the 'edit' command to provide some helpful error text if the 105" current buffer can't be abandoned. If name is provided, it is used; 106" otherwise, a nameless scratch buffer is used. 107" Returns: 0 if successful, -1 if an error occurs. 108 109function! s:HGEditFile(name, origBuffNR) 110 "Name parameter will be pasted into expression. 111 let name = escape(a:name, ' *?\') 112 113 let editCommand = s:HGGetOption('HGCommandEdit', 'edit') 114 if editCommand != 'edit' 115 if s:HGGetOption('HGCommandSplit', 'horizontal') == 'horizontal' 116 if name == "" 117 let editCommand = 'rightbelow new' 118 else 119 let editCommand = 'rightbelow split ' . name 120 endif 121 else 122 if name == "" 123 let editCommand = 'vert rightbelow new' 124 else 125 let editCommand = 'vert rightbelow split ' . name 126 endif 127 endif 128 else 129 if name == "" 130 let editCommand = 'enew' 131 else 132 let editCommand = 'edit ' . name 133 endif 134 endif 135 136 " Protect against useless buffer set-up 137 let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1 138 try 139 execute editCommand 140 finally 141 let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1 142 endtry 143 144 let b:HGOrigBuffNR=a:origBuffNR 145 let b:HGCommandEdit='split' 146endfunction 147 148" Function: s:HGCreateCommandBuffer(cmd, cmdName, statusText, filename) {{{2 149" Creates a new scratch buffer and captures the output from execution of the 150" given command. The name of the scratch buffer is returned. 151 152function! s:HGCreateCommandBuffer(cmd, cmdName, statusText, origBuffNR) 153 let fileName=bufname(a:origBuffNR) 154 155 let resultBufferName='' 156 157 if s:HGGetOption("HGCommandNameResultBuffers", 0) 158 let nameMarker = s:HGGetOption("HGCommandNameMarker", '_') 159 if strlen(a:statusText) > 0 160 let bufName=a:cmdName . ' -- ' . a:statusText 161 else 162 let bufName=a:cmdName 163 endif 164 let bufName=fileName . ' ' . nameMarker . bufName . nameMarker 165 let counter=0 166 let resultBufferName = bufName 167 while buflisted(resultBufferName) 168 let counter=counter + 1 169 let resultBufferName=bufName . ' (' . counter . ')' 170 endwhile 171 endif 172 173 let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " " . a:cmd 174 echomsg "DBG :".hgCommand 175 let hgOut = system(hgCommand) 176 " HACK: diff command does not return proper error codes 177 if v:shell_error && a:cmdName != 'hgdiff' 178 if strlen(hgOut) == 0 179 echoerr "HG command failed" 180 else 181 echoerr "HG command failed: " . hgOut 182 endif 183 return -1 184 endif 185 if strlen(hgOut) == 0 186 " Handle case of no output. In this case, it is important to check the 187 " file status, especially since hg edit/unedit may change the attributes 188 " of the file with no visible output. 189 190 echomsg "No output from HG command" 191 checktime 192 return -1 193 endif 194 195 if s:HGEditFile(resultBufferName, a:origBuffNR) == -1 196 return -1 197 endif 198 199 set buftype=nofile 200 set noswapfile 201 set filetype= 202 203 if s:HGGetOption("HGCommandDeleteOnHide", 0) 204 set bufhidden=delete 205 endif 206 207 silent 0put=hgOut 208 209 " The last command left a blank line at the end of the buffer. If the 210 " last line is folded (a side effect of the 'put') then the attempt to 211 " remove the blank line will kill the last fold. 212 " 213 " This could be fixed by explicitly detecting whether the last line is 214 " within a fold, but I prefer to simply unfold the result buffer altogether. 215 216 if has('folding') 217 normal zR 218 endif 219 220 $d 221 1 222 223 " Define the environment and execute user-defined hooks. 224 225 let b:HGSourceFile=fileName 226 let b:HGCommand=a:cmdName 227 if a:statusText != "" 228 let b:HGStatusText=a:statusText 229 endif 230 231 silent do HGCommand User HGBufferCreated 232 return bufnr("%") 233endfunction 234 235" Function: s:HGBufferCheck(hgBuffer) {{{2 236" Attempts to locate the original file to which HG operations were applied 237" for a given buffer. 238 239function! s:HGBufferCheck(hgBuffer) 240 let origBuffer = getbufvar(a:hgBuffer, "HGOrigBuffNR") 241 if origBuffer 242 if bufexists(origBuffer) 243 return origBuffer 244 else 245 " Original buffer no longer exists. 246 return -1 247 endif 248 else 249 " No original buffer 250 return a:hgBuffer 251 endif 252endfunction 253 254" Function: s:HGCurrentBufferCheck() {{{2 255" Attempts to locate the original file to which HG operations were applied 256" for the current buffer. 257 258function! s:HGCurrentBufferCheck() 259 return s:HGBufferCheck(bufnr("%")) 260endfunction 261 262" Function: s:HGToggleDeleteOnHide() {{{2 263" Toggles on and off the delete-on-hide behavior of HG buffers 264 265function! s:HGToggleDeleteOnHide() 266 if exists("g:HGCommandDeleteOnHide") 267 unlet g:HGCommandDeleteOnHide 268 else 269 let g:HGCommandDeleteOnHide=1 270 endif 271endfunction 272 273" Function: s:HGDoCommand(hgcmd, cmdName, statusText) {{{2 274" General skeleton for HG function execution. 275" Returns: name of the new command buffer containing the command results 276 277function! s:HGDoCommand(cmd, cmdName, statusText) 278 let hgBufferCheck=s:HGCurrentBufferCheck() 279 if hgBufferCheck == -1 280 echo "Original buffer no longer exists, aborting." 281 return -1 282 endif 283 284 let fileName=bufname(hgBufferCheck) 285 if isdirectory(fileName) 286 let fileName=fileName . "/" . getline(".") 287 endif 288 let realFileName = fnamemodify(s:HGResolveLink(fileName), ':t') 289 let oldCwd=s:HGChangeToCurrentFileDir(fileName) 290 try 291 " TODO 292 "if !filereadable('HG/Root') 293 "throw fileName . ' is not a HG-controlled file.' 294 "endif 295 let fullCmd = a:cmd . ' "' . realFileName . '"' 296 "echomsg "DEBUG".fullCmd 297 let resultBuffer=s:HGCreateCommandBuffer(fullCmd, a:cmdName, a:statusText, hgBufferCheck) 298 return resultBuffer 299 catch 300 echoerr v:exception 301 return -1 302 finally 303 execute 'cd' escape(oldCwd, ' ') 304 endtry 305endfunction 306 307 308" Function: s:HGGetStatusVars(revision, branch, repository) {{{2 309" 310" Obtains a HG revision number and branch name. The 'revisionVar', 311" 'branchVar'and 'repositoryVar' arguments, if non-empty, contain the names of variables to hold 312" the corresponding results. 313" 314" Returns: string to be exec'd that sets the multiple return values. 315 316function! s:HGGetStatusVars(revisionVar, branchVar, repositoryVar) 317 let hgBufferCheck=s:HGCurrentBufferCheck() 318 if hgBufferCheck == -1 319 return "" 320 endif 321 let fileName=bufname(hgBufferCheck) 322 let realFileName = fnamemodify(s:HGResolveLink(fileName), ':t') 323 let oldCwd=s:HGChangeToCurrentFileDir(fileName) 324 try 325 ""TODO 326 "if !filereadable('HG/Root') 327 "return "" 328 "endif 329 let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " status -mardui " . fileName 330 let statustext=system(hgCommand) 331 if(v:shell_error) 332 return "" 333 endif 334 if match(statustext, '^[?I]') >= 0 335 let revision="NEW" 336 elseif match(statustext, '^[R]') >= 0 337 let revision="REMOVED" 338 elseif match(statustext, '^[D]') >= 0 339 let revision="DELETED" 340 elseif match(statustext, '^[A]') >= 0 341 let revision="ADDED" 342 endif 343 344 let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " parents -b " 345 let statustext=system(hgCommand) 346 if(v:shell_error) 347 return "" 348 endif 349 if exists('revision') 350 let returnExpression = "let " . a:revisionVar . "='" . revision . "'" 351 else 352 let revision=substitute(statustext, '^changeset:\s*\(\d\+\):.*\_$\_.*$', '\1', "") 353 let returnExpression = "let " . a:revisionVar . "='" . revision . "'" 354 endif 355 356 if a:branchVar != "" && match(statustext, '^\_.*\_^branch:') >= 0 357 let branch=substitute(statustext, '^\_.*\_^branch:\s*\(\S\+\)\n\_.*$', '\1', "") 358 let returnExpression=returnExpression . " | let " . a:branchVar . "='" . branch . "'" 359 endif 360 if a:repositoryVar != "" 361 let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " root " 362 let roottext=system(hgCommand) 363 let repository=substitute(roottext,'^.*/\([^/\n\r]*\)\n\_.*$','\1','') 364 let returnExpression=returnExpression . " | let " . a:repositoryVar . "='" . repository . "'" 365 endif 366 367 368 369 return returnExpression 370 finally 371 execute 'cd' escape(oldCwd, ' ') 372 endtry 373endfunction 374 375" Function: s:HGSetupBuffer() {{{2 376" Attempts to set the b:HGBranch, b:HGRevision and b:HGRepository variables. 377 378function! s:HGSetupBuffer() 379 if (exists("b:HGBufferSetup") && b:HGBufferSetup) 380 " This buffer is already set up. 381 return 382 endif 383 384 if !s:HGGetOption("HGCommandEnableBufferSetup", 0) 385 \ || @% == "" 386 \ || s:HGCommandEditFileRunning > 0 387 \ || exists("b:HGOrigBuffNR") 388 unlet! b:HGRevision 389 unlet! b:HGBranch 390 unlet! b:HGRepository 391 return 392 endif 393 394 if !filereadable(expand("%")) 395 return -1 396 endif 397 398 let revision="" 399 let branch="" 400 let repository="" 401 402 exec s:HGGetStatusVars('revision', 'branch', 'repository') 403 "echomsg "DBG ".revision."#".branch."#".repository 404 if revision != "" 405 let b:HGRevision=revision 406 else 407 unlet! b:HGRevision 408 endif 409 if branch != "" 410 let b:HGBranch=branch 411 else 412 unlet! b:HGBranch 413 endif 414 if repository != "" 415 let b:HGRepository=repository 416 else 417 unlet! b:HGRepository 418 endif 419 silent do HGCommand User HGBufferSetup 420 let b:HGBufferSetup=1 421endfunction 422 423" Function: s:HGMarkOrigBufferForSetup(hgbuffer) {{{2 424" Resets the buffer setup state of the original buffer for a given HG buffer. 425" Returns: The HG buffer number in a passthrough mode. 426 427function! s:HGMarkOrigBufferForSetup(hgBuffer) 428 checktime 429 if a:hgBuffer != -1 430 let origBuffer = s:HGBufferCheck(a:hgBuffer) 431 "This should never not work, but I'm paranoid 432 if origBuffer != a:hgBuffer 433 call setbufvar(origBuffer, "HGBufferSetup", 0) 434 endif 435 endif 436 return a:hgBuffer 437endfunction 438 439" Function: s:HGOverrideOption(option, [value]) {{{2 440" Provides a temporary override for the given HG option. If no value is 441" passed, the override is disabled. 442 443function! s:HGOverrideOption(option, ...) 444 if a:0 == 0 445 unlet! s:{a:option}Override 446 else 447 let s:{a:option}Override = a:1 448 endif 449endfunction 450 451" Function: s:HGWipeoutCommandBuffers() {{{2 452" Clears all current HG buffers of the specified type for a given source. 453 454function! s:HGWipeoutCommandBuffers(originalBuffer, hgCommand) 455 let buffer = 1 456 while buffer <= bufnr('$') 457 if getbufvar(buffer, 'HGOrigBuffNR') == a:originalBuffer 458 if getbufvar(buffer, 'HGCommand') == a:hgCommand 459 execute 'bw' buffer 460 endif 461 endif 462 let buffer = buffer + 1 463 endwhile 464endfunction 465 466" Function: s:HGInstallDocumentation(full_name, revision) {{{2 467" Install help documentation. 468" Arguments: 469" full_name: Full name of this vim plugin script, including path name. 470" revision: Revision of the vim script. #version# mark in the document file 471" will be replaced with this string with 'v' prefix. 472" Return: 473" 1 if new document installed, 0 otherwise. 474" Note: Cleaned and generalized by guo-peng Wen 475"''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 476 477function! s:HGInstallDocumentation(full_name, revision) 478 " Name of the document path based on the system we use: 479 if (has("unix")) 480 " On UNIX like system, using forward slash: 481 let l:slash_char = '/' 482 let l:mkdir_cmd = ':silent !mkdir -p ' 483 else 484 " On M$ system, use backslash. Also mkdir syntax is different. 485 " This should only work on W2K and up. 486 let l:slash_char = '\' 487 let l:mkdir_cmd = ':silent !mkdir ' 488 endif 489 490 let l:doc_path = l:slash_char . 'doc' 491 let l:doc_home = l:slash_char . '.vim' . l:slash_char . 'doc' 492 493 " Figure out document path based on full name of this script: 494 let l:vim_plugin_path = fnamemodify(a:full_name, ':h') 495 let l:vim_doc_path = fnamemodify(a:full_name, ':h:h') . l:doc_path 496 if (!(filewritable(l:vim_doc_path) == 2)) 497 echomsg "Doc path: " . l:vim_doc_path 498 execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' 499 if (!(filewritable(l:vim_doc_path) == 2)) 500 " Try a default configuration in user home: 501 let l:vim_doc_path = expand("~") . l:doc_home 502 if (!(filewritable(l:vim_doc_path) == 2)) 503 execute l:mkdir_cmd . '"' . l:vim_doc_path . '"' 504 if (!(filewritable(l:vim_doc_path) == 2)) 505 " Put a warning: 506 echomsg "Unable to open documentation directory" 507 echomsg " type :help add-local-help for more informations." 508 return 0 509 endif 510 endif 511 endif 512 endif 513 514 " Exit if we have problem to access the document directory: 515 if (!isdirectory(l:vim_plugin_path) 516 \ || !isdirectory(l:vim_doc_path) 517 \ || filewritable(l:vim_doc_path) != 2) 518 return 0 519 endif 520 521 " Full name of script and documentation file: 522 let l:script_name = fnamemodify(a:full_name, ':t') 523 let l:doc_name = fnamemodify(a:full_name, ':t:r') . '.txt' 524 let l:plugin_file = l:vim_plugin_path . l:slash_char . l:script_name 525 let l:doc_file = l:vim_doc_path . l:slash_char . l:doc_name 526 527 " Bail out if document file is still up to date: 528 if (filereadable(l:doc_file) && 529 \ getftime(l:plugin_file) < getftime(l:doc_file)) 530 return 0 531 endif 532 533 " Prepare window position restoring command: 534 if (strlen(@%)) 535 let l:go_back = 'b ' . bufnr("%") 536 else 537 let l:go_back = 'enew!' 538 endif 539 540 " Create a new buffer & read in the plugin file (me): 541 setl nomodeline 542 exe 'enew!' 543 exe 'r ' . l:plugin_file 544 545 setl modeline 546 let l:buf = bufnr("%") 547 setl noswapfile modifiable 548 549 norm zR 550 norm gg 551 552 " Delete from first line to a line starts with 553 " === START_DOC 554 1,/^=\{3,}\s\+START_DOC\C/ d 555 556 " Delete from a line starts with 557 " === END_DOC 558 " to the end of the documents: 559 /^=\{3,}\s\+END_DOC\C/,$ d 560 561 " Remove fold marks: 562 %s/{\{3}[1-9]/ / 563 564 " Add modeline for help doc: the modeline string is mangled intentionally 565 " to avoid it be recognized by VIM: 566 call append(line('$'), '') 567 call append(line('$'), ' v' . 'im:tw=78:ts=8:ft=help:norl:') 568 569 " Replace revision: 570 exe "normal :1s/#version#/ v" . a:revision . "/\<CR>" 571 572 " Save the help document: 573 exe 'w! ' . l:doc_file 574 exe l:go_back 575 exe 'bw ' . l:buf 576 577 " Build help tags: 578 exe 'helptags ' . l:vim_doc_path 579 580 return 1 581endfunction 582 583" Section: Public functions {{{1 584 585" Function: HGGetRevision() {{{2 586" Global function for retrieving the current buffer's HG revision number. 587" Returns: Revision number or an empty string if an error occurs. 588 589function! HGGetRevision() 590 let revision="" 591 exec s:HGGetStatusVars('revision', '', '') 592 return revision 593endfunction 594 595" Function: HGDisableBufferSetup() {{{2 596" Global function for deactivating the buffer autovariables. 597 598function! HGDisableBufferSetup() 599 let g:HGCommandEnableBufferSetup=0 600 silent! augroup! HGCommandPlugin 601endfunction 602 603" Function: HGEnableBufferSetup() {{{2 604" Global function for activating the buffer autovariables. 605 606function! HGEnableBufferSetup() 607 let g:HGCommandEnableBufferSetup=1 608 augroup HGCommandPlugin 609 au! 610 au BufEnter * call s:HGSetupBuffer() 611 augroup END 612 613 " Only auto-load if the plugin is fully loaded. This gives other plugins a 614 " chance to run. 615 if g:loaded_hgcommand == 2 616 call s:HGSetupBuffer() 617 endif 618endfunction 619 620" Function: HGGetStatusLine() {{{2 621" Default (sample) status line entry for HG files. This is only useful if 622" HG-managed buffer mode is on (see the HGCommandEnableBufferSetup variable 623" for how to do this). 624 625function! HGGetStatusLine() 626 if exists('b:HGSourceFile') 627 " This is a result buffer 628 let value='[' . b:HGCommand . ' ' . b:HGSourceFile 629 if exists('b:HGStatusText') 630 let value=value . ' ' . b:HGStatusText 631 endif 632 let value = value . ']' 633 return value 634 endif 635 636 if exists('b:HGRevision') 637 \ && b:HGRevision != '' 638 \ && exists('b:HGBranch') 639 \ && b:HGBranch != '' 640 \ && exists('b:HGRepository') 641 \ && b:HGRepository != '' 642 \ && exists('g:HGCommandEnableBufferSetup') 643 \ && g:HGCommandEnableBufferSetup 644 return '[HG ' . b:HGRepository . '/' . b:HGBranch .'/' . b:HGRevision . ']' 645 else 646 return '' 647 endif 648endfunction 649 650" Section: HG command functions {{{1 651 652" Function: s:HGAdd() {{{2 653function! s:HGAdd() 654 return s:HGMarkOrigBufferForSetup(s:HGDoCommand('add', 'hgadd', '')) 655endfunction 656 657" Function: s:HGAnnotate(...) {{{2 658function! s:HGAnnotate(...) 659 if a:0 == 0 660 if &filetype == "HGAnnotate" 661 " This is a HGAnnotate buffer. Perform annotation of the version 662 " indicated by the current line. 663 let revision = substitute(getline("."),'\(^[0-9]*\):.*','\1','') 664 if s:HGGetOption('HGCommandAnnotateParent', 0) != 0 && revision > 0 665 let revision = revision - 1 666 endif 667 else 668 let revision=HGGetRevision() 669 if revision == "" 670 echoerr "Unable to obtain HG version information." 671 return -1 672 endif 673 endif 674 else 675 let revision=a:1 676 endif 677 678 if revision == "NEW" 679 echo "No annotatation available for new file." 680 return -1 681 endif 682 683 let resultBuffer=s:HGDoCommand('annotate -ndu -r ' . revision, 'hgannotate', revision) 684 echomsg "DBG: ".resultBuffer 685 if resultBuffer != -1 686 set filetype=HGAnnotate 687 endif 688 689 return resultBuffer 690endfunction 691 692" Function: s:HGCommit() {{{2 693function! s:HGCommit(...) 694 " Handle the commit message being specified. If a message is supplied, it 695 " is used; if bang is supplied, an empty message is used; otherwise, the 696 " user is provided a buffer from which to edit the commit message. 697 if a:2 != "" || a:1 == "!" 698 return s:HGMarkOrigBufferForSetup(s:HGDoCommand('commit -m "' . a:2 . '"', 'hgcommit', '')) 699 endif 700 701 let hgBufferCheck=s:HGCurrentBufferCheck() 702 if hgBufferCheck == -1 703 echo "Original buffer no longer exists, aborting." 704 return -1 705 endif 706 707 " Protect against windows' backslashes in paths. They confuse exec'd 708 " commands. 709 710 let shellSlashBak = &shellslash 711 try 712 set shellslash 713 714 let messageFileName = tempname() 715 716 let fileName=bufname(hgBufferCheck) 717 let realFilePath=s:HGResolveLink(fileName) 718 let newCwd=fnamemodify(realFilePath, ':h') 719 if strlen(newCwd) == 0 720 " Account for autochdir being in effect, which will make this blank, but 721 " we know we'll be in the current directory for the original file. 722 let newCwd = getcwd() 723 endif 724 725 let realFileName=fnamemodify(realFilePath, ':t') 726 727 if s:HGEditFile(messageFileName, hgBufferCheck) == -1 728 return 729 endif 730 731 " Protect against case and backslash issues in Windows. 732 let autoPattern = '\c' . messageFileName 733 734 " Ensure existence of group 735 augroup HGCommit 736 augroup END 737 738 execute 'au HGCommit BufDelete' autoPattern 'call delete("' . messageFileName . '")' 739 execute 'au HGCommit BufDelete' autoPattern 'au! HGCommit * ' autoPattern 740 741 " Create a commit mapping. The mapping must clear all autocommands in case 742 " it is invoked when HGCommandCommitOnWrite is active, as well as to not 743 " invoke the buffer deletion autocommand. 744 745 execute 'nnoremap <silent> <buffer> <Plug>HGCommit '. 746 \ ':au! HGCommit * ' . autoPattern . '<CR>'. 747 \ ':g/^HG:/d<CR>'. 748 \ ':update<CR>'. 749 \ ':call <SID>HGFinishCommit("' . messageFileName . '",' . 750 \ '"' . newCwd . '",' . 751 \ '"' . realFileName . '",' . 752 \ hgBufferCheck . ')<CR>' 753 754 silent 0put ='HG: ----------------------------------------------------------------------' 755 silent put =\"HG: Enter Log. Lines beginning with `HG:' are removed automatically\" 756 silent put ='HG: Type <leader>cc (or your own <Plug>HGCommit mapping)' 757 758 if s:HGGetOption('HGCommandCommitOnWrite', 1) == 1 759 execute 'au HGCommit BufWritePre' autoPattern 'g/^HG:/d' 760 execute 'au HGCommit BufWritePost' autoPattern 'call s:HGFinishCommit("' . messageFileName . '", "' . newCwd . '", "' . realFileName . '", ' . hgBufferCheck . ') | au! * ' autoPattern 761 silent put ='HG: or write this buffer' 762 endif 763 764 silent put ='HG: to finish this commit operation' 765 silent put ='HG: ----------------------------------------------------------------------' 766 $ 767 let b:HGSourceFile=fileName 768 let b:HGCommand='HGCommit' 769 set filetype=hg 770 finally 771 let &shellslash = shellSlashBak 772 endtry 773 774endfunction 775 776" Function: s:HGDiff(...) {{{2 777function! s:HGDiff(...) 778 if a:0 == 1 779 let revOptions = '-r' . a:1 780 let caption = a:1 . ' -> current' 781 elseif a:0 == 2 782 let revOptions = '-r' . a:1 . ' -r' . a:2 783 let caption = a:1 . ' -> ' . a:2 784 else 785 let revOptions = '' 786 let caption = '' 787 endif 788 789 let hgdiffopt=s:HGGetOption('HGCommandDiffOpt', 'w') 790 791 if hgdiffopt == "" 792 let diffoptionstring="" 793 else 794 let diffoptionstring=" -" . hgdiffopt . " " 795 endif 796 797 let resultBuffer = s:HGDoCommand('diff ' . diffoptionstring . revOptions , 'hgdiff', caption) 798 if resultBuffer != -1 799 set filetype=diff 800 endif 801 return resultBuffer 802endfunction 803 804 805" Function: s:HGGotoOriginal(["!]) {{{2 806function! s:HGGotoOriginal(...) 807 let origBuffNR = s:HGCurrentBufferCheck() 808 if origBuffNR > 0 809 let origWinNR = bufwinnr(origBuffNR) 810 if origWinNR == -1 811 execute 'buffer' origBuffNR 812 else 813 execute origWinNR . 'wincmd w' 814 endif 815 if a:0 == 1 816 if a:1 == "!" 817 let buffnr = 1 818 let buffmaxnr = bufnr("$") 819 while buffnr <= buffmaxnr 820 if getbufvar(buffnr, "HGOrigBuffNR") == origBuffNR 821 execute "bw" buffnr 822 endif 823 let buffnr = buffnr + 1 824 endwhile 825 endif 826 endif 827 endif 828endfunction 829 830" Function: s:HGFinishCommit(messageFile, targetDir, targetFile) {{{2 831function! s:HGFinishCommit(messageFile, targetDir, targetFile, origBuffNR) 832 if filereadable(a:messageFile) 833 let oldCwd=getcwd() 834 if strlen(a:targetDir) > 0 835 execute 'cd' escape(a:targetDir, ' ') 836 endif 837 let resultBuffer=s:HGCreateCommandBuffer('commit -F "' . a:messageFile . '" "'. a:targetFile . '"', 'hgcommit', '', a:origBuffNR) 838 execute 'cd' escape(oldCwd, ' ') 839 execute 'bw' escape(a:messageFile, ' *?\') 840 silent execute 'call delete("' . a:messageFile . '")' 841 return s:HGMarkOrigBufferForSetup(resultBuffer) 842 else 843 echoerr "Can't read message file; no commit is possible." 844 return -1 845 endif 846endfunction 847 848" Function: s:HGLog() {{{2 849function! s:HGLog(...) 850 if a:0 == 0 851 let versionOption = "" 852 let caption = '' 853 else 854 let versionOption=" -r" . a:1 855 let caption = a:1 856 endif 857 858 let resultBuffer=s:HGDoCommand('log' . versionOption, 'hglog', caption) 859 if resultBuffer != "" 860 set filetype=rcslog 861 endif 862 return resultBuffer 863endfunction 864 865" Function: s:HGRevert() {{{2 866function! s:HGRevert() 867 return s:HGMarkOrigBufferForSetup(s:HGDoCommand('revert', 'hgrevert', '')) 868endfunction 869 870" Function: s:HGReview(...) {{{2 871function! s:HGReview(...) 872 if a:0 == 0 873 let versiontag="" 874 if s:HGGetOption('HGCommandInteractive', 0) 875 let versiontag=input('Revision: ') 876 endif 877 if versiontag == "" 878 let versiontag="(current)" 879 let versionOption="" 880 else 881 let versionOption=" -r " . versiontag . " " 882 endif 883 else 884 let versiontag=a:1 885 let versionOption=" -r " . versiontag . " " 886 endif 887 888 let resultBuffer = s:HGDoCommand('cat' . versionOption, 'hgreview', versiontag) 889 if resultBuffer > 0 890 let &filetype=getbufvar(b:HGOrigBuffNR, '&filetype') 891 endif 892 893 return resultBuffer 894endfunction 895 896" Function: s:HGStatus() {{{2 897function! s:HGStatus() 898 return s:HGDoCommand('status', 'hgstatus', '') 899endfunction 900 901 902" Function: s:HGUpdate() {{{2 903function! s:HGUpdate() 904 return s:HGMarkOrigBufferForSetup(s:HGDoCommand('update', 'update', '')) 905endfunction 906 907" Function: s:HGVimDiff(...) {{{2 908function! s:HGVimDiff(...) 909 let originalBuffer = s:HGCurrentBufferCheck() 910 let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1 911 try 912 " If there's already a VimDiff'ed window, restore it. 913 " There may only be one HGVimDiff original window at a time. 914 915 if exists("s:vimDiffSourceBuffer") && s:vimDiffSourceBuffer != originalBuffer 916 " Clear the existing vimdiff setup by removing the result buffers. 917 call s:HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff') 918 endif 919 920 " Split and diff 921 if(a:0 == 2) 922 " Reset the vimdiff system, as 2 explicit versions were provided. 923 if exists('s:vimDiffSourceBuffer') 924 call s:HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff') 925 endif 926 let resultBuffer = s:HGReview(a:1) 927 if resultBuffer < 0 928 echomsg "Can't open HG revision " . a:1 929 return resultBuffer 930 endif 931 let b:HGCommand = 'vimdiff' 932 diffthis 933 let s:vimDiffBufferCount = 1 934 let s:vimDiffScratchList = '{'. resultBuffer . '}' 935 " If no split method is defined, cheat, and set it to vertical. 936 try 937 call s:HGOverrideOption('HGCommandSplit', s:HGGetOption('HGCommandDiffSplit', s:HGGetOption('HGCommandSplit', 'vertical'))) 938 let resultBuffer=s:HGReview(a:2) 939 finally 940 call s:HGOverrideOption('HGCommandSplit') 941 endtry 942 if resultBuffer < 0 943 echomsg "Can't open HG revision " . a:1 944 return resultBuffer 945 endif 946 let b:HGCommand = 'vimdiff' 947 diffthis 948 let s:vimDiffBufferCount = 2 949 let s:vimDiffScratchList = s:vimDiffScratchList . '{'. resultBuffer . '}' 950 else 951 " Add new buffer 952 try 953 " Force splitting behavior, otherwise why use vimdiff? 954 call s:HGOverrideOption("HGCommandEdit", "split") 955 call s:HGOverrideOption("HGCommandSplit", s:HGGetOption('HGCommandDiffSplit', s:HGGetOption('HGCommandSplit', 'vertical'))) 956 if(a:0 == 0) 957 let resultBuffer=s:HGReview() 958 else 959 let resultBuffer=s:HGReview(a:1) 960 endif 961 finally 962 call s:HGOverrideOption("HGCommandEdit") 963 call s:HGOverrideOption("HGCommandSplit") 964 endtry 965 if resultBuffer < 0 966 echomsg "Can't open current HG revision" 967 return resultBuffer 968 endif 969 let b:HGCommand = 'vimdiff' 970 diffthis 971 972 if !exists('s:vimDiffBufferCount') 973 " New instance of vimdiff. 974 let s:vimDiffBufferCount = 2 975 let s:vimDiffScratchList = '{' . resultBuffer . '}' 976 977 " This could have been invoked on a HG result buffer, not the 978 " original buffer. 979 wincmd W 980 execute 'buffer' originalBuffer 981 " Store info for later original buffer restore 982 let s:vimDiffRestoreCmd = 983 \ "call setbufvar(".originalBuffer.", \"&diff\", ".getbufvar(originalBuffer, '&diff').")" 984 \ . "|call setbufvar(".originalBuffer.", \"&foldcolumn\", ".getbufvar(originalBuffer, '&foldcolumn').")" 985 \ . "|call setbufvar(".originalBuffer.", \"&foldenable\", ".getbufvar(originalBuffer, '&foldenable').")" 986 \ . "|call setbufvar(".originalBuffer.", \"&foldmethod\", '".getbufvar(originalBuffer, '&foldmethod')."')" 987 \ . "|call setbufvar(".originalBuffer.", \"&scrollbind\", ".getbufvar(originalBuffer, '&scrollbind').")" 988 \ . "|call setbufvar(".originalBuffer.", \"&wrap\", ".getbufvar(originalBuffer, '&wrap').")" 989 \ . "|if &foldmethod=='manual'|execute 'normal zE'|endif" 990 diffthis 991 wincmd w 992 else 993 " Adding a window to an existing vimdiff 994 let s:vimDiffBufferCount = s:vimDiffBufferCount + 1 995 let s:vimDiffScratchList = s:vimDiffScratchList . '{' . resultBuffer . '}' 996 endif 997 endif 998 999 let s:vimDiffSourceBuffer = originalBuffer 1000 1001 " Avoid executing the modeline in the current buffer after the autocommand. 1002 1003 let currentBuffer = bufnr('%') 1004 let saveModeline = getbufvar(currentBuffer, '&modeline') 1005 try 1006 call setbufvar(currentBuffer, '&modeline', 0) 1007 silent do HGCommand User HGVimDiffFinish 1008 finally 1009 call setbufvar(currentBuffer, '&modeline', saveModeline) 1010 endtry 1011 return resultBuffer 1012 finally 1013 let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1 1014 endtry 1015endfunction 1016 1017" Section: Command definitions {{{1 1018" Section: Primary commands {{{2 1019com! HGAdd call s:HGAdd() 1020com! -nargs=? HGAnnotate call s:HGAnnotate(<f-args>) 1021com! -bang -nargs=? HGCommit call s:HGCommit(<q-bang>, <q-args>) 1022com! -nargs=* HGDiff call s:HGDiff(<f-args>) 1023com! -bang HGGotoOriginal call s:HGGotoOriginal(<q-bang>) 1024com! -nargs=? HGLog call s:HGLog(<f-args>) 1025com! HGRevert call s:HGRevert() 1026com! -nargs=? HGReview call s:HGReview(<f-args>) 1027com! HGStatus call s:HGStatus() 1028com! HGUpdate call s:HGUpdate() 1029com! -nargs=* HGVimDiff call s:HGVimDiff(<f-args>) 1030 1031" Section: HG buffer management commands {{{2 1032com! HGDisableBufferSetup call HGDisableBufferSetup() 1033com! HGEnableBufferSetup call HGEnableBufferSetup() 1034 1035" Allow reloading hgcommand.vim 1036com! HGReload unlet! loaded_hgcommand | runtime plugin/hgcommand.vim 1037 1038" Section: Plugin command mappings {{{1 1039nnoremap <silent> <Plug>HGAdd :HGAdd<CR> 1040nnoremap <silent> <Plug>HGAnnotate :HGAnnotate<CR> 1041nnoremap <silent> <Plug>HGCommit :HGCommit<CR> 1042nnoremap <silent> <Plug>HGDiff :HGDiff<CR> 1043nnoremap <silent> <Plug>HGGotoOriginal :HGGotoOriginal<CR> 1044nnoremap <silent> <Plug>HGClearAndGotoOriginal :HGGotoOriginal!<CR> 1045nnoremap <silent> <Plug>HGLog :HGLog<CR> 1046nnoremap <silent> <Plug>HGRevert :HGRevert<CR> 1047nnoremap <silent> <Plug>HGReview :HGReview<CR> 1048nnoremap <silent> <Plug>HGStatus :HGStatus<CR> 1049nnoremap <silent> <Plug>HGUpdate :HGUpdate<CR> 1050nnoremap <silent> <Plug>HGVimDiff :HGVimDiff<CR> 1051nnoremap <silent> <Plug>HGWatchers :HGWatchers<CR> 1052nnoremap <silent> <Plug>HGWatchAdd :HGWatchAdd<CR> 1053nnoremap <silent> <Plug>HGWatchOn :HGWatchOn<CR> 1054nnoremap <silent> <Plug>HGWatchOff :HGWatchOff<CR> 1055nnoremap <silent> <Plug>HGWatchRemove :HGWatchRemove<CR> 1056 1057" Section: Default mappings {{{1 1058if !hasmapto('<Plug>HGAdd') 1059 nmap <unique> <Leader>hga <Plug>HGAdd 1060endif 1061if !hasmapto('<Plug>HGAnnotate') 1062 nmap <unique> <Leader>hgn <Plug>HGAnnotate 1063endif 1064if !hasmapto('<Plug>HGClearAndGotoOriginal') 1065 nmap <unique> <Leader>hgG <Plug>HGClearAndGotoOriginal 1066endif 1067if !hasmapto('<Plug>HGCommit') 1068 nmap <unique> <Leader>hgc <Plug>HGCommit 1069endif 1070if !hasmapto('<Plug>HGDiff') 1071 nmap <unique> <Leader>hgd <Plug>HGDiff 1072endif 1073if !hasmapto('<Plug>HGGotoOriginal') 1074 nmap <unique> <Leader>hgg <Plug>HGGotoOriginal 1075endif 1076if !hasmapto('<Plug>HGLog') 1077 nmap <unique> <Leader>hgl <Plug>HGLog 1078endif 1079if !hasmapto('<Plug>HGRevert') 1080 nmap <unique> <Leader>hgq <Plug>HGRevert 1081endif 1082if !hasmapto('<Plug>HGReview') 1083 nmap <unique> <Leader>hgr <Plug>HGReview 1084endif 1085if !hasmapto('<Plug>HGStatus') 1086 nmap <unique> <Leader>hgs <Plug>HGStatus 1087endif 1088if !hasmapto('<Plug>HGUpdate') 1089 nmap <unique> <Leader>hgu <Plug>HGUpdate 1090endif 1091if !hasmapto('<Plug>HGVimDiff') 1092 nmap <unique> <Leader>hgv <Plug>HGVimDiff 1093endif 1094 1095" Section: Menu items {{{1 1096silent! aunmenu Plugin.HG 1097amenu <silent> &Plugin.HG.&Add <Plug>HGAdd 1098amenu <silent> &Plugin.HG.A&nnotate <Plug>HGAnnotate 1099amenu <silent> &Plugin.HG.&Commit <Plug>HGCommit 1100amenu <silent> &Plugin.HG.&Diff <Plug>HGDiff 1101amenu <silent> &Plugin.HG.&Log <Plug>HGLog 1102amenu <silent> &Plugin.HG.Revert <Plug>HGRevert 1103amenu <silent> &Plugin.HG.&Review <Plug>HGReview 1104amenu <silent> &Plugin.HG.&Status <Plug>HGStatus 1105amenu <silent> &Plugin.HG.&Update <Plug>HGUpdate 1106amenu <silent> &Plugin.HG.&VimDiff <Plug>HGVimDiff 1107amenu <silent> &Plugin.HG.&Watchers <Plug>HGWatchers 1108amenu <silent> &Plugin.HG.WatchAdd <Plug>HGWatchAdd 1109amenu <silent> &Plugin.HG.WatchOn <Plug>HGWatchOn 1110amenu <silent> &Plugin.HG.WatchOff <Plug>HGWatchOff 1111amenu <silent> &Plugin.HG.WatchRemove <Plug>HGWatchRemove 1112 1113" Section: Autocommands to restore vimdiff state {{{1 1114function! s:HGVimDiffRestore(vimDiffBuff) 1115 let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1 1116 try 1117 if exists("s:vimDiffSourceBuffer") 1118 if a:vimDiffBuff == s:vimDiffSourceBuffer 1119 " Original file is being removed. 1120 unlet! s:vimDiffSourceBuffer 1121 unlet! s:vimDiffBufferCount 1122 unlet! s:vimDiffRestoreCmd 1123 unlet! s:vimDiffScratchList 1124 elseif match(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}') >= 0 1125 let s:vimDiffScratchList = substitute(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}', '', '') 1126 let s:vimDiffBufferCount = s:vimDiffBufferCount - 1 1127 if s:vimDiffBufferCount == 1 && exists('s:vimDiffRestoreCmd') 1128 " All scratch buffers are gone, reset the original. 1129 " Only restore if the source buffer is still in Diff mode 1130 1131 let sourceWinNR=bufwinnr(s:vimDiffSourceBuffer) 1132 if sourceWinNR != -1 1133 " The buffer is visible in at least one window 1134 let currentWinNR = winnr() 1135 while winbufnr(sourceWinNR) != -1 1136 if winbufnr(sourceWinNR) == s:vimDiffSourceBuffer 1137 execute sourceWinNR . 'wincmd w' 1138 if getwinvar('', "&diff") 1139 execute s:vimDiffRestoreCmd 1140 endif 1141 endif 1142 let sourceWinNR = sourceWinNR + 1 1143 endwhile 1144 execute currentWinNR . 'wincmd w' 1145 else 1146 " The buffer is hidden. It must be visible in order to set the 1147 " diff option. 1148 let currentBufNR = bufnr('') 1149 execute "hide buffer" s:vimDiffSourceBuffer 1150 if getwinvar('', "&diff") 1151 execute s:vimDiffRestoreCmd 1152 endif 1153 execute "hide buffer" currentBufNR 1154 endif 1155 1156 unlet s:vimDiffRestoreCmd 1157 unlet s:vimDiffSourceBuffer 1158 unlet s:vimDiffBufferCount 1159 unlet s:vimDiffScratchList 1160 elseif s:vimDiffBufferCount == 0 1161 " All buffers are gone. 1162 unlet s:vimDiffSourceBuffer 1163 unlet s:vimDiffBufferCount 1164 unlet s:vimDiffScratchList 1165 endif 1166 endif 1167 endif 1168 finally 1169 let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1 1170 endtry 1171endfunction 1172 1173augroup HGVimDiffRestore 1174 au! 1175 au BufUnload * call s:HGVimDiffRestore(expand("<abuf>")) 1176augroup END 1177 1178" Section: Optional activation of buffer management {{{1 1179 1180if s:HGGetOption('HGCommandEnableBufferSetup', 0) 1181 call HGEnableBufferSetup() 1182endif 1183 1184" Section: Doc installation {{{1 1185" 1186 let s:revision="0.1" 1187 silent! let s:install_status = 1188 \ s:HGInstallDocumentation(expand('<sfile>:p'), s:revision) 1189 if (s:install_status == 1) 1190 echom expand("<sfile>:t:r") . ' v' . s:revision . 1191 \ ': Help-documentation installed.' 1192 endif 1193 1194 1195" Section: Plugin completion {{{1 1196 1197let loaded_hgcommand=2 1198silent do HGCommand User HGPluginFinish 1199" vim:se expandtab sts=2 sw=2: 1200finish 1201 1202"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1203" Section: Documentation content {{{1 1204"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1205=== START_DOC 1206*hgcommand.txt* Mercurial vim integration #version# 1207 1208 1209 HGCOMMAND REFERENCE MANUAL~ 1210 1211 1212Author: Mathieu Clabaut <mathieu.clabaut@gmail.com> 1213Credits: Bob Hiestand <bob.hiestand@gmail.com> 1214Mercurial: http://www.selenic.com/mercurial 1215 Mercurial (noted Hg) is a fast, lightweight Source Control Management 1216 system designed for efficient handling of very large distributed projects. 1217 1218============================================================================== 12191. Contents *hgcommand-contents* 1220 1221 Installation : |hgcommand-install| 1222 HGCommand Intro : |hgcommand| 1223 HGCommand Manual : |hgcommand-manual| 1224 Customization : |hgcommand-customize| 1225 Bugs : |hgcommand-bugs| 1226 1227============================================================================== 12282. HGCommand Installation *hgcommand-install* 1229 1230 In order to install the plugin, place the hgcommand.vim file into a plugin' 1231 directory in your runtime path (please see |add-global-plugin| and 1232 |'runtimepath'|. 1233 1234 HGCommand may be customized by setting variables, creating maps, and 1235 specifying event handlers. Please see |hgcommand-customize| for more 1236 details. 1237 1238 *hgcommand-auto-help* 1239 The help file is automagically generated when the |hgcommand| script is 1240 loaded for the first time. 1241 1242============================================================================== 1243 12443. HGCommand Intro *hgcommand* 1245 *hgcommand-intro* 1246 1247 The HGCommand plugin provides global ex commands for manipulating 1248 HG-controlled source files. In general, each command operates on the 1249 current buffer and accomplishes a separate hg function, such as update, 1250 commit, log, and others (please see |hgcommand-commands| for a list of all 1251 available commands). The results of each operation are displayed in a 1252 scratch buffer. Several buffer variables are defined for those scratch 1253 buffers (please see |hgcommand-buffer-variables|). 1254 1255 The notion of "current file" means either the current buffer, or, in the 1256 case of a directory buffer, the file on the current line within the buffer. 1257 1258 For convenience, any HGCommand invoked on a HGCommand scratch buffer acts 1259 as though it was invoked on the original file and splits the screen so that 1260 the output appears in a new window. 1261 1262 Many of the commands accept revisions as arguments. By default, most 1263 operate on the most recent revision on the current branch if no revision is 1264 specified (though see |HGCommandInteractive| to prompt instead). 1265 1266 Each HGCommand is mapped to a key sequence starting with the <Leader> 1267 keystroke. The default mappings may be overridden by supplying different 1268 mappings before the plugin is loaded, such as in the vimrc, in the standard 1269 fashion for plugin mappings. For examples, please see 1270 |hgcommand-mappings-override|. 1271 1272 The HGCommand plugin may be configured in several ways. For more details, 1273 please see |hgcommand-customize|. 1274 1275============================================================================== 12764. HGCommand Manual *hgcommand-manual* 1277 12784.1 HGCommand commands *hgcommand-commands* 1279 1280 HGCommand defines the following commands: 1281 1282 |:HGAdd| 1283 |:HGAnnotate| 1284 |:HGCommit| 1285 |:HGDiff| 1286 |:HGGotoOriginal| 1287 |:HGLog| 1288 |:HGRevert| 1289 |:HGReview| 1290 |:HGStatus| 1291 |:HGUpdate| 1292 |:HGVimDiff| 1293 1294:HGAdd *:HGAdd* 1295 1296 This command performs "hg add" on the current file. Please note, this does 1297 not commit the newly-added file. 1298 1299:HGAnnotate *:HGAnnotate* 1300 1301 This command performs "hg annotate" on the current file. If an argument is 1302 given, the argument is used as a revision number to display. If not given 1303 an argument, it uses the most recent version of the file on the current 1304 branch. Additionally, if the current buffer is a HGAnnotate buffer 1305 already, the version number on the current line is used. 1306 1307 If the |HGCommandAnnotateParent| variable is set to a non-zero value, the 1308 version previous to the one on the current line is used instead. This 1309 allows one to navigate back to examine the previous version of a line. 1310 1311 The filetype of the HGCommand scratch buffer is set to 'HGAnnotate', to 1312 take advantage of the bundled syntax file. 1313 1314 1315:HGCommit[!] *:HGCommit* 1316 1317 If called with arguments, this performs "hg commit" using the arguments as 1318 the log message. 1319 1320 If '!' is used with no arguments, an empty log message is committed. 1321 1322 If called with no arguments, this is a two-step command. The first step 1323 opens a buffer to accept a log message. When that buffer is written, it is 1324 automatically closed and the file is committed using the information from 1325 that log message. The commit can be abandoned if the log message buffer is 1326 deleted or wiped before being written. 1327 1328 Alternatively, the mapping that is used to invoke :HGCommit (by default 1329 <Leader>hgc) can be used in the log message buffer to immediately commit. 1330 This is useful if the |HGCommandCommitOnWrite| variable is set to 0 to 1331 disable the normal commit-on-write behavior. 1332 1333:HGDiff *:HGDiff* 1334 1335 With no arguments, this performs "hg diff" on the current file against the 1336 current repository version. 1337 1338 With one argument, "hg diff" is performed on the current file against the 1339 specified revision. 1340 1341 With two arguments, hg diff is performed between the specified revisions of 1342 the current file. 1343 1344 This command uses the 'HGCommandDiffOpt' variable to specify diff options. 1345 If that variable does not exist, then 'wbBc' is assumed. If you wish to 1346 have no options, then set it to the empty string. 1347 1348 1349:HGGotoOriginal *:HGGotoOriginal* 1350 1351 This command returns the current window to the source buffer, if the 1352 current buffer is a HG command output buffer. 1353 1354:HGGotoOriginal! 1355 1356 Like ":HGGotoOriginal" but also executes :bufwipeout on all HG command 1357 output buffers for the source buffer. 1358 1359:HGLog *:HGLog* 1360 1361 Performs "hg log" on the current file. 1362 1363 If an argument is given, it is passed as an argument to the "-r" option of 1364 "hg log". 1365 1366:HGRevert *:HGRevert* 1367 1368 Replaces the current file with the most recent version from the repository 1369 in order to wipe out any undesired changes. 1370 1371:HGReview *:HGReview* 1372 1373 Retrieves a particular version of the current file. If no argument is 1374 given, the most recent version of the file on the current branch is 1375 retrieved. Otherwise, the specified version is retrieved. 1376 1377:HGStatus *:HGStatus* 1378 1379 Performs "hg status" on the current file. 1380 1381:HGUpdate *:HGUpdate* 1382 1383 Performs "hg update" on the current file. This intentionally does not 1384 automatically reload the current buffer, though vim should prompt the user 1385 to do so if the underlying file is altered by this command. 1386 1387:HGVimDiff *:HGVimDiff* 1388 1389 With no arguments, this prompts the user for a revision and then uses 1390 vimdiff to display the differences between the current file and the 1391 specified revision. If no revision is specified, the most recent version 1392 of the file on the current branch is used. 1393 1394 With one argument, that argument is used as the revision as above. With 1395 two arguments, the differences between the two revisions is displayed using 1396 vimdiff. 1397 1398 With either zero or one argument, the original buffer is used to perform 1399 the vimdiff. When the other buffer is closed, the original buffer will be 1400 returned to normal mode. 1401 1402 Once vimdiff mode is started using the above methods, additional vimdiff 1403 buffers may be added by passing a single version argument to the command. 1404 There may be up to 4 vimdiff buffers total. 1405 1406 Using the 2-argument form of the command resets the vimdiff to only those 2 1407 versions. Additionally, invoking the command on a different file will 1408 close the previous vimdiff buffers. 1409 1410 14114.2 Mappings *hgcommand-mappings* 1412 1413 By default, a mapping is defined for each command. These mappings execute 1414 the default (no-argument) form of each command. 1415 1416 <Leader>hga HGAdd 1417 <Leader>hgn HGAnnotate 1418 <Leader>hgc HGCommit 1419 <Leader>hgd HGDiff 1420 <Leader>hgg HGGotoOriginal 1421 <Leader>hgG HGGotoOriginal! 1422 <Leader>hgl HGLog 1423 <Leader>hgr HGReview 1424 <Leader>hgs HGStatus 1425 <Leader>hgu HGUpdate 1426 <Leader>hgv HGVimDiff 1427 1428 *hgcommand-mappings-override* 1429 1430 The default mappings can be overriden by user-provided instead by mapping 1431 to <Plug>CommandName. This is especially useful when these mappings 1432 collide with other existing mappings (vim will warn of this during plugin 1433 initialization, but will not clobber the existing mappings). 1434 1435 For instance, to override the default mapping for :HGAdd to set it to 1436 '\add', add the following to the vimrc: > 1437 1438 nmap \add <Plug>HGAdd 1439< 14404.3 Automatic buffer variables *hgcommand-buffer-variables* 1441 1442 Several buffer variables are defined in each HGCommand result buffer. 1443 These may be useful for additional customization in callbacks defined in 1444 the event handlers (please see |hgcommand-events|). 1445 1446 The following variables are automatically defined: 1447 1448b:hgOrigBuffNR *b:hgOrigBuffNR* 1449 1450 This variable is set to the buffer number of the source file. 1451 1452b:hgcmd *b:hgcmd* 1453 1454 This variable is set to the name of the hg command that created the result 1455 buffer. 1456============================================================================== 1457 14585. Configuration and customization *hgcommand-customize* 1459 *hgcommand-config* 1460 1461 The HGCommand plugin can be configured in two ways: by setting 1462 configuration variables (see |hgcommand-options|) or by defining HGCommand 1463 event handlers (see |hgcommand-events|). Additionally, the HGCommand 1464 plugin provides several option for naming the HG result buffers (see 1465 |hgcommand-naming|) and supported a customized status line (see 1466 |hgcommand-statusline| and |hgcommand-buffer-management|). 1467 14685.1 HGCommand configuration variables *hgcommand-options* 1469 1470 Several variables affect the plugin's behavior. These variables are 1471 checked at time of execution, and may be defined at the window, buffer, or 1472 global level and are checked in that order of precedence. 1473 1474 1475 The following variables are available: 1476 1477 |HGCommandAnnotateParent| 1478 |HGCommandCommitOnWrite| 1479 |HGCommandHGExec| 1480 |HGCommandDeleteOnHide| 1481 |HGCommandDiffOpt| 1482 |HGCommandDiffSplit| 1483 |HGCommandEdit| 1484 |HGCommandEnableBufferSetup| 1485 |HGCommandInteractive| 1486 |HGCommandNameMarker| 1487 |HGCommandNameResultBuffers| 1488 |HGCommandSplit| 1489 1490HGCommandAnnotateParent *HGCommandAnnotateParent* 1491 1492 This variable, if set to a non-zero value, causes the zero-argument form of 1493 HGAnnotate when invoked on a HGAnnotate buffer to go to the version 1494 previous to that displayed on the current line. If not set, it defaults to 1495 0. 1496 1497HGCommandCommitOnWrite *HGCommandCommitOnWrite* 1498 1499 This variable, if set to a non-zero value, causes the pending hg commit to 1500 take place immediately as soon as the log message buffer is written. If 1501 set to zero, only the HGCommit mapping will cause the pending commit to 1502 occur. If not set, it defaults to 1. 1503 1504HGCommandHGExec *HGCommandHGExec* 1505 1506 This variable controls the executable used for all HG commands. If not 1507 set, it defaults to "hg". 1508 1509HGCommandDeleteOnHide *HGCommandDeleteOnHide* 1510 1511 This variable, if set to a non-zero value, causes the temporary HG result 1512 buffers to automatically delete themselves when hidden. 1513 1514HGCommandDiffOpt *HGCommandDiffOpt* 1515 1516 This variable, if set, determines the options passed to the diff command of 1517 HG. If not set, it defaults to 'w'. 1518 1519HGCommandDiffSplit *HGCommandDiffSplit* 1520 1521 This variable overrides the |HGCommandSplit| variable, but only for buffers 1522 created with |:HGVimDiff|. 1523 1524HGCommandEdit *HGCommandEdit* 1525 1526 This variable controls whether the original buffer is replaced ('edit') or 1527 split ('split'). If not set, it defaults to 'edit'. 1528 1529HGCommandEnableBufferSetup *HGCommandEnableBufferSetup* 1530 1531 This variable, if set to a non-zero value, activates HG buffer management 1532 mode see (|hgcommand-buffer-management|). This mode means that three 1533 buffer variables, 'HGRepository', 'HGRevision' and 'HGBranch', are set if 1534 the file is HG-controlled. This is useful for displaying version 1535 information in the status bar. 1536 1537HGCommandInteractive *HGCommandInteractive* 1538 1539 This variable, if set to a non-zero value, causes appropriate commands (for 1540 the moment, only |:HGReview|) to query the user for a revision to use 1541 instead of the current revision if none is specified. 1542 1543HGCommandNameMarker *HGCommandNameMarker* 1544 1545 This variable, if set, configures the special attention-getting characters 1546 that appear on either side of the hg buffer type in the buffer name. This 1547 has no effect unless |HGCommandNameResultBuffers| is set to a true value. 1548 If not set, it defaults to '_'. 1549 1550HGCommandNameResultBuffers *HGCommandNameResultBuffers* 1551 1552 This variable, if set to a true value, causes the hg result buffers to be 1553 named in the old way ('<source file name> _<hg command>_'). If not set or 1554 set to a false value, the result buffer is nameless. 1555 1556HGCommandSplit *HGCommandSplit* 1557 1558 This variable controls the orientation of the various window splits that 1559 may occur (such as with HGVimDiff, when using a HG command on a HG command 1560 buffer, or when the |HGCommandEdit| variable is set to 'split'. If set to 1561 'horizontal', the resulting windows will be on stacked on top of one 1562 another. If set to 'vertical', the resulting windows will be side-by-side. 1563 If not set, it defaults to 'horizontal' for all but HGVimDiff windows. 1564 15655.2 HGCommand events *hgcommand-events* 1566 1567 For additional customization, HGCommand can trigger user-defined events. 1568 Event handlers are provided by defining User event autocommands (see 1569 |autocommand|, |User|) in the HGCommand group with patterns matching the 1570 event name. 1571 1572 For instance, the following could be added to the vimrc to provide a 'q' 1573 mapping to quit a HGCommand scratch buffer: > 1574 1575 augroup HGCommand 1576 au HGCommand User HGBufferCreated silent! nmap <unique> <buffer> q: 1577 bwipeout<cr> 1578 augroup END 1579< 1580 1581 The following hooks are available: 1582 1583HGBufferCreated This event is fired just after a hg command result 1584 buffer is created and filled with the result of a hg 1585 command. It is executed within the context of the HG 1586 command buffer. The HGCommand buffer variables may be 1587 useful for handlers of this event (please see 1588 |hgcommand-buffer-variables|). 1589 1590HGBufferSetup This event is fired just after HG buffer setup occurs, 1591 if enabled. 1592 1593HGPluginInit This event is fired when the HGCommand plugin first 1594 loads. 1595 1596HGPluginFinish This event is fired just after the HGCommand plugin 1597 loads. 1598 1599HGVimDiffFinish This event is fired just after the HGVimDiff command 1600 executes to allow customization of, for instance, 1601 window placement and focus. 1602 16035.3 HGCommand buffer naming *hgcommand-naming* 1604 1605 By default, the buffers containing the result of HG commands are nameless 1606 scratch buffers. It is intended that buffer variables of those buffers be 1607 used to customize the statusline option so that the user may fully control 1608 the display of result buffers. 1609 1610 If the old-style naming is desired, please enable the 1611 |HGCommandNameResultBuffers| variable. Then, each result buffer will 1612 receive a unique name that includes the source file name, the HG command, 1613 and any extra data (such as revision numbers) that were part of the 1614 command. 1615 16165.4 HGCommand status line support *hgcommand-statusline* 1617 1618 It is intended that the user will customize the |'statusline'| option to 1619 include HG result buffer attributes. A sample function that may be used in 1620 the |'statusline'| option is provided by the plugin, HGGetStatusLine(). In 1621 order to use that function in the status line, do something like the 1622 following: > 1623 1624 set statusline=%<%f\ %{HGGetStatusLine()}\ %h%m%r%=%l,%c%V\ %P 1625< 1626 of which %{HGGetStatusLine()} is the relevant portion. 1627 1628 The sample HGGetStatusLine() function handles both HG result buffers and 1629 HG-managed files if HGCommand buffer management is enabled (please see 1630 |hgcommand-buffer-management|). 1631 16325.5 HGCommand buffer management *hgcommand-buffer-management* 1633 1634 The HGCommand plugin can operate in buffer management mode, which means 1635 that it attempts to set two buffer variables ('HGRevision' and 'HGBranch') 1636 upon entry into a buffer. This is rather slow because it means that 'hg 1637 status' will be invoked at each entry into a buffer (during the |BufEnter| 1638 autocommand). 1639 1640 This mode is disabled by default. In order to enable it, set the 1641 |HGCommandEnableBufferSetup| variable to a true (non-zero) value. Enabling 1642 this mode simply provides the buffer variables mentioned above. The user 1643 must explicitly include those in the |'statusline'| option if they are to 1644 appear in the status line (but see |hgcommand-statusline| for a simple way 1645 to do that). 1646 1647============================================================================== 16489. Tips *hgcommand-tips* 1649 16509.1 Split window annotation, by Michael Anderson > 1651 1652 :nmap <Leader>hgN :vs<CR><C-w>h<Leader>hgn:vertical res 40<CR> 1653 \ggdddd:set scb<CR>:set nowrap<CR><C-w>lgg:set scb<CR> 1654 \:set nowrap<CR> 1655< 1656 1657 This splits the buffer vertically, puts an annotation on the left (minus 1658 the header) with the width set to 40. An editable/normal copy is placed on 1659 the right. The two versions are scroll locked so they move as one. and 1660 wrapping is turned off so that the lines line up correctly. The advantages 1661 are... 1662 1663 1) You get a versioning on the right. 1664 2) You can still edit your own code. 1665 3) Your own code still has syntax highlighting. 1666 1667============================================================================== 1668 16698. Known bugs *hgcommand-bugs* 1670 1671 Please let me know if you run across any. 1672 1673 HGVimDiff, when using the original (real) source buffer as one of the diff 1674 buffers, uses some hacks to try to restore the state of the original buffer 1675 when the scratch buffer containing the other version is destroyed. There 1676 may still be bugs in here, depending on many configuration details. 1677 1678============================================================================== 1679=== END_DOC 1680"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 1681" v im:tw=78:ts=8:ft=help:norl: 1682" vim600: set foldmethod=marker tabstop=8 shiftwidth=2 softtabstop=2 smartindent smarttab : 1683"fileencoding=iso-8859-15 1684