comparison contrib/vim/hgcommand.vim @ 2591:61f2008cd6bf

Addition of CVScommand vim script as a base for HGcommand
author "Mathieu Clabaut <mathieu.clabaut@gmail.com>"
date Mon, 10 Jul 2006 23:39:08 +0200
parents
children 457846f400e8
comparison
equal deleted inserted replaced
2576:6a961a54f953 2591:61f2008cd6bf
1 " vim600: set foldmethod=marker:
2 "
3 " Vim plugin to assist in working with CVS-controlled files.
4 "
5 " Last Change: 2006/02/22
6 " Version: 1.76
7 " Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
8 " License: This file is placed in the public domain.
9 " Credits: {{{1
10 " Mathieu Clabaut for many suggestions and improvements.
11 "
12 " Suresh Govindachar and Jeeva Chelladhurai for finding waaaay
13 " too many bugs.
14 "
15 " Suresh Govindachar (again!) for finding the
16 " fully-folded-last-line-delete bug.
17 "
18 " Albrecht Gass for the Delete-on-Hide behavior suggestion.
19 "
20 " Joe MacDonald for finding the CVS log message header bug and
21 " pointing out that buffer refreshes are needed after CVS
22 " \%(un\)\?edit.
23 "
24 " Srinath Avadhanula for the suggestion and original patch for
25 " the CVSCommitOnWrite option and mapping hot key.
26 "
27 " John Sivak for helping to debug Windows issues and suggesting
28 " the CVSEditors and CVSWatchers commands.
29 "
30 " Igor Levko for the patch to recognize numerical sticky tags.
31 "
32 " Domink Strasser for the patch to correct the status line for
33 " CVSAdd'd files.
34 "
35 " Weerapong Sirikanya for finding a bug with CVSCommit and
36 " autochdir.
37 "
38 " David Gotz for finding a bug with CVSVimDiff buffer splitting
39 " and original buffer restoration.
40 "
41 " CJ van den Berg for the patch to not change working directory
42 " when editing a non-CVS file.
43 "
44 " Luca Gerli for noticing bad behavior for keywords in files
45 " after commit if split windows are used.
46
47 " Section: Documentation {{{1
48 "
49 " Provides functions to invoke various CVS commands on the current file
50 " (either the current buffer, or, in the case of an directory buffer, the file
51 " on the current line). The output of the commands is captured in a new
52 " scratch window. For convenience, if the functions are invoked on a CVS
53 " output window, the original file is used for the cvs operation instead after
54 " the window is split. This is primarily useful when running CVSCommit and
55 " you need to see the changes made, so that CVSDiff is usable and shows up in
56 " another window.
57 "
58 " Command documentation {{{2
59 "
60 " CVSAdd Performs "cvs add" on the current file.
61 "
62 " CVSAnnotate Performs "cvs annotate" on the current file. If an
63 " argument is given, the argument is used as a revision
64 " number to display. If not given an argument, it uses the
65 " most recent version of the file on the current branch.
66 " Additionally, if the current buffer is a CVSAnnotate buffer
67 " already, the version number on the current line is used.
68 "
69 " If the 'CVSCommandAnnotateParent' variable is set to a
70 " non-zero value, the version previous to the one on the
71 " current line is used instead. This allows one to navigate
72 " back to examine the previous version of a line.
73 "
74 " CVSCommit[!] If called with arguments, this performs "cvs commit" using
75 " the arguments as the log message.
76 "
77 " If '!' is used, an empty log message is committed.
78 "
79 " If called with no arguments, this is a two-step command.
80 " The first step opens a buffer to accept a log message.
81 " When that buffer is written, it is automatically closed and
82 " the file is committed using the information from that log
83 " message. The commit can be abandoned if the log message
84 " buffer is deleted or wiped before being written.
85 "
86 " CVSDiff With no arguments, this performs "cvs diff" on the current
87 " file. With one argument, "cvs diff" is performed on the
88 " current file against the specified revision. With two
89 " arguments, cvs diff is performed between the specified
90 " revisions of the current file. This command uses the
91 " 'CVSCommandDiffOpt' variable to specify diff options. If
92 " that variable does not exist, then 'wbBc' is assumed. If
93 " you wish to have no options, then set it to the empty
94 " string.
95 "
96 " CVSEdit Performs "cvs edit" on the current file.
97 "
98 " CVSEditors Performs "cvs editors" on the current file.
99 "
100 " CVSGotoOriginal Returns the current window to the source buffer if the
101 " current buffer is a CVS output buffer.
102 "
103 " CVSLog Performs "cvs log" on the current file.
104 "
105 " CVSRevert Replaces the modified version of the current file with the
106 " most recent version from the repository.
107 "
108 " CVSReview Retrieves a particular version of the current file. If no
109 " argument is given, the most recent version of the file on
110 " the current branch is retrieved. The specified revision is
111 " retrieved into a new buffer.
112 "
113 " CVSStatus Performs "cvs status" on the current file.
114 "
115 " CVSUnedit Performs "cvs unedit" on the current file.
116 "
117 " CVSUpdate Performs "cvs update" on the current file.
118 "
119 " CVSVimDiff With no arguments, this prompts the user for a revision and
120 " then uses vimdiff to display the differences between the
121 " current file and the specified revision. If no revision is
122 " specified, the most recent version of the file on the
123 " current branch is used. With one argument, that argument
124 " is used as the revision as above. With two arguments, the
125 " differences between the two revisions is displayed using
126 " vimdiff.
127 "
128 " With either zero or one argument, the original buffer is used
129 " to perform the vimdiff. When the other buffer is closed, the
130 " original buffer will be returned to normal mode.
131 "
132 " Once vimdiff mode is started using the above methods,
133 " additional vimdiff buffers may be added by passing a single
134 " version argument to the command. There may be up to 4
135 " vimdiff buffers total.
136 "
137 " Using the 2-argument form of the command resets the vimdiff
138 " to only those 2 versions. Additionally, invoking the
139 " command on a different file will close the previous vimdiff
140 " buffers.
141 "
142 " CVSWatch Takes an argument which must be one of [on|off|add|remove].
143 " Performs "cvs watch" with the given argument on the current
144 " file.
145 "
146 " CVSWatchers Performs "cvs watchers" on the current file.
147 "
148 " CVSWatchAdd Alias for "CVSWatch add"
149 "
150 " CVSWatchOn Alias for "CVSWatch on"
151 "
152 " CVSWatchOff Alias for "CVSWatch off"
153 "
154 " CVSWatchRemove Alias for "CVSWatch remove"
155 "
156 " Mapping documentation: {{{2
157 "
158 " By default, a mapping is defined for each command. User-provided mappings
159 " can be used instead by mapping to <Plug>CommandName, for instance:
160 "
161 " nnoremap ,ca <Plug>CVSAdd
162 "
163 " The default mappings are as follow:
164 "
165 " <Leader>ca CVSAdd
166 " <Leader>cn CVSAnnotate
167 " <Leader>cc CVSCommit
168 " <Leader>cd CVSDiff
169 " <Leader>ce CVSEdit
170 " <Leader>ci CVSEditors
171 " <Leader>cg CVSGotoOriginal
172 " <Leader>cG CVSGotoOriginal!
173 " <Leader>cl CVSLog
174 " <Leader>cr CVSReview
175 " <Leader>cs CVSStatus
176 " <Leader>ct CVSUnedit
177 " <Leader>cu CVSUpdate
178 " <Leader>cv CVSVimDiff
179 " <Leader>cwv CVSWatchers
180 " <Leader>cwa CVSWatchAdd
181 " <Leader>cwn CVSWatchOn
182 " <Leader>cwa CVSWatchOff
183 " <Leader>cwr CVSWatchRemove
184 "
185 " Options documentation: {{{2
186 "
187 " Several variables are checked by the script to determine behavior as follow:
188 "
189 " CVSCommandAnnotateParent
190 " This variable, if set to a non-zero value, causes the zero-argument form
191 " of CVSAnnotate when invoked on a CVSAnnotate buffer to go to the version
192 " previous to that displayed on the current line. If not set, it defaults
193 " to 0.
194 "
195 " CVSCommandCommitOnWrite
196 " This variable, if set to a non-zero value, causes the pending cvs commit
197 " to take place immediately as soon as the log message buffer is written.
198 " If set to zero, only the CVSCommit mapping will cause the pending commit
199 " to occur. If not set, it defaults to 1.
200 "
201 " CVSCommandDeleteOnHide
202 " This variable, if set to a non-zero value, causes the temporary CVS result
203 " buffers to automatically delete themselves when hidden.
204 "
205 " CVSCommandDiffOpt
206 " This variable, if set, determines the options passed to the diff command
207 " of CVS. If not set, it defaults to 'wbBc'.
208 "
209 " CVSCommandDiffSplit
210 " This variable overrides the CVSCommandSplit variable, but only for buffers
211 " created with CVSVimDiff.
212 "
213 " CVSCommandEdit
214 " This variable controls whether the original buffer is replaced ('edit') or
215 " split ('split'). If not set, it defaults to 'edit'.
216 "
217 " CVSCommandEnableBufferSetup
218 " This variable, if set to a non-zero value, activates CVS buffer management
219 " mode. This mode means that two buffer variables, 'CVSRevision' and
220 " 'CVSBranch', are set if the file is CVS-controlled. This is useful for
221 " displaying version information in the status bar.
222 "
223 " CVSCommandInteractive
224 " This variable, if set to a non-zero value, causes appropriate functions (for
225 " the moment, only CVSReview) to query the user for a revision to use
226 " instead of the current revision if none is specified.
227 "
228 " CVSCommandNameMarker
229 " This variable, if set, configures the special attention-getting characters
230 " that appear on either side of the cvs buffer type in the buffer name.
231 " This has no effect unless 'CVSCommandNameResultBuffers' is set to a true
232 " value. If not set, it defaults to '_'.
233 "
234 " CVSCommandNameResultBuffers
235 " This variable, if set to a true value, causes the cvs result buffers to be
236 " named in the old way ('<source file name> _<cvs command>_'). If not set
237 " or set to a false value, the result buffer is nameless.
238 "
239 " CVSCommandSplit
240 " This variable controls the orientation of the various window splits that
241 " may occur (such as with CVSVimDiff, when using a CVS command on a CVS
242 " command buffer, or when the 'CVSCommandEdit' variable is set to 'split'.
243 " If set to 'horizontal', the resulting windows will be on stacked on top of
244 " one another. If set to 'vertical', the resulting windows will be
245 " side-by-side. If not set, it defaults to 'horizontal' for all but
246 " CVSVimDiff windows.
247 "
248 " Event documentation {{{2
249 " For additional customization, cvscommand.vim uses User event autocommand
250 " hooks. Each event is in the CVSCommand group, and different patterns
251 " match the various hooks.
252 "
253 " For instance, the following could be added to the vimrc to provide a 'q'
254 " mapping to quit a CVS buffer:
255 "
256 " augroup CVSCommand
257 " au CVSCommand User CVSBufferCreated silent! nmap <unique> <buffer> q :bwipeout<cr>
258 " augroup END
259 "
260 " The following hooks are available:
261 "
262 " CVSBufferCreated This event is fired just after a cvs command
263 " result buffer is created and filled with the
264 " result of a cvs command. It is executed within
265 " the context of the new buffer.
266 "
267 " CVSBufferSetup This event is fired just after CVS buffer setup
268 " occurs, if enabled.
269 "
270 " CVSPluginInit This event is fired when the CVSCommand plugin
271 " first loads.
272 "
273 " CVSPluginFinish This event is fired just after the CVSCommand
274 " plugin loads.
275 "
276 " CVSVimDiffFinish This event is fired just after the CVSVimDiff
277 " command executes to allow customization of,
278 " for instance, window placement and focus.
279 "
280 " Section: Plugin header {{{1
281
282 " loaded_cvscommand is set to 1 when the initialization begins, and 2 when it
283 " completes. This allows various actions to only be taken by functions after
284 " system initialization.
285
286 if exists("loaded_cvscommand")
287 finish
288 endif
289 let loaded_cvscommand = 1
290
291 if v:version < 602
292 echohl WarningMsg|echomsg "CVSCommand 1.69 or later requires VIM 6.2 or later"|echohl None
293 finish
294 endif
295
296 " Section: Event group setup {{{1
297
298 augroup CVSCommand
299 augroup END
300
301 " Section: Plugin initialization {{{1
302 silent do CVSCommand User CVSPluginInit
303
304 " Section: Script variable initialization {{{1
305
306 let s:CVSCommandEditFileRunning = 0
307 unlet! s:vimDiffRestoreCmd
308 unlet! s:vimDiffSourceBuffer
309 unlet! s:vimDiffBufferCount
310 unlet! s:vimDiffScratchList
311
312 " Section: Utility functions {{{1
313
314 " Function: s:CVSResolveLink() {{{2
315 " Fully resolve the given file name to remove shortcuts or symbolic links.
316
317 function! s:CVSResolveLink(fileName)
318 let resolved = resolve(a:fileName)
319 if resolved != a:fileName
320 let resolved = s:CVSResolveLink(resolved)
321 endif
322 return resolved
323 endfunction
324
325 " Function: s:CVSChangeToCurrentFileDir() {{{2
326 " Go to the directory in which the current CVS-controlled file is located.
327 " If this is a CVS command buffer, first switch to the original file.
328
329 function! s:CVSChangeToCurrentFileDir(fileName)
330 let oldCwd=getcwd()
331 let fileName=s:CVSResolveLink(a:fileName)
332 let newCwd=fnamemodify(fileName, ':h')
333 if strlen(newCwd) > 0
334 execute 'cd' escape(newCwd, ' ')
335 endif
336 return oldCwd
337 endfunction
338
339 " Function: s:CVSGetOption(name, default) {{{2
340 " Grab a user-specified option to override the default provided. Options are
341 " searched in the window, buffer, then global spaces.
342
343 function! s:CVSGetOption(name, default)
344 if exists("s:" . a:name . "Override")
345 execute "return s:".a:name."Override"
346 elseif exists("w:" . a:name)
347 execute "return w:".a:name
348 elseif exists("b:" . a:name)
349 execute "return b:".a:name
350 elseif exists("g:" . a:name)
351 execute "return g:".a:name
352 else
353 return a:default
354 endif
355 endfunction
356
357 " Function: s:CVSEditFile(name, origBuffNR) {{{2
358 " Wrapper around the 'edit' command to provide some helpful error text if the
359 " current buffer can't be abandoned. If name is provided, it is used;
360 " otherwise, a nameless scratch buffer is used.
361 " Returns: 0 if successful, -1 if an error occurs.
362
363 function! s:CVSEditFile(name, origBuffNR)
364 "Name parameter will be pasted into expression.
365 let name = escape(a:name, ' *?\')
366
367 let editCommand = s:CVSGetOption('CVSCommandEdit', 'edit')
368 if editCommand != 'edit'
369 if s:CVSGetOption('CVSCommandSplit', 'horizontal') == 'horizontal'
370 if name == ""
371 let editCommand = 'rightbelow new'
372 else
373 let editCommand = 'rightbelow split ' . name
374 endif
375 else
376 if name == ""
377 let editCommand = 'vert rightbelow new'
378 else
379 let editCommand = 'vert rightbelow split ' . name
380 endif
381 endif
382 else
383 if name == ""
384 let editCommand = 'enew'
385 else
386 let editCommand = 'edit ' . name
387 endif
388 endif
389
390 " Protect against useless buffer set-up
391 let s:CVSCommandEditFileRunning = s:CVSCommandEditFileRunning + 1
392 try
393 execute editCommand
394 finally
395 let s:CVSCommandEditFileRunning = s:CVSCommandEditFileRunning - 1
396 endtry
397
398 let b:CVSOrigBuffNR=a:origBuffNR
399 let b:CVSCommandEdit='split'
400 endfunction
401
402 " Function: s:CVSCreateCommandBuffer(cmd, cmdName, statusText, filename) {{{2
403 " Creates a new scratch buffer and captures the output from execution of the
404 " given command. The name of the scratch buffer is returned.
405
406 function! s:CVSCreateCommandBuffer(cmd, cmdName, statusText, origBuffNR)
407 let fileName=bufname(a:origBuffNR)
408
409 let resultBufferName=''
410
411 if s:CVSGetOption("CVSCommandNameResultBuffers", 0)
412 let nameMarker = s:CVSGetOption("CVSCommandNameMarker", '_')
413 if strlen(a:statusText) > 0
414 let bufName=a:cmdName . ' -- ' . a:statusText
415 else
416 let bufName=a:cmdName
417 endif
418 let bufName=fileName . ' ' . nameMarker . bufName . nameMarker
419 let counter=0
420 let resultBufferName = bufName
421 while buflisted(resultBufferName)
422 let counter=counter + 1
423 let resultBufferName=bufName . ' (' . counter . ')'
424 endwhile
425 endif
426
427 let cvsCommand = s:CVSGetOption("CVSCommandCVSExec", "cvs") . " " . a:cmd
428 let cvsOut = system(cvsCommand)
429 " HACK: diff command does not return proper error codes
430 if v:shell_error && a:cmdName != 'cvsdiff'
431 if strlen(cvsOut) == 0
432 echoerr "CVS command failed"
433 else
434 echoerr "CVS command failed: " . cvsOut
435 endif
436 return -1
437 endif
438 if strlen(cvsOut) == 0
439 " Handle case of no output. In this case, it is important to check the
440 " file status, especially since cvs edit/unedit may change the attributes
441 " of the file with no visible output.
442
443 echomsg "No output from CVS command"
444 checktime
445 return -1
446 endif
447
448 if s:CVSEditFile(resultBufferName, a:origBuffNR) == -1
449 return -1
450 endif
451
452 set buftype=nofile
453 set noswapfile
454 set filetype=
455
456 if s:CVSGetOption("CVSCommandDeleteOnHide", 0)
457 set bufhidden=delete
458 endif
459
460 silent 0put=cvsOut
461
462 " The last command left a blank line at the end of the buffer. If the
463 " last line is folded (a side effect of the 'put') then the attempt to
464 " remove the blank line will kill the last fold.
465 "
466 " This could be fixed by explicitly detecting whether the last line is
467 " within a fold, but I prefer to simply unfold the result buffer altogether.
468
469 if has('folding')
470 normal zR
471 endif
472
473 $d
474 1
475
476 " Define the environment and execute user-defined hooks.
477
478 let b:CVSSourceFile=fileName
479 let b:CVSCommand=a:cmdName
480 if a:statusText != ""
481 let b:CVSStatusText=a:statusText
482 endif
483
484 silent do CVSCommand User CVSBufferCreated
485 return bufnr("%")
486 endfunction
487
488 " Function: s:CVSBufferCheck(cvsBuffer) {{{2
489 " Attempts to locate the original file to which CVS operations were applied
490 " for a given buffer.
491
492 function! s:CVSBufferCheck(cvsBuffer)
493 let origBuffer = getbufvar(a:cvsBuffer, "CVSOrigBuffNR")
494 if origBuffer
495 if bufexists(origBuffer)
496 return origBuffer
497 else
498 " Original buffer no longer exists.
499 return -1
500 endif
501 else
502 " No original buffer
503 return a:cvsBuffer
504 endif
505 endfunction
506
507 " Function: s:CVSCurrentBufferCheck() {{{2
508 " Attempts to locate the original file to which CVS operations were applied
509 " for the current buffer.
510
511 function! s:CVSCurrentBufferCheck()
512 return s:CVSBufferCheck(bufnr("%"))
513 endfunction
514
515 " Function: s:CVSToggleDeleteOnHide() {{{2
516 " Toggles on and off the delete-on-hide behavior of CVS buffers
517
518 function! s:CVSToggleDeleteOnHide()
519 if exists("g:CVSCommandDeleteOnHide")
520 unlet g:CVSCommandDeleteOnHide
521 else
522 let g:CVSCommandDeleteOnHide=1
523 endif
524 endfunction
525
526 " Function: s:CVSDoCommand(cvscmd, cmdName, statusText) {{{2
527 " General skeleton for CVS function execution.
528 " Returns: name of the new command buffer containing the command results
529
530 function! s:CVSDoCommand(cmd, cmdName, statusText)
531 let cvsBufferCheck=s:CVSCurrentBufferCheck()
532 if cvsBufferCheck == -1
533 echo "Original buffer no longer exists, aborting."
534 return -1
535 endif
536
537 let fileName=bufname(cvsBufferCheck)
538 if isdirectory(fileName)
539 let fileName=fileName . "/" . getline(".")
540 endif
541 let realFileName = fnamemodify(s:CVSResolveLink(fileName), ':t')
542 let oldCwd=s:CVSChangeToCurrentFileDir(fileName)
543 try
544 if !filereadable('CVS/Root')
545 throw fileName . ' is not a CVS-controlled file.'
546 endif
547 let fullCmd = a:cmd . ' "' . realFileName . '"'
548 let resultBuffer=s:CVSCreateCommandBuffer(fullCmd, a:cmdName, a:statusText, cvsBufferCheck)
549 return resultBuffer
550 catch
551 echoerr v:exception
552 return -1
553 finally
554 execute 'cd' escape(oldCwd, ' ')
555 endtry
556 endfunction
557
558
559 " Function: s:CVSGetStatusVars(revision, branch, repository) {{{2
560 "
561 " Obtains a CVS revision number and branch name. The 'revisionVar',
562 " 'branchVar'and 'repositoryVar' arguments, if non-empty, contain the names of variables to hold
563 " the corresponding results.
564 "
565 " Returns: string to be exec'd that sets the multiple return values.
566
567 function! s:CVSGetStatusVars(revisionVar, branchVar, repositoryVar)
568 let cvsBufferCheck=s:CVSCurrentBufferCheck()
569 if cvsBufferCheck == -1
570 return ""
571 endif
572 let fileName=bufname(cvsBufferCheck)
573 let realFileName = fnamemodify(s:CVSResolveLink(fileName), ':t')
574 let oldCwd=s:CVSChangeToCurrentFileDir(fileName)
575 try
576 if !filereadable('CVS/Root')
577 return ""
578 endif
579 let cvsCommand = s:CVSGetOption("CVSCommandCVSExec", "cvs") . " status " . escape(realFileName, ' *?\')
580 let statustext=system(cvsCommand)
581 if(v:shell_error)
582 return ""
583 endif
584 let revision=substitute(statustext, '^\_.*Working revision:\s*\(\d\+\%(\.\d\+\)\+\|New file!\)\_.*$', '\1', "")
585
586 " We can still be in a CVS-controlled directory without this being a CVS
587 " file
588 if match(revision, '^New file!$') >= 0
589 let revision="NEW"
590 elseif match(revision, '^\d\+\.\d\+\%(\.\d\+\.\d\+\)*$') >=0
591 else
592 return ""
593 endif
594
595 let returnExpression = "let " . a:revisionVar . "='" . revision . "'"
596
597 if a:branchVar != ""
598 let branch=substitute(statustext, '^\_.*Sticky Tag:\s\+\(\d\+\%(\.\d\+\)\+\|\a[A-Za-z0-9-_]*\|(none)\).*$', '\1', "")
599 let returnExpression=returnExpression . " | let " . a:branchVar . "='" . branch . "'"
600 endif
601
602 if a:repositoryVar != ""
603 let repository=substitute(statustext, '^\_.*Repository revision:\s*\(\d\+\%(\.\d\+\)\+\|New file!\|No revision control file\)\_.*$', '\1', "")
604 let repository=substitute(repository, '^New file!\|No revision control file$', 'NEW', "")
605 let returnExpression=returnExpression . " | let " . a:repositoryVar . "='" . repository . "'"
606 endif
607
608 return returnExpression
609 finally
610 execute 'cd' escape(oldCwd, ' ')
611 endtry
612 endfunction
613
614 " Function: s:CVSSetupBuffer() {{{2
615 " Attempts to set the b:CVSBranch, b:CVSRevision and b:CVSRepository variables.
616
617 function! s:CVSSetupBuffer()
618 if (exists("b:CVSBufferSetup") && b:CVSBufferSetup)
619 " This buffer is already set up.
620 return
621 endif
622
623 if !s:CVSGetOption("CVSCommandEnableBufferSetup", 0)
624 \ || @% == ""
625 \ || s:CVSCommandEditFileRunning > 0
626 \ || exists("b:CVSOrigBuffNR")
627 unlet! b:CVSRevision
628 unlet! b:CVSBranch
629 unlet! b:CVSRepository
630 return
631 endif
632
633 if !filereadable(expand("%"))
634 return -1
635 endif
636
637 let revision=""
638 let branch=""
639 let repository=""
640
641 exec s:CVSGetStatusVars('revision', 'branch', 'repository')
642 if revision != ""
643 let b:CVSRevision=revision
644 else
645 unlet! b:CVSRevision
646 endif
647 if branch != ""
648 let b:CVSBranch=branch
649 else
650 unlet! b:CVSBranch
651 endif
652 if repository != ""
653 let b:CVSRepository=repository
654 else
655 unlet! b:CVSRepository
656 endif
657 silent do CVSCommand User CVSBufferSetup
658 let b:CVSBufferSetup=1
659 endfunction
660
661 " Function: s:CVSMarkOrigBufferForSetup(cvsbuffer) {{{2
662 " Resets the buffer setup state of the original buffer for a given CVS buffer.
663 " Returns: The CVS buffer number in a passthrough mode.
664
665 function! s:CVSMarkOrigBufferForSetup(cvsBuffer)
666 checktime
667 if a:cvsBuffer != -1
668 let origBuffer = s:CVSBufferCheck(a:cvsBuffer)
669 "This should never not work, but I'm paranoid
670 if origBuffer != a:cvsBuffer
671 call setbufvar(origBuffer, "CVSBufferSetup", 0)
672 endif
673 endif
674 return a:cvsBuffer
675 endfunction
676
677 " Function: s:CVSOverrideOption(option, [value]) {{{2
678 " Provides a temporary override for the given CVS option. If no value is
679 " passed, the override is disabled.
680
681 function! s:CVSOverrideOption(option, ...)
682 if a:0 == 0
683 unlet! s:{a:option}Override
684 else
685 let s:{a:option}Override = a:1
686 endif
687 endfunction
688
689 " Function: s:CVSWipeoutCommandBuffers() {{{2
690 " Clears all current CVS buffers of the specified type for a given source.
691
692 function! s:CVSWipeoutCommandBuffers(originalBuffer, cvsCommand)
693 let buffer = 1
694 while buffer <= bufnr('$')
695 if getbufvar(buffer, 'CVSOrigBuffNR') == a:originalBuffer
696 if getbufvar(buffer, 'CVSCommand') == a:cvsCommand
697 execute 'bw' buffer
698 endif
699 endif
700 let buffer = buffer + 1
701 endwhile
702 endfunction
703
704 " Section: Public functions {{{1
705
706 " Function: CVSGetRevision() {{{2
707 " Global function for retrieving the current buffer's CVS revision number.
708 " Returns: Revision number or an empty string if an error occurs.
709
710 function! CVSGetRevision()
711 let revision=""
712 exec s:CVSGetStatusVars('revision', '', '')
713 return revision
714 endfunction
715
716 " Function: CVSDisableBufferSetup() {{{2
717 " Global function for deactivating the buffer autovariables.
718
719 function! CVSDisableBufferSetup()
720 let g:CVSCommandEnableBufferSetup=0
721 silent! augroup! CVSCommandPlugin
722 endfunction
723
724 " Function: CVSEnableBufferSetup() {{{2
725 " Global function for activating the buffer autovariables.
726
727 function! CVSEnableBufferSetup()
728 let g:CVSCommandEnableBufferSetup=1
729 augroup CVSCommandPlugin
730 au!
731 au BufEnter * call s:CVSSetupBuffer()
732 augroup END
733
734 " Only auto-load if the plugin is fully loaded. This gives other plugins a
735 " chance to run.
736 if g:loaded_cvscommand == 2
737 call s:CVSSetupBuffer()
738 endif
739 endfunction
740
741 " Function: CVSGetStatusLine() {{{2
742 " Default (sample) status line entry for CVS files. This is only useful if
743 " CVS-managed buffer mode is on (see the CVSCommandEnableBufferSetup variable
744 " for how to do this).
745
746 function! CVSGetStatusLine()
747 if exists('b:CVSSourceFile')
748 " This is a result buffer
749 let value='[' . b:CVSCommand . ' ' . b:CVSSourceFile
750 if exists('b:CVSStatusText')
751 let value=value . ' ' . b:CVSStatusText
752 endif
753 let value = value . ']'
754 return value
755 endif
756
757 if exists('b:CVSRevision')
758 \ && b:CVSRevision != ''
759 \ && exists('b:CVSBranch')
760 \ && b:CVSBranch != ''
761 \ && exists('b:CVSRepository')
762 \ && b:CVSRepository != ''
763 \ && exists('g:CVSCommandEnableBufferSetup')
764 \ && g:CVSCommandEnableBufferSetup
765 if b:CVSRevision == b:CVSRepository
766 return '[CVS ' . b:CVSBranch . '/' . b:CVSRevision . ']'
767 else
768 return '[CVS ' . b:CVSBranch . '/' . b:CVSRevision . '/' . b:CVSRepository . ']'
769 endif
770 else
771 return ''
772 endif
773 endfunction
774
775 " Section: CVS command functions {{{1
776
777 " Function: s:CVSAdd() {{{2
778 function! s:CVSAdd()
779 return s:CVSMarkOrigBufferForSetup(s:CVSDoCommand('add', 'cvsadd', ''))
780 endfunction
781
782 " Function: s:CVSAnnotate(...) {{{2
783 function! s:CVSAnnotate(...)
784 if a:0 == 0
785 if &filetype == "CVSAnnotate"
786 " This is a CVSAnnotate buffer. Perform annotation of the version
787 " indicated by the current line.
788 let revision = substitute(getline("."),'\(^[0-9.]*\).*','\1','')
789 let revmin = substitute(revision,'^[0-9.]*\.\([0-9]\+\)','\1','')
790 let revmaj = substitute(revision,'^\([0-9.]*\)\.[0-9]\+','\1','')
791 if s:CVSGetOption('CVSCommandAnnotateParent', 0) != 0
792 let revmin = revmin - 1
793 endif
794 if revmin == 0
795 " Jump to ancestor branch
796 let revision = substitute(revmaj,'^\([0-9.]*\)\.[0-9]\+','\1','')
797 else
798 let revision=revmaj . "." . revmin
799 endif
800 else
801 let revision=CVSGetRevision()
802 if revision == ""
803 echoerr "Unable to obtain CVS version information."
804 return -1
805 endif
806 endif
807 else
808 let revision=a:1
809 endif
810
811 if revision == "NEW"
812 echo "No annotatation available for new file."
813 return -1
814 endif
815
816 let resultBuffer=s:CVSDoCommand('-q annotate -r ' . revision, 'cvsannotate', revision)
817 if resultBuffer != -1
818 set filetype=CVSAnnotate
819 " Remove header lines from standard error
820 silent v/^\d\+\%(\.\d\+\)\+/d
821 endif
822
823 return resultBuffer
824 endfunction
825
826 " Function: s:CVSCommit() {{{2
827 function! s:CVSCommit(...)
828 " Handle the commit message being specified. If a message is supplied, it
829 " is used; if bang is supplied, an empty message is used; otherwise, the
830 " user is provided a buffer from which to edit the commit message.
831 if a:2 != "" || a:1 == "!"
832 return s:CVSMarkOrigBufferForSetup(s:CVSDoCommand('commit -m "' . a:2 . '"', 'cvscommit', ''))
833 endif
834
835 let cvsBufferCheck=s:CVSCurrentBufferCheck()
836 if cvsBufferCheck == -1
837 echo "Original buffer no longer exists, aborting."
838 return -1
839 endif
840
841 " Protect against windows' backslashes in paths. They confuse exec'd
842 " commands.
843
844 let shellSlashBak = &shellslash
845 try
846 set shellslash
847
848 let messageFileName = tempname()
849
850 let fileName=bufname(cvsBufferCheck)
851 let realFilePath=s:CVSResolveLink(fileName)
852 let newCwd=fnamemodify(realFilePath, ':h')
853 if strlen(newCwd) == 0
854 " Account for autochdir being in effect, which will make this blank, but
855 " we know we'll be in the current directory for the original file.
856 let newCwd = getcwd()
857 endif
858
859 let realFileName=fnamemodify(realFilePath, ':t')
860
861 if s:CVSEditFile(messageFileName, cvsBufferCheck) == -1
862 return
863 endif
864
865 " Protect against case and backslash issues in Windows.
866 let autoPattern = '\c' . messageFileName
867
868 " Ensure existance of group
869 augroup CVSCommit
870 augroup END
871
872 execute 'au CVSCommit BufDelete' autoPattern 'call delete("' . messageFileName . '")'
873 execute 'au CVSCommit BufDelete' autoPattern 'au! CVSCommit * ' autoPattern
874
875 " Create a commit mapping. The mapping must clear all autocommands in case
876 " it is invoked when CVSCommandCommitOnWrite is active, as well as to not
877 " invoke the buffer deletion autocommand.
878
879 execute 'nnoremap <silent> <buffer> <Plug>CVSCommit '.
880 \ ':au! CVSCommit * ' . autoPattern . '<CR>'.
881 \ ':g/^CVS:/d<CR>'.
882 \ ':update<CR>'.
883 \ ':call <SID>CVSFinishCommit("' . messageFileName . '",' .
884 \ '"' . newCwd . '",' .
885 \ '"' . realFileName . '",' .
886 \ cvsBufferCheck . ')<CR>'
887
888 silent 0put ='CVS: ----------------------------------------------------------------------'
889 silent put =\"CVS: Enter Log. Lines beginning with `CVS:' are removed automatically\"
890 silent put ='CVS: Type <leader>cc (or your own <Plug>CVSCommit mapping)'
891
892 if s:CVSGetOption('CVSCommandCommitOnWrite', 1) == 1
893 execute 'au CVSCommit BufWritePre' autoPattern 'g/^CVS:/d'
894 execute 'au CVSCommit BufWritePost' autoPattern 'call s:CVSFinishCommit("' . messageFileName . '", "' . newCwd . '", "' . realFileName . '", ' . cvsBufferCheck . ') | au! * ' autoPattern
895 silent put ='CVS: or write this buffer'
896 endif
897
898 silent put ='CVS: to finish this commit operation'
899 silent put ='CVS: ----------------------------------------------------------------------'
900 $
901 let b:CVSSourceFile=fileName
902 let b:CVSCommand='CVSCommit'
903 set filetype=cvs
904 finally
905 let &shellslash = shellSlashBak
906 endtry
907
908 endfunction
909
910 " Function: s:CVSDiff(...) {{{2
911 function! s:CVSDiff(...)
912 if a:0 == 1
913 let revOptions = '-r' . a:1
914 let caption = a:1 . ' -> current'
915 elseif a:0 == 2
916 let revOptions = '-r' . a:1 . ' -r' . a:2
917 let caption = a:1 . ' -> ' . a:2
918 else
919 let revOptions = ''
920 let caption = ''
921 endif
922
923 let cvsdiffopt=s:CVSGetOption('CVSCommandDiffOpt', 'wbBc')
924
925 if cvsdiffopt == ""
926 let diffoptionstring=""
927 else
928 let diffoptionstring=" -" . cvsdiffopt . " "
929 endif
930
931 let resultBuffer = s:CVSDoCommand('diff ' . diffoptionstring . revOptions , 'cvsdiff', caption)
932 if resultBuffer != -1
933 set filetype=diff
934 endif
935 return resultBuffer
936 endfunction
937
938 " Function: s:CVSEdit() {{{2
939 function! s:CVSEdit()
940 return s:CVSDoCommand('edit', 'cvsedit', '')
941 endfunction
942
943 " Function: s:CVSEditors() {{{2
944 function! s:CVSEditors()
945 return s:CVSDoCommand('editors', 'cvseditors', '')
946 endfunction
947
948 " Function: s:CVSGotoOriginal(["!]) {{{2
949 function! s:CVSGotoOriginal(...)
950 let origBuffNR = s:CVSCurrentBufferCheck()
951 if origBuffNR > 0
952 let origWinNR = bufwinnr(origBuffNR)
953 if origWinNR == -1
954 execute 'buffer' origBuffNR
955 else
956 execute origWinNR . 'wincmd w'
957 endif
958 if a:0 == 1
959 if a:1 == "!"
960 let buffnr = 1
961 let buffmaxnr = bufnr("$")
962 while buffnr <= buffmaxnr
963 if getbufvar(buffnr, "CVSOrigBuffNR") == origBuffNR
964 execute "bw" buffnr
965 endif
966 let buffnr = buffnr + 1
967 endwhile
968 endif
969 endif
970 endif
971 endfunction
972
973 " Function: s:CVSFinishCommit(messageFile, targetDir, targetFile) {{{2
974 function! s:CVSFinishCommit(messageFile, targetDir, targetFile, origBuffNR)
975 if filereadable(a:messageFile)
976 let oldCwd=getcwd()
977 if strlen(a:targetDir) > 0
978 execute 'cd' escape(a:targetDir, ' ')
979 endif
980 let resultBuffer=s:CVSCreateCommandBuffer('commit -F "' . a:messageFile . '" "'. a:targetFile . '"', 'cvscommit', '', a:origBuffNR)
981 execute 'cd' escape(oldCwd, ' ')
982 execute 'bw' escape(a:messageFile, ' *?\')
983 silent execute 'call delete("' . a:messageFile . '")'
984 return s:CVSMarkOrigBufferForSetup(resultBuffer)
985 else
986 echoerr "Can't read message file; no commit is possible."
987 return -1
988 endif
989 endfunction
990
991 " Function: s:CVSLog() {{{2
992 function! s:CVSLog(...)
993 if a:0 == 0
994 let versionOption = ""
995 let caption = ''
996 else
997 let versionOption=" -r" . a:1
998 let caption = a:1
999 endif
1000
1001 let resultBuffer=s:CVSDoCommand('log' . versionOption, 'cvslog', caption)
1002 if resultBuffer != ""
1003 set filetype=rcslog
1004 endif
1005 return resultBuffer
1006 endfunction
1007
1008 " Function: s:CVSRevert() {{{2
1009 function! s:CVSRevert()
1010 return s:CVSMarkOrigBufferForSetup(s:CVSDoCommand('update -C', 'cvsrevert', ''))
1011 endfunction
1012
1013 " Function: s:CVSReview(...) {{{2
1014 function! s:CVSReview(...)
1015 if a:0 == 0
1016 let versiontag=""
1017 if s:CVSGetOption('CVSCommandInteractive', 0)
1018 let versiontag=input('Revision: ')
1019 endif
1020 if versiontag == ""
1021 let versiontag="(current)"
1022 let versionOption=""
1023 else
1024 let versionOption=" -r " . versiontag . " "
1025 endif
1026 else
1027 let versiontag=a:1
1028 let versionOption=" -r " . versiontag . " "
1029 endif
1030
1031 let resultBuffer = s:CVSDoCommand('-q update -p' . versionOption, 'cvsreview', versiontag)
1032 if resultBuffer > 0
1033 let &filetype=getbufvar(b:CVSOrigBuffNR, '&filetype')
1034 endif
1035
1036 return resultBuffer
1037 endfunction
1038
1039 " Function: s:CVSStatus() {{{2
1040 function! s:CVSStatus()
1041 return s:CVSDoCommand('status', 'cvsstatus', '')
1042 endfunction
1043
1044 " Function: s:CVSUnedit() {{{2
1045 function! s:CVSUnedit()
1046 return s:CVSDoCommand('unedit', 'cvsunedit', '')
1047 endfunction
1048
1049 " Function: s:CVSUpdate() {{{2
1050 function! s:CVSUpdate()
1051 return s:CVSMarkOrigBufferForSetup(s:CVSDoCommand('update', 'update', ''))
1052 endfunction
1053
1054 " Function: s:CVSVimDiff(...) {{{2
1055 function! s:CVSVimDiff(...)
1056 let originalBuffer = s:CVSCurrentBufferCheck()
1057 let s:CVSCommandEditFileRunning = s:CVSCommandEditFileRunning + 1
1058 try
1059 " If there's already a VimDiff'ed window, restore it.
1060 " There may only be one CVSVimDiff original window at a time.
1061
1062 if exists("s:vimDiffSourceBuffer") && s:vimDiffSourceBuffer != originalBuffer
1063 " Clear the existing vimdiff setup by removing the result buffers.
1064 call s:CVSWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')
1065 endif
1066
1067 " Split and diff
1068 if(a:0 == 2)
1069 " Reset the vimdiff system, as 2 explicit versions were provided.
1070 if exists('s:vimDiffSourceBuffer')
1071 call s:CVSWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')
1072 endif
1073 let resultBuffer = s:CVSReview(a:1)
1074 if resultBuffer < 0
1075 echomsg "Can't open CVS revision " . a:1
1076 return resultBuffer
1077 endif
1078 let b:CVSCommand = 'vimdiff'
1079 diffthis
1080 let s:vimDiffBufferCount = 1
1081 let s:vimDiffScratchList = '{'. resultBuffer . '}'
1082 " If no split method is defined, cheat, and set it to vertical.
1083 try
1084 call s:CVSOverrideOption('CVSCommandSplit', s:CVSGetOption('CVSCommandDiffSplit', s:CVSGetOption('CVSCommandSplit', 'vertical')))
1085 let resultBuffer=s:CVSReview(a:2)
1086 finally
1087 call s:CVSOverrideOption('CVSCommandSplit')
1088 endtry
1089 if resultBuffer < 0
1090 echomsg "Can't open CVS revision " . a:1
1091 return resultBuffer
1092 endif
1093 let b:CVSCommand = 'vimdiff'
1094 diffthis
1095 let s:vimDiffBufferCount = 2
1096 let s:vimDiffScratchList = s:vimDiffScratchList . '{'. resultBuffer . '}'
1097 else
1098 " Add new buffer
1099 try
1100 " Force splitting behavior, otherwise why use vimdiff?
1101 call s:CVSOverrideOption("CVSCommandEdit", "split")
1102 call s:CVSOverrideOption("CVSCommandSplit", s:CVSGetOption('CVSCommandDiffSplit', s:CVSGetOption('CVSCommandSplit', 'vertical')))
1103 if(a:0 == 0)
1104 let resultBuffer=s:CVSReview()
1105 else
1106 let resultBuffer=s:CVSReview(a:1)
1107 endif
1108 finally
1109 call s:CVSOverrideOption("CVSCommandEdit")
1110 call s:CVSOverrideOption("CVSCommandSplit")
1111 endtry
1112 if resultBuffer < 0
1113 echomsg "Can't open current CVS revision"
1114 return resultBuffer
1115 endif
1116 let b:CVSCommand = 'vimdiff'
1117 diffthis
1118
1119 if !exists('s:vimDiffBufferCount')
1120 " New instance of vimdiff.
1121 let s:vimDiffBufferCount = 2
1122 let s:vimDiffScratchList = '{' . resultBuffer . '}'
1123
1124 " This could have been invoked on a CVS result buffer, not the
1125 " original buffer.
1126 wincmd W
1127 execute 'buffer' originalBuffer
1128 " Store info for later original buffer restore
1129 let s:vimDiffRestoreCmd =
1130 \ "call setbufvar(".originalBuffer.", \"&diff\", ".getbufvar(originalBuffer, '&diff').")"
1131 \ . "|call setbufvar(".originalBuffer.", \"&foldcolumn\", ".getbufvar(originalBuffer, '&foldcolumn').")"
1132 \ . "|call setbufvar(".originalBuffer.", \"&foldenable\", ".getbufvar(originalBuffer, '&foldenable').")"
1133 \ . "|call setbufvar(".originalBuffer.", \"&foldmethod\", '".getbufvar(originalBuffer, '&foldmethod')."')"
1134 \ . "|call setbufvar(".originalBuffer.", \"&scrollbind\", ".getbufvar(originalBuffer, '&scrollbind').")"
1135 \ . "|call setbufvar(".originalBuffer.", \"&wrap\", ".getbufvar(originalBuffer, '&wrap').")"
1136 \ . "|if &foldmethod=='manual'|execute 'normal zE'|endif"
1137 diffthis
1138 wincmd w
1139 else
1140 " Adding a window to an existing vimdiff
1141 let s:vimDiffBufferCount = s:vimDiffBufferCount + 1
1142 let s:vimDiffScratchList = s:vimDiffScratchList . '{' . resultBuffer . '}'
1143 endif
1144 endif
1145
1146 let s:vimDiffSourceBuffer = originalBuffer
1147
1148 " Avoid executing the modeline in the current buffer after the autocommand.
1149
1150 let currentBuffer = bufnr('%')
1151 let saveModeline = getbufvar(currentBuffer, '&modeline')
1152 try
1153 call setbufvar(currentBuffer, '&modeline', 0)
1154 silent do CVSCommand User CVSVimDiffFinish
1155 finally
1156 call setbufvar(currentBuffer, '&modeline', saveModeline)
1157 endtry
1158 return resultBuffer
1159 finally
1160 let s:CVSCommandEditFileRunning = s:CVSCommandEditFileRunning - 1
1161 endtry
1162 endfunction
1163
1164 " Function: s:CVSWatch(onoff) {{{2
1165 function! s:CVSWatch(onoff)
1166 if a:onoff !~ '^\c\%(on\|off\|add\|remove\)$'
1167 echoerr "Argument to CVSWatch must be one of [on|off|add|remove]"
1168 return -1
1169 end
1170 return s:CVSDoCommand('watch ' . tolower(a:onoff), 'cvswatch', '')
1171 endfunction
1172
1173 " Function: s:CVSWatchers() {{{2
1174 function! s:CVSWatchers()
1175 return s:CVSDoCommand('watchers', 'cvswatchers', '')
1176 endfunction
1177
1178 " Section: Command definitions {{{1
1179 " Section: Primary commands {{{2
1180 com! CVSAdd call s:CVSAdd()
1181 com! -nargs=? CVSAnnotate call s:CVSAnnotate(<f-args>)
1182 com! -bang -nargs=? CVSCommit call s:CVSCommit(<q-bang>, <q-args>)
1183 com! -nargs=* CVSDiff call s:CVSDiff(<f-args>)
1184 com! CVSEdit call s:CVSEdit()
1185 com! CVSEditors call s:CVSEditors()
1186 com! -bang CVSGotoOriginal call s:CVSGotoOriginal(<q-bang>)
1187 com! -nargs=? CVSLog call s:CVSLog(<f-args>)
1188 com! CVSRevert call s:CVSRevert()
1189 com! -nargs=? CVSReview call s:CVSReview(<f-args>)
1190 com! CVSStatus call s:CVSStatus()
1191 com! CVSUnedit call s:CVSUnedit()
1192 com! CVSUpdate call s:CVSUpdate()
1193 com! -nargs=* CVSVimDiff call s:CVSVimDiff(<f-args>)
1194 com! -nargs=1 CVSWatch call s:CVSWatch(<f-args>)
1195 com! CVSWatchAdd call s:CVSWatch('add')
1196 com! CVSWatchOn call s:CVSWatch('on')
1197 com! CVSWatchOff call s:CVSWatch('off')
1198 com! CVSWatchRemove call s:CVSWatch('remove')
1199 com! CVSWatchers call s:CVSWatchers()
1200
1201 " Section: CVS buffer management commands {{{2
1202 com! CVSDisableBufferSetup call CVSDisableBufferSetup()
1203 com! CVSEnableBufferSetup call CVSEnableBufferSetup()
1204
1205 " Allow reloading cvscommand.vim
1206 com! CVSReload unlet! loaded_cvscommand | runtime plugin/cvscommand.vim
1207
1208 " Section: Plugin command mappings {{{1
1209 nnoremap <silent> <Plug>CVSAdd :CVSAdd<CR>
1210 nnoremap <silent> <Plug>CVSAnnotate :CVSAnnotate<CR>
1211 nnoremap <silent> <Plug>CVSCommit :CVSCommit<CR>
1212 nnoremap <silent> <Plug>CVSDiff :CVSDiff<CR>
1213 nnoremap <silent> <Plug>CVSEdit :CVSEdit<CR>
1214 nnoremap <silent> <Plug>CVSEditors :CVSEditors<CR>
1215 nnoremap <silent> <Plug>CVSGotoOriginal :CVSGotoOriginal<CR>
1216 nnoremap <silent> <Plug>CVSClearAndGotoOriginal :CVSGotoOriginal!<CR>
1217 nnoremap <silent> <Plug>CVSLog :CVSLog<CR>
1218 nnoremap <silent> <Plug>CVSRevert :CVSRevert<CR>
1219 nnoremap <silent> <Plug>CVSReview :CVSReview<CR>
1220 nnoremap <silent> <Plug>CVSStatus :CVSStatus<CR>
1221 nnoremap <silent> <Plug>CVSUnedit :CVSUnedit<CR>
1222 nnoremap <silent> <Plug>CVSUpdate :CVSUpdate<CR>
1223 nnoremap <silent> <Plug>CVSVimDiff :CVSVimDiff<CR>
1224 nnoremap <silent> <Plug>CVSWatchers :CVSWatchers<CR>
1225 nnoremap <silent> <Plug>CVSWatchAdd :CVSWatchAdd<CR>
1226 nnoremap <silent> <Plug>CVSWatchOn :CVSWatchOn<CR>
1227 nnoremap <silent> <Plug>CVSWatchOff :CVSWatchOff<CR>
1228 nnoremap <silent> <Plug>CVSWatchRemove :CVSWatchRemove<CR>
1229
1230 " Section: Default mappings {{{1
1231 if !hasmapto('<Plug>CVSAdd')
1232 nmap <unique> <Leader>ca <Plug>CVSAdd
1233 endif
1234 if !hasmapto('<Plug>CVSAnnotate')
1235 nmap <unique> <Leader>cn <Plug>CVSAnnotate
1236 endif
1237 if !hasmapto('<Plug>CVSClearAndGotoOriginal')
1238 nmap <unique> <Leader>cG <Plug>CVSClearAndGotoOriginal
1239 endif
1240 if !hasmapto('<Plug>CVSCommit')
1241 nmap <unique> <Leader>cc <Plug>CVSCommit
1242 endif
1243 if !hasmapto('<Plug>CVSDiff')
1244 nmap <unique> <Leader>cd <Plug>CVSDiff
1245 endif
1246 if !hasmapto('<Plug>CVSEdit')
1247 nmap <unique> <Leader>ce <Plug>CVSEdit
1248 endif
1249 if !hasmapto('<Plug>CVSEditors')
1250 nmap <unique> <Leader>ci <Plug>CVSEditors
1251 endif
1252 if !hasmapto('<Plug>CVSGotoOriginal')
1253 nmap <unique> <Leader>cg <Plug>CVSGotoOriginal
1254 endif
1255 if !hasmapto('<Plug>CVSLog')
1256 nmap <unique> <Leader>cl <Plug>CVSLog
1257 endif
1258 if !hasmapto('<Plug>CVSRevert')
1259 nmap <unique> <Leader>cq <Plug>CVSRevert
1260 endif
1261 if !hasmapto('<Plug>CVSReview')
1262 nmap <unique> <Leader>cr <Plug>CVSReview
1263 endif
1264 if !hasmapto('<Plug>CVSStatus')
1265 nmap <unique> <Leader>cs <Plug>CVSStatus
1266 endif
1267 if !hasmapto('<Plug>CVSUnedit')
1268 nmap <unique> <Leader>ct <Plug>CVSUnedit
1269 endif
1270 if !hasmapto('<Plug>CVSUpdate')
1271 nmap <unique> <Leader>cu <Plug>CVSUpdate
1272 endif
1273 if !hasmapto('<Plug>CVSVimDiff')
1274 nmap <unique> <Leader>cv <Plug>CVSVimDiff
1275 endif
1276 if !hasmapto('<Plug>CVSWatchers')
1277 nmap <unique> <Leader>cwv <Plug>CVSWatchers
1278 endif
1279 if !hasmapto('<Plug>CVSWatchAdd')
1280 nmap <unique> <Leader>cwa <Plug>CVSWatchAdd
1281 endif
1282 if !hasmapto('<Plug>CVSWatchOn')
1283 nmap <unique> <Leader>cwn <Plug>CVSWatchOn
1284 endif
1285 if !hasmapto('<Plug>CVSWatchOff')
1286 nmap <unique> <Leader>cwf <Plug>CVSWatchOff
1287 endif
1288 if !hasmapto('<Plug>CVSWatchRemove')
1289 nmap <unique> <Leader>cwr <Plug>CVSWatchRemove
1290 endif
1291
1292 " Section: Menu items {{{1
1293 silent! aunmenu Plugin.CVS
1294 amenu <silent> &Plugin.CVS.&Add <Plug>CVSAdd
1295 amenu <silent> &Plugin.CVS.A&nnotate <Plug>CVSAnnotate
1296 amenu <silent> &Plugin.CVS.&Commit <Plug>CVSCommit
1297 amenu <silent> &Plugin.CVS.&Diff <Plug>CVSDiff
1298 amenu <silent> &Plugin.CVS.&Edit <Plug>CVSEdit
1299 amenu <silent> &Plugin.CVS.Ed&itors <Plug>CVSEditors
1300 amenu <silent> &Plugin.CVS.&Log <Plug>CVSLog
1301 amenu <silent> &Plugin.CVS.Revert <Plug>CVSRevert
1302 amenu <silent> &Plugin.CVS.&Review <Plug>CVSReview
1303 amenu <silent> &Plugin.CVS.&Status <Plug>CVSStatus
1304 amenu <silent> &Plugin.CVS.Unedi&t <Plug>CVSUnedit
1305 amenu <silent> &Plugin.CVS.&Update <Plug>CVSUpdate
1306 amenu <silent> &Plugin.CVS.&VimDiff <Plug>CVSVimDiff
1307 amenu <silent> &Plugin.CVS.&Watchers <Plug>CVSWatchers
1308 amenu <silent> &Plugin.CVS.WatchAdd <Plug>CVSWatchAdd
1309 amenu <silent> &Plugin.CVS.WatchOn <Plug>CVSWatchOn
1310 amenu <silent> &Plugin.CVS.WatchOff <Plug>CVSWatchOff
1311 amenu <silent> &Plugin.CVS.WatchRemove <Plug>CVSWatchRemove
1312
1313 " Section: Autocommands to restore vimdiff state {{{1
1314 function! s:CVSVimDiffRestore(vimDiffBuff)
1315 let s:CVSCommandEditFileRunning = s:CVSCommandEditFileRunning + 1
1316 try
1317 if exists("s:vimDiffSourceBuffer")
1318 if a:vimDiffBuff == s:vimDiffSourceBuffer
1319 " Original file is being removed.
1320 unlet! s:vimDiffSourceBuffer
1321 unlet! s:vimDiffBufferCount
1322 unlet! s:vimDiffRestoreCmd
1323 unlet! s:vimDiffScratchList
1324 elseif match(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}') >= 0
1325 let s:vimDiffScratchList = substitute(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}', '', '')
1326 let s:vimDiffBufferCount = s:vimDiffBufferCount - 1
1327 if s:vimDiffBufferCount == 1 && exists('s:vimDiffRestoreCmd')
1328 " All scratch buffers are gone, reset the original.
1329 " Only restore if the source buffer is still in Diff mode
1330
1331 let sourceWinNR=bufwinnr(s:vimDiffSourceBuffer)
1332 if sourceWinNR != -1
1333 " The buffer is visible in at least one window
1334 let currentWinNR = winnr()
1335 while winbufnr(sourceWinNR) != -1
1336 if winbufnr(sourceWinNR) == s:vimDiffSourceBuffer
1337 execute sourceWinNR . 'wincmd w'
1338 if getwinvar('', "&diff")
1339 execute s:vimDiffRestoreCmd
1340 endif
1341 endif
1342 let sourceWinNR = sourceWinNR + 1
1343 endwhile
1344 execute currentWinNR . 'wincmd w'
1345 else
1346 " The buffer is hidden. It must be visible in order to set the
1347 " diff option.
1348 let currentBufNR = bufnr('')
1349 execute "hide buffer" s:vimDiffSourceBuffer
1350 if getwinvar('', "&diff")
1351 execute s:vimDiffRestoreCmd
1352 endif
1353 execute "hide buffer" currentBufNR
1354 endif
1355
1356 unlet s:vimDiffRestoreCmd
1357 unlet s:vimDiffSourceBuffer
1358 unlet s:vimDiffBufferCount
1359 unlet s:vimDiffScratchList
1360 elseif s:vimDiffBufferCount == 0
1361 " All buffers are gone.
1362 unlet s:vimDiffSourceBuffer
1363 unlet s:vimDiffBufferCount
1364 unlet s:vimDiffScratchList
1365 endif
1366 endif
1367 endif
1368 finally
1369 let s:CVSCommandEditFileRunning = s:CVSCommandEditFileRunning - 1
1370 endtry
1371 endfunction
1372
1373 augroup CVSVimDiffRestore
1374 au!
1375 au BufUnload * call s:CVSVimDiffRestore(expand("<abuf>"))
1376 augroup END
1377
1378 " Section: Optional activation of buffer management {{{1
1379
1380 if s:CVSGetOption('CVSCommandEnableBufferSetup', 0)
1381 call CVSEnableBufferSetup()
1382 endif
1383
1384 " Section: Plugin completion {{{1
1385
1386 let loaded_cvscommand=2
1387 silent do CVSCommand User CVSPluginFinish