##// END OF EJS Templates
Addition of CVScommand vim script as a base for HGcommand
"Mathieu Clabaut " -
r2591:61f2008c default
parent child Browse files
Show More
@@ -0,0 +1,27 b''
1 " $Id: CVSAnnotate.vim,v 1.5 2002/10/01 21:34:02 rhiestan Exp $
2 " Vim syntax file
3 " Language: CVS annotate output
4 " Maintainer: Bob Hiestand <bob@hiestandfamily.org>
5 " Last Change: $Date: 2002/10/01 21:34:02 $
6 " Remark: Used by the cvscommand plugin. Originally written by Mathieu
7 " Clabaut
8 if version < 600
9 syntax clear
10 elseif exists("b:current_syntax")
11 finish
12 endif
13
14 syn match cvsDate /\S\S\S \S\+ \d\+ \d\+:\d\+:\d\+ \d\+ [+-]\?\d\+/ contained
15 syn match cvsName /^\s*\S\+ / contained nextgroup=cvsVer
16 syn match cvsVer /\d\+ / contained nextgroup=cvsDate
17 syn region cvsHead start="^" end=":" contains=cvsVer,cvsName,cvsDate
18
19 if !exists("did_cvsannotate_syntax_inits")
20 let did_cvsannotate_syntax_inits = 1
21 hi link cvsText String
22 hi link cvsDate Comment
23 hi link cvsName Type
24 hi link cvsVer Statement
25 endif
26
27 let b:current_syntax="CVSAnnotate"
This diff has been collapsed as it changes many lines, (617 lines changed) Show them Hide them
@@ -0,0 +1,617 b''
1 *cvscommand.txt* CVSCommand
2
3 For instructions on installing this file, type
4 :help add-local-help
5 inside Vim.
6
7 Author: Bob Hiestand <bob.hiestand@gmail.com>
8 Credits: Benji Fisher's excellent MatchIt documentation
9
10 ==============================================================================
11 1. Contents *cvscommand-contents*
12
13 Installation : |cvscommand-install|
14 CVSCommand Intro : |cvscommand|
15 CVSCommand Manual : |cvscommand-manual|
16 Customization : |cvscommand-customize|
17 SSH "integration" : |cvscommand-ssh|
18 Bugs : |cvscommand-bugs|
19
20 ==============================================================================
21
22 2. CVSCommand Installation *cvscommand-install*
23
24 The CVSCommand plugin comprises two files, cvscommand.vim and cvscommand.txt
25 (this file). In order to install the plugin, place the cvscommand.vim file
26 into a plugin' directory in your runtime path (please see |add-global-plugin|
27 and |'runtimepath'|.
28
29 CVSCommand may be customized by setting variables, creating maps, and
30 specifying event handlers. Please see |cvscommand-customize| for more
31 details.
32
33 This help file can be included in the VIM help system by copying it into a
34 'doc' directory in your runtime path and then executing the |:helptags|
35 command, specifying the full path of the 'doc' directory. Please see
36 |add-local-help| for more details.
37
38 ==============================================================================
39
40 3. CVSCommand Intro *cvscommand*
41 *cvscommand-intro*
42
43 The CVSCommand plugin provides global ex commands for manipulating
44 CVS-controlled source files. In general, each command operates on the current
45 buffer and accomplishes a separate cvs function, such as update, commit, log,
46 and others (please see |cvscommand-commands| for a list of all available
47 commands). The results of each operation are displayed in a scratch buffer.
48 Several buffer variables are defined for those scratch buffers (please see
49 |cvscommand-buffer-variables|).
50
51 The notion of "current file" means either the current buffer, or, in the case
52 of a directory buffer, the file on the current line within the buffer.
53
54 For convenience, any CVSCommand invoked on a CVSCommand scratch buffer acts as
55 though it was invoked on the original file and splits the screen so that the
56 output appears in a new window.
57
58 Many of the commands accept revisions as arguments. By default, most operate
59 on the most recent revision on the current branch if no revision is specified
60 (though see |CVSCommandInteractive| to prompt instead).
61
62 Each CVSCommand is mapped to a key sequence starting with the <Leader>
63 keystroke. The default mappings may be overridden by supplying different
64 mappings before the plugin is loaded, such as in the vimrc, in the standard
65 fashion for plugin mappings. For examples, please see
66 |cvscommand-mappings-override|.
67
68 The CVSCommand plugin may be configured in several ways. For more details,
69 please see |cvscommand-customize|.
70
71 ==============================================================================
72
73 4. CVSCommand Manual *cvscommand-manual*
74
75 4.1 CVSCommand commands *cvscommand-commands*
76
77 CVSCommand defines the following commands:
78
79 |:CVSAdd|
80 |:CVSAnnotate|
81 |:CVSCommit|
82 |:CVSDiff|
83 |:CVSEdit|
84 |:CVSEditors|
85 |:CVSGotoOriginal|
86 |:CVSLog|
87 |:CVSRevert|
88 |:CVSReview|
89 |:CVSStatus|
90 |:CVSUnedit|
91 |:CVSUpdate|
92 |:CVSVimDiff|
93 |:CVSWatch|
94 |:CVSWatchAdd|
95 |:CVSWatchOn|
96 |:CVSWatchOff|
97 |:CVSWatchRemove|
98 |:CVSWatchers|
99
100 :CVSAdd *:CVSAdd*
101
102 This command performs "cvs add" on the current file. Please note, this does
103 not commit the newly-added file.
104
105 :CVSAnnotate *:CVSAnnotate*
106
107 This command performs "cvs annotate" on the current file. If an argument is
108 given, the argument is used as a revision number to display. If not given an
109 argument, it uses the most recent version of the file on the current branch.
110 Additionally, if the current buffer is a CVSAnnotate buffer already, the
111 version number on the current line is used.
112
113 If the |CVSCommandAnnotateParent| variable is set to a non-zero value, the
114 version previous to the one on the current line is used instead. This allows
115 one to navigate back to examine the previous version of a line.
116
117 The filetype of the CVSCommand scratch buffer is set to 'CVSAnnotate', to take
118 advantage of the bundled syntax file.
119
120
121 :CVSCommit[!] *:CVSCommit*
122
123 If called with arguments, this performs "cvs commit" using the arguments as
124 the log message.
125
126 If '!' is used with no arguments, an empty log message is committed.
127
128 If called with no arguments, this is a two-step command. The first step opens
129 a buffer to accept a log message. When that buffer is written, it is
130 automatically closed and the file is committed using the information from that
131 log message. The commit can be abandoned if the log message buffer is deleted
132 or wiped before being written.
133
134 Alternatively, the mapping that is used to invoke :CVSCommit (by default
135 <Leader>cc) can be used in the log message buffer to immediately commit. This
136 is useful if the |CVSCommandCommitOnWrite| variable is set to 0 to disable the
137 normal commit-on-write behavior.
138
139 :CVSDiff *:CVSDiff*
140
141 With no arguments, this performs "cvs diff" on the current file against the
142 current repository version.
143
144 With one argument, "cvs diff" is performed on the current file against the
145 specified revision.
146
147 With two arguments, cvs diff is performed between the specified
148 revisions of the current file.
149
150 This command uses the 'CVSCommandDiffOpt' variable to specify diff options.
151 If that variable does not exist, then 'wbBc' is assumed. If you wish to have
152 no options, then set it to the empty string.
153
154 :CVSEdit *:CVSEdit*
155
156 This command performs "cvs edit" on the current file. Yes, the output buffer
157 in this case is almost completely useless.
158
159 :CVSEditors *:CVSEditors*
160
161 This command performs "cvs edit" on the current file.
162
163 :CVSGotoOriginal *:CVSGotoOriginal*
164
165 This command returns the current window to the source buffer, if the current
166 buffer is a CVS command output buffer.
167
168 :CVSGotoOriginal!
169
170 Like ":CVSGotoOriginal" but also executes :bufwipeout on all CVS command
171 output buffers for the source buffer.
172
173 :CVSLog *:CVSLog*
174
175 Performs "cvs log" on the current file.
176
177 If an argument is given, it is passed as an argument to the "-r" option of
178 "cvs log".
179
180 :CVSRevert *:CVSRevert*
181
182 Replaces the current file with the most recent version from the repository in
183 order to wipe out any undesired changes.
184
185 :CVSReview *:CVSReview*
186
187 Retrieves a particular version of the current file. If no argument is given,
188 the most recent version of the file on the current branch is retrieved.
189 Otherwise, the specified version is retrieved.
190
191 :CVSStatus *:CVSStatus*
192
193 Performs "cvs status" on the current file.
194
195 :CVSUnedit *:CVSUnedit*
196
197 Performs "cvs unedit" on the current file. Again, yes, the output buffer here
198 is basically useless.
199
200 :CVSUpdate *:CVSUpdate*
201
202 Performs "cvs update" on the current file. This intentionally does not
203 automatically reload the current buffer, though vim should prompt the user to
204 do so if the underlying file is altered by this command.
205
206 :CVSVimDiff *:CVSVimDiff*
207
208 With no arguments, this prompts the user for a revision and then uses vimdiff
209 to display the differences between the current file and the specified
210 revision. If no revision is specified, the most recent version of the file on
211 the current branch is used.
212
213 With one argument, that argument is used as the revision as above. With two
214 arguments, the differences between the two revisions is displayed using
215 vimdiff.
216
217 With either zero or one argument, the original buffer is used to perform the
218 vimdiff. When the other buffer is closed, the original buffer will be
219 returned to normal mode.
220
221 Once vimdiff mode is started using the above methods, additional vimdiff
222 buffers may be added by passing a single version argument to the command.
223 There may be up to 4 vimdiff buffers total.
224
225 Using the 2-argument form of the command resets the vimdiff to only those 2
226 versions. Additionally, invoking the command on a different file will close
227 the previous vimdiff buffers.
228
229 :CVSWatch *:CVSWatch*
230
231 This command takes an argument which must be one of [on|off|add|remove]. The
232 command performs "cvs watch" with the given argument on the current file.
233
234 :CVSWatchAdd *:CVSWatchAdd*
235
236 This command is an alias for ":CVSWatch add"
237
238 :CVSWatchOn *:CVSWatchOn*
239
240 This command is an alias for ":CVSWatch on"
241
242 :CVSWatchOff *:CVSWatchOff*
243
244 This command is an alias for ":CVSWatch off"
245
246 :CVSWatchRemove *:CVSWatchRemove*
247
248 This command is an alias for ":CVSWatch remove"
249
250 :CVSWatchers *:CVSWatchers*
251
252 This command performs "cvs watchers" on the current file.
253
254 4.2 Mappings *cvscommand-mappings*
255
256 By default, a mapping is defined for each command. These mappings execute the
257 default (no-argument) form of each command.
258
259 <Leader>ca CVSAdd
260 <Leader>cn CVSAnnotate
261 <Leader>cc CVSCommit
262 <Leader>cd CVSDiff
263 <Leader>ce CVSEdit
264 <Leader>ci CVSEditors
265 <Leader>cg CVSGotoOriginal
266 <Leader>cG CVSGotoOriginal!
267 <Leader>cl CVSLog
268 <Leader>cr CVSReview
269 <Leader>cs CVSStatus
270 <Leader>ct CVSUnedit
271 <Leader>cu CVSUpdate
272 <Leader>cv CVSVimDiff
273 <Leader>cwv CVSWatchers
274 <Leader>cwa CVSWatchAdd
275 <Leader>cwn CVSWatchOn
276 <Leader>cwf CVSWatchOff
277 <Leader>cwf CVSWatchRemove
278
279 *cvscommand-mappings-override*
280
281 The default mappings can be overriden by user-provided instead by mapping to
282 <Plug>CommandName. This is especially useful when these mappings collide with
283 other existing mappings (vim will warn of this during plugin initialization,
284 but will not clobber the existing mappings).
285
286 For instance, to override the default mapping for :CVSAdd to set it to '\add',
287 add the following to the vimrc:
288
289 nmap \add <Plug>CVSAdd
290
291 4.3 Automatic buffer variables *cvscommand-buffer-variables*
292
293 Several buffer variables are defined in each CVSCommand result buffer. These
294 may be useful for additional customization in callbacks defined in the event
295 handlers (please see |cvscommand-events|).
296
297 The following variables are automatically defined:
298
299 b:cvsOrigBuffNR *b:cvsOrigBuffNR*
300
301 This variable is set to the buffer number of the source file.
302
303 b:cvscmd *b:cvscmd*
304
305 This variable is set to the name of the cvs command that created the result
306 buffer.
307 ==============================================================================
308
309 5. Configuration and customization *cvscommand-customize*
310 *cvscommand-config*
311
312 The CVSCommand plugin can be configured in two ways: by setting configuration
313 variables (see |cvscommand-options|) or by defining CVSCommand event handlers
314 (see |cvscommand-events|). Additionally, the CVSCommand plugin provides
315 several option for naming the CVS result buffers (see |cvscommand-naming|) and
316 supported a customized status line (see |cvscommand-statusline| and
317 |cvscommand-buffer-management|).
318
319 5.1 CVSCommand configuration variables *cvscommand-options*
320
321 Several variables affect the plugin's behavior. These variables are checked
322 at time of execution, and may be defined at the window, buffer, or global
323 level and are checked in that order of precedence.
324
325
326 The following variables are available:
327
328 |CVSCommandAnnotateParent|
329 |CVSCommandCommitOnWrite|
330 |CVSCommandCVSExec|
331 |CVSCommandDeleteOnHide|
332 |CVSCommandDiffOpt|
333 |CVSCommandDiffSplit|
334 |CVSCommandEdit|
335 |CVSCommandEnableBufferSetup|
336 |CVSCommandInteractive|
337 |CVSCommandNameMarker|
338 |CVSCommandNameResultBuffers|
339 |CVSCommandSplit|
340
341 CVSCommandAnnotateParent *CVSCommandAnnotateParent*
342
343 This variable, if set to a non-zero value, causes the zero-argument form of
344 CVSAnnotate when invoked on a CVSAnnotate buffer to go to the version previous
345 to that displayed on the current line. If not set, it defaults to 0.
346
347 CVSCommandCommitOnWrite *CVSCommandCommitOnWrite*
348
349 This variable, if set to a non-zero value, causes the pending cvs commit
350 to take place immediately as soon as the log message buffer is written.
351 If set to zero, only the CVSCommit mapping will cause the pending commit to
352 occur. If not set, it defaults to 1.
353
354 CVSCommandCVSExec *CVSCommandCVSExec*
355
356 This variable controls the executable used for all CVS commands If not set,
357 it defaults to "cvs".
358
359 CVSCommandDeleteOnHide *CVSCommandDeleteOnHide*
360
361 This variable, if set to a non-zero value, causes the temporary CVS result
362 buffers to automatically delete themselves when hidden.
363
364 CVSCommandDiffOpt *CVSCommandDiffOpt*
365
366 This variable, if set, determines the options passed to the diff command of
367 CVS. If not set, it defaults to 'wbBc'.
368
369 CVSCommandDiffSplit *CVSCommandDiffSplit*
370
371 This variable overrides the |CVSCommandSplit| variable, but only for buffers
372 created with |:CVSVimDiff|.
373
374 CVSCommandEdit *CVSCommandEdit*
375
376 This variable controls whether the original buffer is replaced ('edit') or
377 split ('split'). If not set, it defaults to 'edit'.
378
379 CVSCommandEnableBufferSetup *CVSCommandEnableBufferSetup*
380
381 This variable, if set to a non-zero value, activates CVS buffer management
382 mode see (|cvscommand-buffer-management|). This mode means that two buffer
383 variables, 'CVSRevision' and 'CVSBranch', are set if the file is
384 CVS-controlled. This is useful for displaying version information in the
385 status bar.
386
387 CVSCommandInteractive *CVSCommandInteractive*
388
389 This variable, if set to a non-zero value, causes appropriate commands (for
390 the moment, only |:CVSReview|) to query the user for a revision to use instead
391 of the current revision if none is specified.
392
393 CVSCommandNameMarker *CVSCommandNameMarker*
394
395 This variable, if set, configures the special attention-getting characters
396 that appear on either side of the cvs buffer type in the buffer name. This
397 has no effect unless |CVSCommandNameResultBuffers| is set to a true value. If
398 not set, it defaults to '_'.
399
400 CVSCommandNameResultBuffers *CVSCommandNameResultBuffers*
401
402 This variable, if set to a true value, causes the cvs result buffers to be
403 named in the old way ('<source file name> _<cvs command>_'). If not set
404 or set to a false value, the result buffer is nameless.
405
406 CVSCommandSplit *CVSCommandSplit*
407
408 This variable controls the orientation of the various window splits that
409 may occur (such as with CVSVimDiff, when using a CVS command on a CVS
410 command buffer, or when the |CVSCommandEdit| variable is set to 'split'.
411 If set to 'horizontal', the resulting windows will be on stacked on top of
412 one another. If set to 'vertical', the resulting windows will be
413 side-by-side. If not set, it defaults to 'horizontal' for all but
414 CVSVimDiff windows.
415
416 5.2 CVSCommand events *cvscommand-events*
417
418 For additional customization, CVSCommand can trigger user-defined events.
419 Event handlers are provided by defining User event autocommands (see
420 |autocommand|, |User|) in the CVSCommand group with patterns matching the
421 event name.
422
423 For instance, the following could be added to the vimrc to provide a 'q'
424 mapping to quit a CVSCommand scratch buffer:
425
426 augroup CVSCommand
427 au CVSCommand User CVSBufferCreated silent! nmap <unique> <buffer> q: bwipeout<cr>
428 augroup END
429
430 The following hooks are available:
431
432 CVSBufferCreated This event is fired just after a cvs command
433 result buffer is created and filled with the
434 result of a cvs command. It is executed within
435 the context of the CVS command buffer. The
436 CVSCommand buffer variables may be useful for
437 handlers of this event (please see
438 |cvscommand-buffer-variables|).
439
440 CVSBufferSetup This event is fired just after CVS buffer setup
441 occurs, if enabled.
442
443 CVSPluginInit This event is fired when the CVSCommand plugin
444 first loads.
445
446 CVSPluginFinish This event is fired just after the CVSCommand
447 plugin loads.
448
449 CVSVimDiffFinish This event is fired just after the CVSVimDiff
450 command executes to allow customization of,
451 for instance, window placement and focus.
452
453 5.3 CVSCommand buffer naming *cvscommand-naming*
454
455 By default, the buffers containing the result of CVS commands are nameless
456 scratch buffers. It is intended that buffer variables of those buffers be
457 used to customize the statusline option so that the user may fully control the
458 display of result buffers.
459
460 If the old-style naming is desired, please enable the
461 |CVSCommandNameResultBuffers| variable. Then, each result buffer will receive
462 a unique name that includes the source file name, the CVS command, and any
463 extra data (such as revision numbers) that were part of the command.
464
465 5.4 CVSCommand status line support *cvscommand-statusline*
466
467 It is intended that the user will customize the |'statusline'| option to
468 include CVS result buffer attributes. A sample function that may be used in
469 the |'statusline'| option is provided by the plugin, CVSGetStatusLine(). In
470 order to use that function in the status line, do something like the
471 following:
472
473 set statusline=%<%f\ %{CVSGetStatusLine()}\ %h%m%r%=%l,%c%V\ %P
474
475 of which %{CVSGetStatusLine()} is the relevant portion.
476
477 The sample CVSGetStatusLine() function handles both CVS result buffers and
478 CVS-managed files if CVSCommand buffer management is enabled (please see
479 |cvscommand-buffer-management|).
480
481 5.5 CVSCommand buffer management *cvscommand-buffer-management*
482
483 The CVSCommand plugin can operate in buffer management mode, which means that
484 it attempts to set two buffer variables ('CVSRevision' and 'CVSBranch') upon
485 entry into a buffer. This is rather slow because it means that 'cvs status'
486 will be invoked at each entry into a buffer (during the |BufEnter|
487 autocommand).
488
489 This mode is disabled by default. In order to enable it, set the
490 |CVSCommandEnableBufferSetup| variable to a true (non-zero) value. Enabling
491 this mode simply provides the buffer variables mentioned above. The user must
492 explicitly include those in the |'statusline'| option if they are to appear in
493 the status line (but see |cvscommand-statusline| for a simple way to do that).
494
495 ==============================================================================
496
497 6. SSH "integration" *cvscommand-ssh*
498
499 The following instructions are intended for use in integrating the
500 cvscommand.vim plugin with an SSH-based CVS environment.
501
502 Familiarity with SSH and CVS are assumed.
503
504 These instructions assume that the intent is to have a message box pop up in
505 order to allow the user to enter a passphrase. If, instead, the user is
506 comfortable using certificate-based authentication, then only instructions
507 6.1.1 and 6.1.2 (and optionally 6.1.4) need to be followed; ssh should then
508 work transparently.
509
510 6.1 Environment settings *cvscommand-ssh-env*
511
512 6.1.1 CVSROOT should be set to something like:
513
514 :ext:user@host:/path_to_repository
515
516 6.1.2 CVS_RSH should be set to:
517
518 ssh
519
520 Together, those settings tell CVS to use ssh as the transport when
521 performing CVS calls.
522
523 6.1.3 SSH_ASKPASS should be set to the password-dialog program. In my case,
524 running gnome, it's set to:
525
526 /usr/libexec/openssh/gnome-ssh-askpass
527
528 This tells SSH how to get passwords if no input is available.
529
530 6.1.4 OPTIONAL. You may need to set SSH_SERVER to the location of the cvs
531 executable on the remote (server) machine.
532
533 6.2 CVS wrapper program *cvscommand-ssh-wrapper*
534
535 Now you need to convince SSH to use the password-dialog program. This means
536 you need to execute SSH (and therefore CVS) without standard input. The
537 following script is a simple perl wrapper that dissasociates the CVS command
538 from the current terminal. Specific steps to do this may vary from system to
539 system; the following example works for me on linux.
540
541 #!/usr/bin/perl -w
542 use strict;
543 use POSIX qw(setsid);
544 open STDIN, '/dev/null';
545 fork and do {wait; exit;};
546 setsid;
547 exec('cvs', @ARGV);
548
549 6.3 Configuring cvscommand.vim *cvscommand-ssh-config*
550
551 At this point, you should be able to use your wrapper script to invoke CVS with
552 various commands, and get the password dialog. All that's left is to make CVS
553 use your newly-created wrapper script.
554
555 6.3.1 Tell cvscommand.vim what CVS executable to use. The easiest way to do this
556 is globally, by putting the following in your .vimrc:
557
558 let CVSCommandCVSExec=/path/to/cvs/wrapper/script
559
560 6.4 Where to go from here *cvscommand-ssh-other*
561
562 The script given above works even when non-SSH CVS connections are used,
563 except possibly when interactively entering the message for CVS commit log
564 (depending on the editor you use... VIM works fine). Since the cvscommand.vim
565 plugin handles that message without a terminal, the wrapper script can be used
566 all the time.
567
568 This allows mixed-mode operation, where some work is done with SSH-based CVS
569 repositories, and others with pserver or local access.
570
571 It is possible, though beyond the scope of the plugin, to dynamically set the
572 CVS executable based on the CVSROOT for the file being edited. The user
573 events provided (such as CVSBufferCreated and CVSBufferSetup) can be used to
574 set a buffer-local value (b:CVSCommandCVSExec) to override the CVS executable
575 on a file-by-file basis. Alternatively, much the same can be done (less
576 automatically) by the various project-oriented plugins out there.
577
578 It is highly recommended for ease-of-use that certificates with no passphrase
579 or ssh-agent are employed so that the user is not given the password prompt
580 too often.
581
582 ==============================================================================
583 9. Tips *cvscommand-tips*
584
585 9.1 Split window annotation, by Michael Anderson
586
587 :nmap <Leader>cN :vs<CR><C-w>h<Leader>cn:vertical res 40<CR>
588 \ggdddd:set scb<CR>:set nowrap<CR><C-w>lgg:set scb<CR>
589 \:set nowrap<CR>
590
591 This splits the buffer vertically, puts an annotation on the left (minus the
592 header) with the width set to 40. An editable/normal copy is placed on the
593 right. The two versions are scroll locked so they move as one. and wrapping
594 is turned off so that the lines line up correctly. The advantages are...
595
596 1) You get a versioning on the right.
597 2) You can still edit your own code.
598 3) Your own code still has syntax highlighting.
599
600 ==============================================================================
601
602 8. Known bugs *cvscommand-bugs*
603
604 Please let me know if you run across any.
605
606 CVSUnedit may, if a file is changed from the repository, provide prompt text
607 to determine whether the changes should be thrown away. Currently, that text
608 shows up in the CVS result buffer as information; there is no way for the user
609 to actually respond to the prompt and the CVS unedit command does nothing. If
610 this really bothers anyone, please let me know.
611
612 CVSVimDiff, when using the original (real) source buffer as one of the diff
613 buffers, uses some hacks to try to restore the state of the original buffer
614 when the scratch buffer containing the other version is destroyed. There may
615 still be bugs in here, depending on many configuration details.
616
617 vim:tw=78:ts=8:ft=help
This diff has been collapsed as it changes many lines, (1387 lines changed) Show them Hide them
@@ -0,0 +1,1387 b''
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
General Comments 0
You need to be logged in to leave comments. Login now