--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/vim/hgcommand.txt Tue Jul 11 13:47:51 2006 -0700
@@ -0,0 +1,567 @@
+*hgcommand.txt* HGCommand
+
+For instructions on installing this file, type
+ :help add-local-help
+inside Vim.
+
+Author: Mathieu Clabaut <mathieu.clabaut@gmail.com>
+Credits: Bob Hiestand <bob.hiestand@gmail.com>
+
+==============================================================================
+1. Contents *hgcommand-contents*
+
+ Installation : |hgcommand-install|
+ HGCommand Intro : |hgcommand|
+ HGCommand Manual : |hgcommand-manual|
+ Customization : |hgcommand-customize|
+ SSH "integration" : |hgcommand-ssh|
+ Bugs : |hgcommand-bugs|
+
+==============================================================================
+
+2. HGCommand Installation *hgcommand-install*
+
+The HGCommand plugin comprises two files, hgcommand.vim and hgcommand.txt
+(this file). In order to install the plugin, place the hgcommand.vim file
+into a plugin' directory in your runtime path (please see |add-global-plugin|
+and |'runtimepath'|.
+
+HGCommand may be customized by setting variables, creating maps, and
+specifying event handlers. Please see |hgcommand-customize| for more
+details.
+
+This help file can be included in the VIM help system by copying it into a
+'doc' directory in your runtime path and then executing the |:helptags|
+command, specifying the full path of the 'doc' directory. Please see
+|add-local-help| for more details.
+
+==============================================================================
+
+3. HGCommand Intro *hgcommand*
+ *hgcommand-intro*
+
+The HGCommand plugin provides global ex commands for manipulating
+HG-controlled source files. In general, each command operates on the current
+buffer and accomplishes a separate hg function, such as update, commit, log,
+and others (please see |hgcommand-commands| for a list of all available
+commands). The results of each operation are displayed in a scratch buffer.
+Several buffer variables are defined for those scratch buffers (please see
+|hgcommand-buffer-variables|).
+
+The notion of "current file" means either the current buffer, or, in the case
+of a directory buffer, the file on the current line within the buffer.
+
+For convenience, any HGCommand invoked on a HGCommand scratch buffer acts as
+though it was invoked on the original file and splits the screen so that the
+output appears in a new window.
+
+Many of the commands accept revisions as arguments. By default, most operate
+on the most recent revision on the current branch if no revision is specified
+(though see |HGCommandInteractive| to prompt instead).
+
+Each HGCommand is mapped to a key sequence starting with the <Leader>
+keystroke. The default mappings may be overridden by supplying different
+mappings before the plugin is loaded, such as in the vimrc, in the standard
+fashion for plugin mappings. For examples, please see
+|hgcommand-mappings-override|.
+
+The HGCommand plugin may be configured in several ways. For more details,
+please see |hgcommand-customize|.
+
+==============================================================================
+
+4. HGCommand Manual *hgcommand-manual*
+
+4.1 HGCommand commands *hgcommand-commands*
+
+HGCommand defines the following commands:
+
+|:HGAdd|
+|:HGAnnotate|
+|:HGCommit|
+|:HGDiff|
+|:HGGotoOriginal|
+|:HGLog|
+|:HGRevert|
+|:HGReview|
+|:HGStatus|
+|:HGUnedit|
+|:HGUpdate|
+|:HGVimDiff|
+
+:HGAdd *:HGAdd*
+
+This command performs "hg add" on the current file. Please note, this does
+not commit the newly-added file.
+
+:HGAnnotate *:HGAnnotate*
+
+This command performs "hg annotate" on the current file. If an argument is
+given, the argument is used as a revision number to display. If not given an
+argument, it uses the most recent version of the file on the current branch.
+Additionally, if the current buffer is a HGAnnotate buffer already, the
+version number on the current line is used.
+
+If the |HGCommandAnnotateParent| variable is set to a non-zero value, the
+version previous to the one on the current line is used instead. This allows
+one to navigate back to examine the previous version of a line.
+
+The filetype of the HGCommand scratch buffer is set to 'HGAnnotate', to take
+advantage of the bundled syntax file.
+
+
+:HGCommit[!] *:HGCommit*
+
+If called with arguments, this performs "hg commit" using the arguments as
+the log message.
+
+If '!' is used with no arguments, an empty log message is committed.
+
+If called with no arguments, this is a two-step command. The first step opens
+a buffer to accept a log message. When that buffer is written, it is
+automatically closed and the file is committed using the information from that
+log message. The commit can be abandoned if the log message buffer is deleted
+or wiped before being written.
+
+Alternatively, the mapping that is used to invoke :HGCommit (by default
+<Leader>hgc) can be used in the log message buffer to immediately commit.
+This
+is useful if the |HGCommandCommitOnWrite| variable is set to 0 to disable the
+normal commit-on-write behavior.
+
+:HGDiff *:HGDiff*
+
+With no arguments, this performs "hg diff" on the current file against the
+current repository version.
+
+With one argument, "hg diff" is performed on the current file against the
+specified revision.
+
+With two arguments, hg diff is performed between the specified
+revisions of the current file.
+
+This command uses the 'HGCommandDiffOpt' variable to specify diff options.
+If that variable does not exist, then 'wbBc' is assumed. If you wish to have
+no options, then set it to the empty string.
+
+
+This command performs "hg edit" on the current file.
+
+:HGGotoOriginal *:HGGotoOriginal*
+
+This command returns the current window to the source buffer, if the current
+buffer is a HG command output buffer.
+
+:HGGotoOriginal!
+
+Like ":HGGotoOriginal" but also executes :bufwipeout on all HG command
+output buffers for the source buffer.
+
+:HGLog *:HGLog*
+
+Performs "hg log" on the current file.
+
+If an argument is given, it is passed as an argument to the "-r" option of
+"hg log".
+
+:HGRevert *:HGRevert*
+
+Replaces the current file with the most recent version from the repository in
+order to wipe out any undesired changes.
+
+:HGReview *:HGReview*
+
+Retrieves a particular version of the current file. If no argument is given,
+the most recent version of the file on the current branch is retrieved.
+Otherwise, the specified version is retrieved.
+
+:HGStatus *:HGStatus*
+
+Performs "hg status" on the current file.
+
+:HGUnedit *:HGUnedit*
+
+Performs "hg unedit" on the current file. Again, yes, the output buffer here
+is basically useless.
+
+:HGUpdate *:HGUpdate*
+
+Performs "hg update" on the current file. This intentionally does not
+automatically reload the current buffer, though vim should prompt the user to
+do so if the underlying file is altered by this command.
+
+:HGVimDiff *:HGVimDiff*
+
+With no arguments, this prompts the user for a revision and then uses vimdiff
+to display the differences between the current file and the specified
+revision. If no revision is specified, the most recent version of the file on
+the current branch is used.
+
+With one argument, that argument is used as the revision as above. With two
+arguments, the differences between the two revisions is displayed using
+vimdiff.
+
+With either zero or one argument, the original buffer is used to perform the
+vimdiff. When the other buffer is closed, the original buffer will be
+returned to normal mode.
+
+Once vimdiff mode is started using the above methods, additional vimdiff
+buffers may be added by passing a single version argument to the command.
+There may be up to 4 vimdiff buffers total.
+
+Using the 2-argument form of the command resets the vimdiff to only those 2
+versions. Additionally, invoking the command on a different file will close
+the previous vimdiff buffers.
+
+
+4.2 Mappings *hgcommand-mappings*
+
+By default, a mapping is defined for each command. These mappings execute the
+default (no-argument) form of each command.
+
+<Leader>hga HGAdd
+<Leader>hgn HGAnnotate
+<Leader>hgc HGCommit
+<Leader>hgd HGDiff
+<Leader>hgg HGGotoOriginal
+<Leader>hgG HGGotoOriginal!
+<Leader>hgl HGLog
+<Leader>hgr HGReview
+<Leader>hgs HGStatus
+<Leader>hgt HGUnedit
+<Leader>hgu HGUpdate
+<Leader>hgv HGVimDiff
+
+ *hgcommand-mappings-override*
+
+The default mappings can be overriden by user-provided instead by mapping to
+<Plug>CommandName. This is especially useful when these mappings collide with
+other existing mappings (vim will warn of this during plugin initialization,
+but will not clobber the existing mappings).
+
+For instance, to override the default mapping for :HGAdd to set it to '\add',
+add the following to the vimrc:
+
+nmap \add <Plug>HGAdd
+
+4.3 Automatic buffer variables *hgcommand-buffer-variables*
+
+Several buffer variables are defined in each HGCommand result buffer. These
+may be useful for additional customization in callbacks defined in the event
+handlers (please see |hgcommand-events|).
+
+The following variables are automatically defined:
+
+b:hgOrigBuffNR *b:hgOrigBuffNR*
+
+This variable is set to the buffer number of the source file.
+
+b:hgcmd *b:hgcmd*
+
+This variable is set to the name of the hg command that created the result
+buffer.
+==============================================================================
+
+5. Configuration and customization *hgcommand-customize*
+ *hgcommand-config*
+
+The HGCommand plugin can be configured in two ways: by setting configuration
+variables (see |hgcommand-options|) or by defining HGCommand event handlers
+(see |hgcommand-events|). Additionally, the HGCommand plugin provides
+several option for naming the HG result buffers (see |hgcommand-naming|) and
+supported a customized status line (see |hgcommand-statusline| and
+|hgcommand-buffer-management|).
+
+5.1 HGCommand configuration variables *hgcommand-options*
+
+Several variables affect the plugin's behavior. These variables are checked
+at time of execution, and may be defined at the window, buffer, or global
+level and are checked in that order of precedence.
+
+
+The following variables are available:
+
+|HGCommandAnnotateParent|
+|HGCommandCommitOnWrite|
+|HGCommandHGExec|
+|HGCommandDeleteOnHide|
+|HGCommandDiffOpt|
+|HGCommandDiffSplit|
+|HGCommandEdit|
+|HGCommandEnableBufferSetup|
+|HGCommandInteractive|
+|HGCommandNameMarker|
+|HGCommandNameResultBuffers|
+|HGCommandSplit|
+
+HGCommandAnnotateParent *HGCommandAnnotateParent*
+
+This variable, if set to a non-zero value, causes the zero-argument form of
+HGAnnotate when invoked on a HGAnnotate buffer to go to the version previous
+to that displayed on the current line. If not set, it defaults to 0.
+
+HGCommandCommitOnWrite *HGCommandCommitOnWrite*
+
+This variable, if set to a non-zero value, causes the pending hg commit
+to take place immediately as soon as the log message buffer is written.
+If set to zero, only the HGCommit mapping will cause the pending commit to
+occur. If not set, it defaults to 1.
+
+HGCommandHGExec *HGCommandHGExec*
+
+This variable controls the executable used for all HG commands If not set,
+it defaults to "hg".
+
+HGCommandDeleteOnHide *HGCommandDeleteOnHide*
+
+This variable, if set to a non-zero value, causes the temporary HG result
+buffers to automatically delete themselves when hidden.
+
+HGCommandDiffOpt *HGCommandDiffOpt*
+
+This variable, if set, determines the options passed to the diff command of
+HG. If not set, it defaults to 'wbBc'.
+
+HGCommandDiffSplit *HGCommandDiffSplit*
+
+This variable overrides the |HGCommandSplit| variable, but only for buffers
+created with |:HGVimDiff|.
+
+HGCommandEdit *HGCommandEdit*
+
+This variable controls whether the original buffer is replaced ('edit') or
+split ('split'). If not set, it defaults to 'edit'.
+
+HGCommandEnableBufferSetup *HGCommandEnableBufferSetup*
+
+This variable, if set to a non-zero value, activates HG buffer management
+mode see (|hgcommand-buffer-management|). This mode means that two buffer
+variables, 'HGRevision' and 'HGBranch', are set if the file is
+HG-controlled. This is useful for displaying version information in the
+status bar.
+
+HGCommandInteractive *HGCommandInteractive*
+
+This variable, if set to a non-zero value, causes appropriate commands (for
+the moment, only |:HGReview|) to query the user for a revision to use instead
+of the current revision if none is specified.
+
+HGCommandNameMarker *HGCommandNameMarker*
+
+This variable, if set, configures the special attention-getting characters
+that appear on either side of the hg buffer type in the buffer name. This
+has no effect unless |HGCommandNameResultBuffers| is set to a true value. If
+not set, it defaults to '_'.
+
+HGCommandNameResultBuffers *HGCommandNameResultBuffers*
+
+This variable, if set to a true value, causes the hg result buffers to be
+named in the old way ('<source file name> _<hg command>_'). If not set
+or set to a false value, the result buffer is nameless.
+
+HGCommandSplit *HGCommandSplit*
+
+This variable controls the orientation of the various window splits that
+may occur (such as with HGVimDiff, when using a HG command on a HG
+command buffer, or when the |HGCommandEdit| variable is set to 'split'.
+If set to 'horizontal', the resulting windows will be on stacked on top of
+one another. If set to 'vertical', the resulting windows will be
+side-by-side. If not set, it defaults to 'horizontal' for all but
+HGVimDiff windows.
+
+5.2 HGCommand events *hgcommand-events*
+
+For additional customization, HGCommand can trigger user-defined events.
+Event handlers are provided by defining User event autocommands (see
+|autocommand|, |User|) in the HGCommand group with patterns matching the
+event name.
+
+For instance, the following could be added to the vimrc to provide a 'q'
+mapping to quit a HGCommand scratch buffer:
+
+augroup HGCommand
+ au HGCommand User HGBufferCreated silent! nmap <unique> <buffer> q: bwipeout<cr>
+augroup END
+
+The following hooks are available:
+
+HGBufferCreated This event is fired just after a hg command
+ result buffer is created and filled with the
+ result of a hg command. It is executed within
+ the context of the HG command buffer. The
+ HGCommand buffer variables may be useful for
+ handlers of this event (please see
+ |hgcommand-buffer-variables|).
+
+HGBufferSetup This event is fired just after HG buffer setup
+ occurs, if enabled.
+
+HGPluginInit This event is fired when the HGCommand plugin
+ first loads.
+
+HGPluginFinish This event is fired just after the HGCommand
+ plugin loads.
+
+HGVimDiffFinish This event is fired just after the HGVimDiff
+ command executes to allow customization of,
+ for instance, window placement and focus.
+
+5.3 HGCommand buffer naming *hgcommand-naming*
+
+By default, the buffers containing the result of HG commands are nameless
+scratch buffers. It is intended that buffer variables of those buffers be
+used to customize the statusline option so that the user may fully control the
+display of result buffers.
+
+If the old-style naming is desired, please enable the
+|HGCommandNameResultBuffers| variable. Then, each result buffer will receive
+a unique name that includes the source file name, the HG command, and any
+extra data (such as revision numbers) that were part of the command.
+
+5.4 HGCommand status line support *hgcommand-statusline*
+
+It is intended that the user will customize the |'statusline'| option to
+include HG result buffer attributes. A sample function that may be used in
+the |'statusline'| option is provided by the plugin, HGGetStatusLine(). In
+order to use that function in the status line, do something like the
+following:
+
+set statusline=%<%f\ %{HGGetStatusLine()}\ %h%m%r%=%l,%c%V\ %P
+
+of which %{HGGetStatusLine()} is the relevant portion.
+
+The sample HGGetStatusLine() function handles both HG result buffers and
+HG-managed files if HGCommand buffer management is enabled (please see
+|hgcommand-buffer-management|).
+
+5.5 HGCommand buffer management *hgcommand-buffer-management*
+
+The HGCommand plugin can operate in buffer management mode, which means that
+it attempts to set two buffer variables ('HGRevision' and 'HGBranch') upon
+entry into a buffer. This is rather slow because it means that 'hg status'
+will be invoked at each entry into a buffer (during the |BufEnter|
+autocommand).
+
+This mode is disabled by default. In order to enable it, set the
+|HGCommandEnableBufferSetup| variable to a true (non-zero) value. Enabling
+this mode simply provides the buffer variables mentioned above. The user must
+explicitly include those in the |'statusline'| option if they are to appear in
+the status line (but see |hgcommand-statusline| for a simple way to do that).
+
+==============================================================================
+
+6. SSH "integration" *hgcommand-ssh*
+
+The following instructions are intended for use in integrating the
+hgcommand.vim plugin with an SSH-based HG environment.
+
+Familiarity with SSH and HG are assumed.
+
+These instructions assume that the intent is to have a message box pop up in
+order to allow the user to enter a passphrase. If, instead, the user is
+comfortable using certificate-based authentication, then only instructions
+6.1.1 and 6.1.2 (and optionally 6.1.4) need to be followed; ssh should then
+work transparently.
+
+6.1 Environment settings *hgcommand-ssh-env*
+
+6.1.1 HGROOT should be set to something like:
+
+ :ext:user@host:/path_to_repository
+
+6.1.2 HG_RSH should be set to:
+
+ ssh
+
+ Together, those settings tell HG to use ssh as the transport when
+ performing HG calls.
+
+6.1.3 SSH_ASKPASS should be set to the password-dialog program. In my case,
+ running gnome, it's set to:
+
+ /usr/libexec/openssh/gnome-ssh-askpass
+
+ This tells SSH how to get passwords if no input is available.
+
+6.1.4 OPTIONAL. You may need to set SSH_SERVER to the location of the hg
+ executable on the remote (server) machine.
+
+6.2 HG wrapper program *hgcommand-ssh-wrapper*
+
+Now you need to convince SSH to use the password-dialog program. This means
+you need to execute SSH (and therefore HG) without standard input. The
+following script is a simple perl wrapper that dissasociates the HG command
+from the current terminal. Specific steps to do this may vary from system to
+system; the following example works for me on linux.
+
+#!/usr/bin/perl -w
+use strict;
+use POSIX qw(setsid);
+open STDIN, '/dev/null';
+fork and do {wait; exit;};
+setsid;
+exec('hg', @ARGV);
+
+6.3 Configuring hgcommand.vim *hgcommand-ssh-config*
+
+At this point, you should be able to use your wrapper script to invoke HG with
+various commands, and get the password dialog. All that's left is to make HG
+use your newly-created wrapper script.
+
+6.3.1 Tell hgcommand.vim what HG executable to use. The easiest way to do this
+ is globally, by putting the following in your .vimrc:
+
+ let HGCommandHGExec=/path/to/hg/wrapper/script
+
+6.4 Where to go from here *hgcommand-ssh-other*
+
+The script given above works even when non-SSH HG connections are used,
+except possibly when interactively entering the message for HG commit log
+(depending on the editor you use... VIM works fine). Since the hgcommand.vim
+plugin handles that message without a terminal, the wrapper script can be used
+all the time.
+
+This allows mixed-mode operation, where some work is done with SSH-based HG
+repositories, and others with pserver or local access.
+
+It is possible, though beyond the scope of the plugin, to dynamically set the
+HG executable based on the HGROOT for the file being edited. The user
+events provided (such as HGBufferCreated and HGBufferSetup) can be used to
+set a buffer-local value (b:HGCommandHGExec) to override the HG executable
+on a file-by-file basis. Alternatively, much the same can be done (less
+automatically) by the various project-oriented plugins out there.
+
+It is highly recommended for ease-of-use that certificates with no passphrase
+or ssh-agent are employed so that the user is not given the password prompt
+too often.
+
+==============================================================================
+9. Tips *hgcommand-tips*
+
+9.1 Split window annotation, by Michael Anderson
+
+:nmap <Leader>hgN :vs<CR><C-w>h<Leader>hgn:vertical res 40<CR>
+ \ggdddd:set scb<CR>:set nowrap<CR><C-w>lgg:set scb<CR>
+ \:set nowrap<CR>
+
+This splits the buffer vertically, puts an annotation on the left (minus the
+header) with the width set to 40. An editable/normal copy is placed on the
+right. The two versions are scroll locked so they move as one. and wrapping
+is turned off so that the lines line up correctly. The advantages are...
+
+1) You get a versioning on the right.
+2) You can still edit your own code.
+3) Your own code still has syntax highlighting.
+
+==============================================================================
+
+8. Known bugs *hgcommand-bugs*
+
+Please let me know if you run across any.
+
+HGVimDiff, when using the original (real) source buffer as one of the diff
+buffers, uses some hacks to try to restore the state of the original buffer
+when the scratch buffer containing the other version is destroyed. There may
+still be bugs in here, depending on many configuration details.
+
+vim:tw=78:ts=8:ft=help
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/vim/hgcommand.vim Tue Jul 11 13:47:51 2006 -0700
@@ -0,0 +1,1265 @@
+" vim600: set foldmethod=marker:
+"
+" Vim plugin to assist in working with HG-controlled files.
+"
+" Last Change: 2006/02/22
+" Version: 1.76
+" Maintainer: Mathieu Clabaut <mathieu.clabaut@gmail.com>
+" License: This file is placed in the public domain.
+" Credits: {{{1
+" Bob Hiestand <bob.hiestand@gmail.com> for the fabulous
+" cvscommand.vim from which this script was directly created by
+" means of sed commands and minor tweaks.
+
+" Section: Documentation {{{1
+"
+" Provides functions to invoke various HG commands on the current file
+" (either the current buffer, or, in the case of an directory buffer, the file
+" on the current line). The output of the commands is captured in a new
+" scratch window. For convenience, if the functions are invoked on a HG
+" output window, the original file is used for the hg operation instead after
+" the window is split. This is primarily useful when running HGCommit and
+" you need to see the changes made, so that HGDiff is usable and shows up in
+" another window.
+"
+" Command documentation {{{2
+"
+" HGAdd Performs "hg add" on the current file.
+"
+" HGAnnotate Performs "hg annotate" on the current file. If an
+" argument is given, the argument is used as a revision
+" number to display. If not given an argument, it uses the
+" most recent version of the file on the current branch.
+" Additionally, if the current buffer is a HGAnnotate buffer
+" already, the version number on the current line is used.
+"
+" If the 'HGCommandAnnotateParent' variable is set to a
+" non-zero value, the version previous to the one on the
+" current line is used instead. This allows one to navigate
+" back to examine the previous version of a line.
+"
+" HGCommit[!] If called with arguments, this performs "hg commit" using
+" the arguments as the log message.
+"
+" If '!' is used, an empty log message is committed.
+"
+" If called with no arguments, this is a two-step command.
+" The first step opens a buffer to accept a log message.
+" When that buffer is written, it is automatically closed and
+" the file is committed using the information from that log
+" message. The commit can be abandoned if the log message
+" buffer is deleted or wiped before being written.
+"
+" HGDiff With no arguments, this performs "hg diff" on the current
+" file. With one argument, "hg diff" is performed on the
+" current file against the specified revision. With two
+" arguments, hg diff is performed between the specified
+" revisions of the current file. This command uses the
+" 'HGCommandDiffOpt' variable to specify diff options. If
+" that variable does not exist, then 'wbBc' is assumed. If
+" you wish to have no options, then set it to the empty
+" string.
+"
+" HGGotoOriginal Returns the current window to the source buffer if the
+" current buffer is a HG output buffer.
+"
+" HGLog Performs "hg log" on the current file.
+"
+" HGRevert Replaces the modified version of the current file with the
+" most recent version from the repository.
+"
+" HGReview Retrieves a particular version of the current file. If no
+" argument is given, the most recent version of the file on
+" the current branch is retrieved. The specified revision is
+" retrieved into a new buffer.
+"
+" HGStatus Performs "hg status" on the current file.
+"
+" HGUpdate Performs "hg update" on the current file.
+"
+" HGVimDiff With no arguments, this prompts the user for a revision and
+" then uses vimdiff to display the differences between the
+" current file and the specified revision. If no revision is
+" specified, the most recent version of the file on the
+" current branch is used. With one argument, that argument
+" is used as the revision as above. With two arguments, the
+" differences between the two revisions is displayed using
+" vimdiff.
+"
+" With either zero or one argument, the original buffer is used
+" to perform the vimdiff. When the other buffer is closed, the
+" original buffer will be returned to normal mode.
+"
+" Once vimdiff mode is started using the above methods,
+" additional vimdiff buffers may be added by passing a single
+" version argument to the command. There may be up to 4
+" vimdiff buffers total.
+"
+" Using the 2-argument form of the command resets the vimdiff
+" to only those 2 versions. Additionally, invoking the
+" command on a different file will close the previous vimdiff
+" buffers.
+"
+"
+" Mapping documentation: {{{2
+"
+" By default, a mapping is defined for each command. User-provided mappings
+" can be used instead by mapping to <Plug>CommandName, for instance:
+"
+" nnoremap ,ca <Plug>HGAdd
+"
+" The default mappings are as follow:
+"
+" <Leader>hga HGAdd
+" <Leader>hgn HGAnnotate
+" <Leader>hgc HGCommit
+" <Leader>hgd HGDiff
+" <Leader>hgg HGGotoOriginal
+" <Leader>hgG HGGotoOriginal!
+" <Leader>hgl HGLog
+" <Leader>hgr HGReview
+" <Leader>hgs HGStatus
+" <Leader>hgu HGUpdate
+" <Leader>hgv HGVimDiff
+"
+" Options documentation: {{{2
+"
+" Several variables are checked by the script to determine behavior as follow:
+"
+" HGCommandAnnotateParent
+" This variable, if set to a non-zero value, causes the zero-argument form
+" of HGAnnotate when invoked on a HGAnnotate buffer to go to the version
+" previous to that displayed on the current line. If not set, it defaults
+" to 0.
+"
+" HGCommandCommitOnWrite
+" This variable, if set to a non-zero value, causes the pending hg commit
+" to take place immediately as soon as the log message buffer is written.
+" If set to zero, only the HGCommit mapping will cause the pending commit
+" to occur. If not set, it defaults to 1.
+"
+" HGCommandDeleteOnHide
+" This variable, if set to a non-zero value, causes the temporary HG result
+" buffers to automatically delete themselves when hidden.
+"
+" HGCommandDiffOpt
+" This variable, if set, determines the options passed to the diff command
+" of HG. If not set, it defaults to 'wbBc'.
+"
+" HGCommandDiffSplit
+" This variable overrides the HGCommandSplit variable, but only for buffers
+" created with HGVimDiff.
+"
+" HGCommandEdit
+" This variable controls whether the original buffer is replaced ('edit') or
+" split ('split'). If not set, it defaults to 'edit'.
+"
+" HGCommandEnableBufferSetup
+" This variable, if set to a non-zero value, activates HG buffer management
+" mode. This mode means that two buffer variables, 'HGRevision' and
+" 'HGBranch', are set if the file is HG-controlled. This is useful for
+" displaying version information in the status bar.
+"
+" HGCommandInteractive
+" This variable, if set to a non-zero value, causes appropriate functions (for
+" the moment, only HGReview) to query the user for a revision to use
+" instead of the current revision if none is specified.
+"
+" HGCommandNameMarker
+" This variable, if set, configures the special attention-getting characters
+" that appear on either side of the hg buffer type in the buffer name.
+" This has no effect unless 'HGCommandNameResultBuffers' is set to a true
+" value. If not set, it defaults to '_'.
+"
+" HGCommandNameResultBuffers
+" This variable, if set to a true value, causes the hg result buffers to be
+" named in the old way ('<source file name> _<hg command>_'). If not set
+" or set to a false value, the result buffer is nameless.
+"
+" HGCommandSplit
+" This variable controls the orientation of the various window splits that
+" may occur (such as with HGVimDiff, when using a HG command on a HG
+" command buffer, or when the 'HGCommandEdit' variable is set to 'split'.
+" If set to 'horizontal', the resulting windows will be on stacked on top of
+" one another. If set to 'vertical', the resulting windows will be
+" side-by-side. If not set, it defaults to 'horizontal' for all but
+" HGVimDiff windows.
+"
+" Event documentation {{{2
+" For additional customization, hgcommand.vim uses User event autocommand
+" hooks. Each event is in the HGCommand group, and different patterns
+" match the various hooks.
+"
+" For instance, the following could be added to the vimrc to provide a 'q'
+" mapping to quit a HG buffer:
+"
+" augroup HGCommand
+" au HGCommand User HGBufferCreated silent! nmap <unique> <buffer> q :bwipeout<cr>
+" augroup END
+"
+" The following hooks are available:
+"
+" HGBufferCreated This event is fired just after a hg command
+" result buffer is created and filled with the
+" result of a hg command. It is executed within
+" the context of the new buffer.
+"
+" HGBufferSetup This event is fired just after HG buffer setup
+" occurs, if enabled.
+"
+" HGPluginInit This event is fired when the HGCommand plugin
+" first loads.
+"
+" HGPluginFinish This event is fired just after the HGCommand
+" plugin loads.
+"
+" HGVimDiffFinish This event is fired just after the HGVimDiff
+" command executes to allow customization of,
+" for instance, window placement and focus.
+"
+" Section: Plugin header {{{1
+
+" loaded_hgcommand is set to 1 when the initialization begins, and 2 when it
+" completes. This allows various actions to only be taken by functions after
+" system initialization.
+
+if exists("loaded_hgcommand")
+ finish
+endif
+let loaded_hgcommand = 1
+
+if v:version < 602
+ echohl WarningMsg|echomsg "HGCommand 1.69 or later requires VIM 6.2 or later"|echohl None
+ finish
+endif
+
+" Section: Event group setup {{{1
+
+augroup HGCommand
+augroup END
+
+" Section: Plugin initialization {{{1
+silent do HGCommand User HGPluginInit
+
+" Section: Script variable initialization {{{1
+
+let s:HGCommandEditFileRunning = 0
+unlet! s:vimDiffRestoreCmd
+unlet! s:vimDiffSourceBuffer
+unlet! s:vimDiffBufferCount
+unlet! s:vimDiffScratchList
+
+" Section: Utility functions {{{1
+
+" Function: s:HGResolveLink() {{{2
+" Fully resolve the given file name to remove shortcuts or symbolic links.
+
+function! s:HGResolveLink(fileName)
+ let resolved = resolve(a:fileName)
+ if resolved != a:fileName
+ let resolved = s:HGResolveLink(resolved)
+ endif
+ return resolved
+endfunction
+
+" Function: s:HGChangeToCurrentFileDir() {{{2
+" Go to the directory in which the current HG-controlled file is located.
+" If this is a HG command buffer, first switch to the original file.
+
+function! s:HGChangeToCurrentFileDir(fileName)
+ let oldCwd=getcwd()
+ let fileName=s:HGResolveLink(a:fileName)
+ let newCwd=fnamemodify(fileName, ':h')
+ if strlen(newCwd) > 0
+ execute 'cd' escape(newCwd, ' ')
+ endif
+ return oldCwd
+endfunction
+
+" Function: s:HGGetOption(name, default) {{{2
+" Grab a user-specified option to override the default provided. Options are
+" searched in the window, buffer, then global spaces.
+
+function! s:HGGetOption(name, default)
+ if exists("s:" . a:name . "Override")
+ execute "return s:".a:name."Override"
+ elseif exists("w:" . a:name)
+ execute "return w:".a:name
+ elseif exists("b:" . a:name)
+ execute "return b:".a:name
+ elseif exists("g:" . a:name)
+ execute "return g:".a:name
+ else
+ return a:default
+ endif
+endfunction
+
+" Function: s:HGEditFile(name, origBuffNR) {{{2
+" Wrapper around the 'edit' command to provide some helpful error text if the
+" current buffer can't be abandoned. If name is provided, it is used;
+" otherwise, a nameless scratch buffer is used.
+" Returns: 0 if successful, -1 if an error occurs.
+
+function! s:HGEditFile(name, origBuffNR)
+ "Name parameter will be pasted into expression.
+ let name = escape(a:name, ' *?\')
+
+ let editCommand = s:HGGetOption('HGCommandEdit', 'edit')
+ if editCommand != 'edit'
+ if s:HGGetOption('HGCommandSplit', 'horizontal') == 'horizontal'
+ if name == ""
+ let editCommand = 'rightbelow new'
+ else
+ let editCommand = 'rightbelow split ' . name
+ endif
+ else
+ if name == ""
+ let editCommand = 'vert rightbelow new'
+ else
+ let editCommand = 'vert rightbelow split ' . name
+ endif
+ endif
+ else
+ if name == ""
+ let editCommand = 'enew'
+ else
+ let editCommand = 'edit ' . name
+ endif
+ endif
+
+ " Protect against useless buffer set-up
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1
+ try
+ execute editCommand
+ finally
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1
+ endtry
+
+ let b:HGOrigBuffNR=a:origBuffNR
+ let b:HGCommandEdit='split'
+endfunction
+
+" Function: s:HGCreateCommandBuffer(cmd, cmdName, statusText, filename) {{{2
+" Creates a new scratch buffer and captures the output from execution of the
+" given command. The name of the scratch buffer is returned.
+
+function! s:HGCreateCommandBuffer(cmd, cmdName, statusText, origBuffNR)
+ let fileName=bufname(a:origBuffNR)
+
+ let resultBufferName=''
+
+ if s:HGGetOption("HGCommandNameResultBuffers", 0)
+ let nameMarker = s:HGGetOption("HGCommandNameMarker", '_')
+ if strlen(a:statusText) > 0
+ let bufName=a:cmdName . ' -- ' . a:statusText
+ else
+ let bufName=a:cmdName
+ endif
+ let bufName=fileName . ' ' . nameMarker . bufName . nameMarker
+ let counter=0
+ let resultBufferName = bufName
+ while buflisted(resultBufferName)
+ let counter=counter + 1
+ let resultBufferName=bufName . ' (' . counter . ')'
+ endwhile
+ endif
+
+ let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " " . a:cmd
+ echomsg "DBG :".hgCommand
+ let hgOut = system(hgCommand)
+ " HACK: diff command does not return proper error codes
+ if v:shell_error && a:cmdName != 'hgdiff'
+ if strlen(hgOut) == 0
+ echoerr "HG command failed"
+ else
+ echoerr "HG command failed: " . hgOut
+ endif
+ return -1
+ endif
+ if strlen(hgOut) == 0
+ " Handle case of no output. In this case, it is important to check the
+ " file status, especially since hg edit/unedit may change the attributes
+ " of the file with no visible output.
+
+ echomsg "No output from HG command"
+ checktime
+ return -1
+ endif
+
+ if s:HGEditFile(resultBufferName, a:origBuffNR) == -1
+ return -1
+ endif
+
+ set buftype=nofile
+ set noswapfile
+ set filetype=
+
+ if s:HGGetOption("HGCommandDeleteOnHide", 0)
+ set bufhidden=delete
+ endif
+
+ silent 0put=hgOut
+
+ " The last command left a blank line at the end of the buffer. If the
+ " last line is folded (a side effect of the 'put') then the attempt to
+ " remove the blank line will kill the last fold.
+ "
+ " This could be fixed by explicitly detecting whether the last line is
+ " within a fold, but I prefer to simply unfold the result buffer altogether.
+
+ if has('folding')
+ normal zR
+ endif
+
+ $d
+ 1
+
+ " Define the environment and execute user-defined hooks.
+
+ let b:HGSourceFile=fileName
+ let b:HGCommand=a:cmdName
+ if a:statusText != ""
+ let b:HGStatusText=a:statusText
+ endif
+
+ silent do HGCommand User HGBufferCreated
+ return bufnr("%")
+endfunction
+
+" Function: s:HGBufferCheck(hgBuffer) {{{2
+" Attempts to locate the original file to which HG operations were applied
+" for a given buffer.
+
+function! s:HGBufferCheck(hgBuffer)
+ let origBuffer = getbufvar(a:hgBuffer, "HGOrigBuffNR")
+ if origBuffer
+ if bufexists(origBuffer)
+ return origBuffer
+ else
+ " Original buffer no longer exists.
+ return -1
+ endif
+ else
+ " No original buffer
+ return a:hgBuffer
+ endif
+endfunction
+
+" Function: s:HGCurrentBufferCheck() {{{2
+" Attempts to locate the original file to which HG operations were applied
+" for the current buffer.
+
+function! s:HGCurrentBufferCheck()
+ return s:HGBufferCheck(bufnr("%"))
+endfunction
+
+" Function: s:HGToggleDeleteOnHide() {{{2
+" Toggles on and off the delete-on-hide behavior of HG buffers
+
+function! s:HGToggleDeleteOnHide()
+ if exists("g:HGCommandDeleteOnHide")
+ unlet g:HGCommandDeleteOnHide
+ else
+ let g:HGCommandDeleteOnHide=1
+ endif
+endfunction
+
+" Function: s:HGDoCommand(hgcmd, cmdName, statusText) {{{2
+" General skeleton for HG function execution.
+" Returns: name of the new command buffer containing the command results
+
+function! s:HGDoCommand(cmd, cmdName, statusText)
+ let hgBufferCheck=s:HGCurrentBufferCheck()
+ if hgBufferCheck == -1
+ echo "Original buffer no longer exists, aborting."
+ return -1
+ endif
+
+ let fileName=bufname(hgBufferCheck)
+ if isdirectory(fileName)
+ let fileName=fileName . "/" . getline(".")
+ endif
+ let realFileName = fnamemodify(s:HGResolveLink(fileName), ':t')
+ let oldCwd=s:HGChangeToCurrentFileDir(fileName)
+ try
+ " TODO
+ "if !filereadable('HG/Root')
+ "throw fileName . ' is not a HG-controlled file.'
+ "endif
+ let fullCmd = a:cmd . ' "' . realFileName . '"'
+ "echomsg "DEBUG".fullCmd
+ let resultBuffer=s:HGCreateCommandBuffer(fullCmd, a:cmdName, a:statusText, hgBufferCheck)
+ return resultBuffer
+ catch
+ echoerr v:exception
+ return -1
+ finally
+ execute 'cd' escape(oldCwd, ' ')
+ endtry
+endfunction
+
+
+" Function: s:HGGetStatusVars(revision, branch, repository) {{{2
+"
+" Obtains a HG revision number and branch name. The 'revisionVar',
+" 'branchVar'and 'repositoryVar' arguments, if non-empty, contain the names of variables to hold
+" the corresponding results.
+"
+" Returns: string to be exec'd that sets the multiple return values.
+
+function! s:HGGetStatusVars(revisionVar, branchVar, repositoryVar)
+ let hgBufferCheck=s:HGCurrentBufferCheck()
+ if hgBufferCheck == -1
+ return ""
+ endif
+ let fileName=bufname(hgBufferCheck)
+ let realFileName = fnamemodify(s:HGResolveLink(fileName), ':t')
+ let oldCwd=s:HGChangeToCurrentFileDir(fileName)
+ try
+ ""TODO
+ "if !filereadable('HG/Root')
+ "return ""
+ "endif
+ let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " status -mardui " . fileName
+ let statustext=system(hgCommand)
+ if(v:shell_error)
+ return ""
+ endif
+ if match(statustext, '^[?I]') >= 0
+ let revision="NEW"
+ elseif match(statustext, '^[R]') >= 0
+ let revision="REMOVED"
+ elseif match(statustext, '^[D]') >= 0
+ let revision="DELETED"
+ elseif match(statustext, '^[A]') >= 0
+ let revision="ADDED"
+ endif
+
+ let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " parents -b "
+ let statustext=system(hgCommand)
+ if(v:shell_error)
+ return ""
+ endif
+ if exists('revision')
+ let returnExpression = "let " . a:revisionVar . "='" . revision . "'"
+ else
+ let revision=substitute(statustext, '^changeset:\s*\(\d\+\):.*\_$\_.*$', '\1', "")
+ let returnExpression = "let " . a:revisionVar . "='" . revision . "'"
+ endif
+
+ if a:branchVar != "" && match(statustext, '^\_.*\_^branch:') >= 0
+ let branch=substitute(statustext, '^\_.*\_^branch:\s*\(\S\+\)\n\_.*$', '\1', "")
+ let returnExpression=returnExpression . " | let " . a:branchVar . "='" . branch . "'"
+ endif
+ if a:repositoryVar != ""
+ let hgCommand = s:HGGetOption("HGCommandHGExec", "hg") . " root "
+ let roottext=system(hgCommand)
+ let repository=substitute(roottext,'^.*/\([^/\n\r]*\)\n\_.*$','\1','')
+ let returnExpression=returnExpression . " | let " . a:repositoryVar . "='" . repository . "'"
+ endif
+
+
+
+ return returnExpression
+ finally
+ execute 'cd' escape(oldCwd, ' ')
+ endtry
+endfunction
+
+" Function: s:HGSetupBuffer() {{{2
+" Attempts to set the b:HGBranch, b:HGRevision and b:HGRepository variables.
+
+function! s:HGSetupBuffer()
+ if (exists("b:HGBufferSetup") && b:HGBufferSetup)
+ " This buffer is already set up.
+ return
+ endif
+
+ if !s:HGGetOption("HGCommandEnableBufferSetup", 0)
+ \ || @% == ""
+ \ || s:HGCommandEditFileRunning > 0
+ \ || exists("b:HGOrigBuffNR")
+ unlet! b:HGRevision
+ unlet! b:HGBranch
+ unlet! b:HGRepository
+ return
+ endif
+
+ if !filereadable(expand("%"))
+ return -1
+ endif
+
+ let revision=""
+ let branch=""
+ let repository=""
+
+ exec s:HGGetStatusVars('revision', 'branch', 'repository')
+ "echomsg "DBG ".revision."#".branch."#".repository
+ if revision != ""
+ let b:HGRevision=revision
+ else
+ unlet! b:HGRevision
+ endif
+ if branch != ""
+ let b:HGBranch=branch
+ else
+ unlet! b:HGBranch
+ endif
+ if repository != ""
+ let b:HGRepository=repository
+ else
+ unlet! b:HGRepository
+ endif
+ silent do HGCommand User HGBufferSetup
+ let b:HGBufferSetup=1
+endfunction
+
+" Function: s:HGMarkOrigBufferForSetup(hgbuffer) {{{2
+" Resets the buffer setup state of the original buffer for a given HG buffer.
+" Returns: The HG buffer number in a passthrough mode.
+
+function! s:HGMarkOrigBufferForSetup(hgBuffer)
+ checktime
+ if a:hgBuffer != -1
+ let origBuffer = s:HGBufferCheck(a:hgBuffer)
+ "This should never not work, but I'm paranoid
+ if origBuffer != a:hgBuffer
+ call setbufvar(origBuffer, "HGBufferSetup", 0)
+ endif
+ endif
+ return a:hgBuffer
+endfunction
+
+" Function: s:HGOverrideOption(option, [value]) {{{2
+" Provides a temporary override for the given HG option. If no value is
+" passed, the override is disabled.
+
+function! s:HGOverrideOption(option, ...)
+ if a:0 == 0
+ unlet! s:{a:option}Override
+ else
+ let s:{a:option}Override = a:1
+ endif
+endfunction
+
+" Function: s:HGWipeoutCommandBuffers() {{{2
+" Clears all current HG buffers of the specified type for a given source.
+
+function! s:HGWipeoutCommandBuffers(originalBuffer, hgCommand)
+ let buffer = 1
+ while buffer <= bufnr('$')
+ if getbufvar(buffer, 'HGOrigBuffNR') == a:originalBuffer
+ if getbufvar(buffer, 'HGCommand') == a:hgCommand
+ execute 'bw' buffer
+ endif
+ endif
+ let buffer = buffer + 1
+ endwhile
+endfunction
+
+" Section: Public functions {{{1
+
+" Function: HGGetRevision() {{{2
+" Global function for retrieving the current buffer's HG revision number.
+" Returns: Revision number or an empty string if an error occurs.
+
+function! HGGetRevision()
+ let revision=""
+ exec s:HGGetStatusVars('revision', '', '')
+ return revision
+endfunction
+
+" Function: HGDisableBufferSetup() {{{2
+" Global function for deactivating the buffer autovariables.
+
+function! HGDisableBufferSetup()
+ let g:HGCommandEnableBufferSetup=0
+ silent! augroup! HGCommandPlugin
+endfunction
+
+" Function: HGEnableBufferSetup() {{{2
+" Global function for activating the buffer autovariables.
+
+function! HGEnableBufferSetup()
+ let g:HGCommandEnableBufferSetup=1
+ augroup HGCommandPlugin
+ au!
+ au BufEnter * call s:HGSetupBuffer()
+ augroup END
+
+ " Only auto-load if the plugin is fully loaded. This gives other plugins a
+ " chance to run.
+ if g:loaded_hgcommand == 2
+ call s:HGSetupBuffer()
+ endif
+endfunction
+
+" Function: HGGetStatusLine() {{{2
+" Default (sample) status line entry for HG files. This is only useful if
+" HG-managed buffer mode is on (see the HGCommandEnableBufferSetup variable
+" for how to do this).
+
+function! HGGetStatusLine()
+ if exists('b:HGSourceFile')
+ " This is a result buffer
+ let value='[' . b:HGCommand . ' ' . b:HGSourceFile
+ if exists('b:HGStatusText')
+ let value=value . ' ' . b:HGStatusText
+ endif
+ let value = value . ']'
+ return value
+ endif
+
+ if exists('b:HGRevision')
+ \ && b:HGRevision != ''
+ \ && exists('b:HGBranch')
+ \ && b:HGBranch != ''
+ \ && exists('b:HGRepository')
+ \ && b:HGRepository != ''
+ \ && exists('g:HGCommandEnableBufferSetup')
+ \ && g:HGCommandEnableBufferSetup
+ return '[HG ' . b:HGRepository . '/' . b:HGBranch .'/' . b:HGRevision . ']'
+ else
+ return ''
+ endif
+endfunction
+
+" Section: HG command functions {{{1
+
+" Function: s:HGAdd() {{{2
+function! s:HGAdd()
+ return s:HGMarkOrigBufferForSetup(s:HGDoCommand('add', 'hgadd', ''))
+endfunction
+
+" Function: s:HGAnnotate(...) {{{2
+function! s:HGAnnotate(...)
+ if a:0 == 0
+ if &filetype == "HGAnnotate"
+ " This is a HGAnnotate buffer. Perform annotation of the version
+ " indicated by the current line.
+ let revision = substitute(getline("."),'\(^[0-9]*\):.*','\1','')
+ if s:HGGetOption('HGCommandAnnotateParent', 0) != 0 && revision > 0
+ let revision = revision - 1
+ endif
+ else
+ let revision=HGGetRevision()
+ if revision == ""
+ echoerr "Unable to obtain HG version information."
+ return -1
+ endif
+ endif
+ else
+ let revision=a:1
+ endif
+
+ if revision == "NEW"
+ echo "No annotatation available for new file."
+ return -1
+ endif
+
+ let resultBuffer=s:HGDoCommand('annotate -ndu -r ' . revision, 'hgannotate', revision)
+ echomsg "DBG: ".resultBuffer
+ if resultBuffer != -1
+ set filetype=HGAnnotate
+ endif
+
+ return resultBuffer
+endfunction
+
+" Function: s:HGCommit() {{{2
+function! s:HGCommit(...)
+ " Handle the commit message being specified. If a message is supplied, it
+ " is used; if bang is supplied, an empty message is used; otherwise, the
+ " user is provided a buffer from which to edit the commit message.
+ if a:2 != "" || a:1 == "!"
+ return s:HGMarkOrigBufferForSetup(s:HGDoCommand('commit -m "' . a:2 . '"', 'hgcommit', ''))
+ endif
+
+ let hgBufferCheck=s:HGCurrentBufferCheck()
+ if hgBufferCheck == -1
+ echo "Original buffer no longer exists, aborting."
+ return -1
+ endif
+
+ " Protect against windows' backslashes in paths. They confuse exec'd
+ " commands.
+
+ let shellSlashBak = &shellslash
+ try
+ set shellslash
+
+ let messageFileName = tempname()
+
+ let fileName=bufname(hgBufferCheck)
+ let realFilePath=s:HGResolveLink(fileName)
+ let newCwd=fnamemodify(realFilePath, ':h')
+ if strlen(newCwd) == 0
+ " Account for autochdir being in effect, which will make this blank, but
+ " we know we'll be in the current directory for the original file.
+ let newCwd = getcwd()
+ endif
+
+ let realFileName=fnamemodify(realFilePath, ':t')
+
+ if s:HGEditFile(messageFileName, hgBufferCheck) == -1
+ return
+ endif
+
+ " Protect against case and backslash issues in Windows.
+ let autoPattern = '\c' . messageFileName
+
+ " Ensure existance of group
+ augroup HGCommit
+ augroup END
+
+ execute 'au HGCommit BufDelete' autoPattern 'call delete("' . messageFileName . '")'
+ execute 'au HGCommit BufDelete' autoPattern 'au! HGCommit * ' autoPattern
+
+ " Create a commit mapping. The mapping must clear all autocommands in case
+ " it is invoked when HGCommandCommitOnWrite is active, as well as to not
+ " invoke the buffer deletion autocommand.
+
+ execute 'nnoremap <silent> <buffer> <Plug>HGCommit '.
+ \ ':au! HGCommit * ' . autoPattern . '<CR>'.
+ \ ':g/^HG:/d<CR>'.
+ \ ':update<CR>'.
+ \ ':call <SID>HGFinishCommit("' . messageFileName . '",' .
+ \ '"' . newCwd . '",' .
+ \ '"' . realFileName . '",' .
+ \ hgBufferCheck . ')<CR>'
+
+ silent 0put ='HG: ----------------------------------------------------------------------'
+ silent put =\"HG: Enter Log. Lines beginning with `HG:' are removed automatically\"
+ silent put ='HG: Type <leader>cc (or your own <Plug>HGCommit mapping)'
+
+ if s:HGGetOption('HGCommandCommitOnWrite', 1) == 1
+ execute 'au HGCommit BufWritePre' autoPattern 'g/^HG:/d'
+ execute 'au HGCommit BufWritePost' autoPattern 'call s:HGFinishCommit("' . messageFileName . '", "' . newCwd . '", "' . realFileName . '", ' . hgBufferCheck . ') | au! * ' autoPattern
+ silent put ='HG: or write this buffer'
+ endif
+
+ silent put ='HG: to finish this commit operation'
+ silent put ='HG: ----------------------------------------------------------------------'
+ $
+ let b:HGSourceFile=fileName
+ let b:HGCommand='HGCommit'
+ set filetype=hg
+ finally
+ let &shellslash = shellSlashBak
+ endtry
+
+endfunction
+
+" Function: s:HGDiff(...) {{{2
+function! s:HGDiff(...)
+ if a:0 == 1
+ let revOptions = '-r' . a:1
+ let caption = a:1 . ' -> current'
+ elseif a:0 == 2
+ let revOptions = '-r' . a:1 . ' -r' . a:2
+ let caption = a:1 . ' -> ' . a:2
+ else
+ let revOptions = ''
+ let caption = ''
+ endif
+
+ let hgdiffopt=s:HGGetOption('HGCommandDiffOpt', 'w')
+
+ if hgdiffopt == ""
+ let diffoptionstring=""
+ else
+ let diffoptionstring=" -" . hgdiffopt . " "
+ endif
+
+ let resultBuffer = s:HGDoCommand('diff ' . diffoptionstring . revOptions , 'hgdiff', caption)
+ if resultBuffer != -1
+ set filetype=diff
+ endif
+ return resultBuffer
+endfunction
+
+
+" Function: s:HGGotoOriginal(["!]) {{{2
+function! s:HGGotoOriginal(...)
+ let origBuffNR = s:HGCurrentBufferCheck()
+ if origBuffNR > 0
+ let origWinNR = bufwinnr(origBuffNR)
+ if origWinNR == -1
+ execute 'buffer' origBuffNR
+ else
+ execute origWinNR . 'wincmd w'
+ endif
+ if a:0 == 1
+ if a:1 == "!"
+ let buffnr = 1
+ let buffmaxnr = bufnr("$")
+ while buffnr <= buffmaxnr
+ if getbufvar(buffnr, "HGOrigBuffNR") == origBuffNR
+ execute "bw" buffnr
+ endif
+ let buffnr = buffnr + 1
+ endwhile
+ endif
+ endif
+ endif
+endfunction
+
+" Function: s:HGFinishCommit(messageFile, targetDir, targetFile) {{{2
+function! s:HGFinishCommit(messageFile, targetDir, targetFile, origBuffNR)
+ if filereadable(a:messageFile)
+ let oldCwd=getcwd()
+ if strlen(a:targetDir) > 0
+ execute 'cd' escape(a:targetDir, ' ')
+ endif
+ let resultBuffer=s:HGCreateCommandBuffer('commit -F "' . a:messageFile . '" "'. a:targetFile . '"', 'hgcommit', '', a:origBuffNR)
+ execute 'cd' escape(oldCwd, ' ')
+ execute 'bw' escape(a:messageFile, ' *?\')
+ silent execute 'call delete("' . a:messageFile . '")'
+ return s:HGMarkOrigBufferForSetup(resultBuffer)
+ else
+ echoerr "Can't read message file; no commit is possible."
+ return -1
+ endif
+endfunction
+
+" Function: s:HGLog() {{{2
+function! s:HGLog(...)
+ if a:0 == 0
+ let versionOption = ""
+ let caption = ''
+ else
+ let versionOption=" -r" . a:1
+ let caption = a:1
+ endif
+
+ let resultBuffer=s:HGDoCommand('log' . versionOption, 'hglog', caption)
+ if resultBuffer != ""
+ set filetype=rcslog
+ endif
+ return resultBuffer
+endfunction
+
+" Function: s:HGRevert() {{{2
+function! s:HGRevert()
+ return s:HGMarkOrigBufferForSetup(s:HGDoCommand('revert', 'hgrevert', ''))
+endfunction
+
+" Function: s:HGReview(...) {{{2
+function! s:HGReview(...)
+ if a:0 == 0
+ let versiontag=""
+ if s:HGGetOption('HGCommandInteractive', 0)
+ let versiontag=input('Revision: ')
+ endif
+ if versiontag == ""
+ let versiontag="(current)"
+ let versionOption=""
+ else
+ let versionOption=" -r " . versiontag . " "
+ endif
+ else
+ let versiontag=a:1
+ let versionOption=" -r " . versiontag . " "
+ endif
+
+ let resultBuffer = s:HGDoCommand('cat' . versionOption, 'hgreview', versiontag)
+ if resultBuffer > 0
+ let &filetype=getbufvar(b:HGOrigBuffNR, '&filetype')
+ endif
+
+ return resultBuffer
+endfunction
+
+" Function: s:HGStatus() {{{2
+function! s:HGStatus()
+ return s:HGDoCommand('status', 'hgstatus', '')
+endfunction
+
+
+" Function: s:HGUpdate() {{{2
+function! s:HGUpdate()
+ return s:HGMarkOrigBufferForSetup(s:HGDoCommand('update', 'update', ''))
+endfunction
+
+" Function: s:HGVimDiff(...) {{{2
+function! s:HGVimDiff(...)
+ let originalBuffer = s:HGCurrentBufferCheck()
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1
+ try
+ " If there's already a VimDiff'ed window, restore it.
+ " There may only be one HGVimDiff original window at a time.
+
+ if exists("s:vimDiffSourceBuffer") && s:vimDiffSourceBuffer != originalBuffer
+ " Clear the existing vimdiff setup by removing the result buffers.
+ call s:HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')
+ endif
+
+ " Split and diff
+ if(a:0 == 2)
+ " Reset the vimdiff system, as 2 explicit versions were provided.
+ if exists('s:vimDiffSourceBuffer')
+ call s:HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')
+ endif
+ let resultBuffer = s:HGReview(a:1)
+ if resultBuffer < 0
+ echomsg "Can't open HG revision " . a:1
+ return resultBuffer
+ endif
+ let b:HGCommand = 'vimdiff'
+ diffthis
+ let s:vimDiffBufferCount = 1
+ let s:vimDiffScratchList = '{'. resultBuffer . '}'
+ " If no split method is defined, cheat, and set it to vertical.
+ try
+ call s:HGOverrideOption('HGCommandSplit', s:HGGetOption('HGCommandDiffSplit', s:HGGetOption('HGCommandSplit', 'vertical')))
+ let resultBuffer=s:HGReview(a:2)
+ finally
+ call s:HGOverrideOption('HGCommandSplit')
+ endtry
+ if resultBuffer < 0
+ echomsg "Can't open HG revision " . a:1
+ return resultBuffer
+ endif
+ let b:HGCommand = 'vimdiff'
+ diffthis
+ let s:vimDiffBufferCount = 2
+ let s:vimDiffScratchList = s:vimDiffScratchList . '{'. resultBuffer . '}'
+ else
+ " Add new buffer
+ try
+ " Force splitting behavior, otherwise why use vimdiff?
+ call s:HGOverrideOption("HGCommandEdit", "split")
+ call s:HGOverrideOption("HGCommandSplit", s:HGGetOption('HGCommandDiffSplit', s:HGGetOption('HGCommandSplit', 'vertical')))
+ if(a:0 == 0)
+ let resultBuffer=s:HGReview()
+ else
+ let resultBuffer=s:HGReview(a:1)
+ endif
+ finally
+ call s:HGOverrideOption("HGCommandEdit")
+ call s:HGOverrideOption("HGCommandSplit")
+ endtry
+ if resultBuffer < 0
+ echomsg "Can't open current HG revision"
+ return resultBuffer
+ endif
+ let b:HGCommand = 'vimdiff'
+ diffthis
+
+ if !exists('s:vimDiffBufferCount')
+ " New instance of vimdiff.
+ let s:vimDiffBufferCount = 2
+ let s:vimDiffScratchList = '{' . resultBuffer . '}'
+
+ " This could have been invoked on a HG result buffer, not the
+ " original buffer.
+ wincmd W
+ execute 'buffer' originalBuffer
+ " Store info for later original buffer restore
+ let s:vimDiffRestoreCmd =
+ \ "call setbufvar(".originalBuffer.", \"&diff\", ".getbufvar(originalBuffer, '&diff').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&foldcolumn\", ".getbufvar(originalBuffer, '&foldcolumn').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&foldenable\", ".getbufvar(originalBuffer, '&foldenable').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&foldmethod\", '".getbufvar(originalBuffer, '&foldmethod')."')"
+ \ . "|call setbufvar(".originalBuffer.", \"&scrollbind\", ".getbufvar(originalBuffer, '&scrollbind').")"
+ \ . "|call setbufvar(".originalBuffer.", \"&wrap\", ".getbufvar(originalBuffer, '&wrap').")"
+ \ . "|if &foldmethod=='manual'|execute 'normal zE'|endif"
+ diffthis
+ wincmd w
+ else
+ " Adding a window to an existing vimdiff
+ let s:vimDiffBufferCount = s:vimDiffBufferCount + 1
+ let s:vimDiffScratchList = s:vimDiffScratchList . '{' . resultBuffer . '}'
+ endif
+ endif
+
+ let s:vimDiffSourceBuffer = originalBuffer
+
+ " Avoid executing the modeline in the current buffer after the autocommand.
+
+ let currentBuffer = bufnr('%')
+ let saveModeline = getbufvar(currentBuffer, '&modeline')
+ try
+ call setbufvar(currentBuffer, '&modeline', 0)
+ silent do HGCommand User HGVimDiffFinish
+ finally
+ call setbufvar(currentBuffer, '&modeline', saveModeline)
+ endtry
+ return resultBuffer
+ finally
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1
+ endtry
+endfunction
+
+" Section: Command definitions {{{1
+" Section: Primary commands {{{2
+com! HGAdd call s:HGAdd()
+com! -nargs=? HGAnnotate call s:HGAnnotate(<f-args>)
+com! -bang -nargs=? HGCommit call s:HGCommit(<q-bang>, <q-args>)
+com! -nargs=* HGDiff call s:HGDiff(<f-args>)
+com! -bang HGGotoOriginal call s:HGGotoOriginal(<q-bang>)
+com! -nargs=? HGLog call s:HGLog(<f-args>)
+com! HGRevert call s:HGRevert()
+com! -nargs=? HGReview call s:HGReview(<f-args>)
+com! HGStatus call s:HGStatus()
+com! HGUpdate call s:HGUpdate()
+com! -nargs=* HGVimDiff call s:HGVimDiff(<f-args>)
+
+" Section: HG buffer management commands {{{2
+com! HGDisableBufferSetup call HGDisableBufferSetup()
+com! HGEnableBufferSetup call HGEnableBufferSetup()
+
+" Allow reloading hgcommand.vim
+com! HGReload unlet! loaded_hgcommand | runtime plugin/hgcommand.vim
+
+" Section: Plugin command mappings {{{1
+nnoremap <silent> <Plug>HGAdd :HGAdd<CR>
+nnoremap <silent> <Plug>HGAnnotate :HGAnnotate<CR>
+nnoremap <silent> <Plug>HGCommit :HGCommit<CR>
+nnoremap <silent> <Plug>HGDiff :HGDiff<CR>
+nnoremap <silent> <Plug>HGGotoOriginal :HGGotoOriginal<CR>
+nnoremap <silent> <Plug>HGClearAndGotoOriginal :HGGotoOriginal!<CR>
+nnoremap <silent> <Plug>HGLog :HGLog<CR>
+nnoremap <silent> <Plug>HGRevert :HGRevert<CR>
+nnoremap <silent> <Plug>HGReview :HGReview<CR>
+nnoremap <silent> <Plug>HGStatus :HGStatus<CR>
+nnoremap <silent> <Plug>HGUpdate :HGUpdate<CR>
+nnoremap <silent> <Plug>HGVimDiff :HGVimDiff<CR>
+nnoremap <silent> <Plug>HGWatchers :HGWatchers<CR>
+nnoremap <silent> <Plug>HGWatchAdd :HGWatchAdd<CR>
+nnoremap <silent> <Plug>HGWatchOn :HGWatchOn<CR>
+nnoremap <silent> <Plug>HGWatchOff :HGWatchOff<CR>
+nnoremap <silent> <Plug>HGWatchRemove :HGWatchRemove<CR>
+
+" Section: Default mappings {{{1
+if !hasmapto('<Plug>HGAdd')
+ nmap <unique> <Leader>hga <Plug>HGAdd
+endif
+if !hasmapto('<Plug>HGAnnotate')
+ nmap <unique> <Leader>hgn <Plug>HGAnnotate
+endif
+if !hasmapto('<Plug>HGClearAndGotoOriginal')
+ nmap <unique> <Leader>hgG <Plug>HGClearAndGotoOriginal
+endif
+if !hasmapto('<Plug>HGCommit')
+ nmap <unique> <Leader>hgc <Plug>HGCommit
+endif
+if !hasmapto('<Plug>HGDiff')
+ nmap <unique> <Leader>hgd <Plug>HGDiff
+endif
+if !hasmapto('<Plug>HGGotoOriginal')
+ nmap <unique> <Leader>hgg <Plug>HGGotoOriginal
+endif
+if !hasmapto('<Plug>HGLog')
+ nmap <unique> <Leader>hgl <Plug>HGLog
+endif
+if !hasmapto('<Plug>HGRevert')
+ nmap <unique> <Leader>hgq <Plug>HGRevert
+endif
+if !hasmapto('<Plug>HGReview')
+ nmap <unique> <Leader>hgr <Plug>HGReview
+endif
+if !hasmapto('<Plug>HGStatus')
+ nmap <unique> <Leader>hgs <Plug>HGStatus
+endif
+if !hasmapto('<Plug>HGUpdate')
+ nmap <unique> <Leader>hgu <Plug>HGUpdate
+endif
+if !hasmapto('<Plug>HGVimDiff')
+ nmap <unique> <Leader>hgv <Plug>HGVimDiff
+endif
+
+" Section: Menu items {{{1
+silent! aunmenu Plugin.HG
+amenu <silent> &Plugin.HG.&Add <Plug>HGAdd
+amenu <silent> &Plugin.HG.A&nnotate <Plug>HGAnnotate
+amenu <silent> &Plugin.HG.&Commit <Plug>HGCommit
+amenu <silent> &Plugin.HG.&Diff <Plug>HGDiff
+amenu <silent> &Plugin.HG.&Log <Plug>HGLog
+amenu <silent> &Plugin.HG.Revert <Plug>HGRevert
+amenu <silent> &Plugin.HG.&Review <Plug>HGReview
+amenu <silent> &Plugin.HG.&Status <Plug>HGStatus
+amenu <silent> &Plugin.HG.&Update <Plug>HGUpdate
+amenu <silent> &Plugin.HG.&VimDiff <Plug>HGVimDiff
+amenu <silent> &Plugin.HG.&Watchers <Plug>HGWatchers
+amenu <silent> &Plugin.HG.WatchAdd <Plug>HGWatchAdd
+amenu <silent> &Plugin.HG.WatchOn <Plug>HGWatchOn
+amenu <silent> &Plugin.HG.WatchOff <Plug>HGWatchOff
+amenu <silent> &Plugin.HG.WatchRemove <Plug>HGWatchRemove
+
+" Section: Autocommands to restore vimdiff state {{{1
+function! s:HGVimDiffRestore(vimDiffBuff)
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1
+ try
+ if exists("s:vimDiffSourceBuffer")
+ if a:vimDiffBuff == s:vimDiffSourceBuffer
+ " Original file is being removed.
+ unlet! s:vimDiffSourceBuffer
+ unlet! s:vimDiffBufferCount
+ unlet! s:vimDiffRestoreCmd
+ unlet! s:vimDiffScratchList
+ elseif match(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}') >= 0
+ let s:vimDiffScratchList = substitute(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}', '', '')
+ let s:vimDiffBufferCount = s:vimDiffBufferCount - 1
+ if s:vimDiffBufferCount == 1 && exists('s:vimDiffRestoreCmd')
+ " All scratch buffers are gone, reset the original.
+ " Only restore if the source buffer is still in Diff mode
+
+ let sourceWinNR=bufwinnr(s:vimDiffSourceBuffer)
+ if sourceWinNR != -1
+ " The buffer is visible in at least one window
+ let currentWinNR = winnr()
+ while winbufnr(sourceWinNR) != -1
+ if winbufnr(sourceWinNR) == s:vimDiffSourceBuffer
+ execute sourceWinNR . 'wincmd w'
+ if getwinvar('', "&diff")
+ execute s:vimDiffRestoreCmd
+ endif
+ endif
+ let sourceWinNR = sourceWinNR + 1
+ endwhile
+ execute currentWinNR . 'wincmd w'
+ else
+ " The buffer is hidden. It must be visible in order to set the
+ " diff option.
+ let currentBufNR = bufnr('')
+ execute "hide buffer" s:vimDiffSourceBuffer
+ if getwinvar('', "&diff")
+ execute s:vimDiffRestoreCmd
+ endif
+ execute "hide buffer" currentBufNR
+ endif
+
+ unlet s:vimDiffRestoreCmd
+ unlet s:vimDiffSourceBuffer
+ unlet s:vimDiffBufferCount
+ unlet s:vimDiffScratchList
+ elseif s:vimDiffBufferCount == 0
+ " All buffers are gone.
+ unlet s:vimDiffSourceBuffer
+ unlet s:vimDiffBufferCount
+ unlet s:vimDiffScratchList
+ endif
+ endif
+ endif
+ finally
+ let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1
+ endtry
+endfunction
+
+augroup HGVimDiffRestore
+ au!
+ au BufUnload * call s:HGVimDiffRestore(expand("<abuf>"))
+augroup END
+
+" Section: Optional activation of buffer management {{{1
+
+if s:HGGetOption('HGCommandEnableBufferSetup', 0)
+ call HGEnableBufferSetup()
+endif
+
+" Section: Plugin completion {{{1
+
+let loaded_hgcommand=2
+silent do HGCommand User HGPluginFinish
+" vim:se expandtab sts=2 sw=2: