with-editor: new mode

Define a new minor mode `with-editor-mode' and the commands
`with-editor-finish' and `with-editor-cancel' which are used to end the
current buffers edit session.

Previously similar commands were defined for both `git-commit-mode' and
`git-rebase-mode'.  The "finish" and "cancel" commands for these two
modes should have been almost identical, however the "rebase" variants
were very insufficient and failed to cover most of the special cases the
"commit" variants knew about.  The "commit" variants on the hand also
weren't properly designed upfront and as a result were rather magical.

Instead of improving these to variants independently, this commit
generalizes the concept, adds hooks to adjust the generalized functions
to the needs of its users, uses the generalized mode and commands for
committing and rebasing, and defines the hook functions necessary to
make the generalized implementation work for these two users.
git-commit: allow use of arbitrary major mode

Decouple the "edit session" logic from the major mode used for editing
a commit message.

Previously `git-commit-mode' was a major mode deriving from `text-mode',
which got turned on for Git commit message files due to an entry in
`auto-mode-alist'.

Aside from "being the major mode" `git-commit-mode' was also responsible
for turning on `with-editor-mode', further setting up font-lock and the
comment logic, and then a bunch of other things.

The different concerns are now split up:

The new minor mode `global-git-commit-mode' serves the same purpose as
the entry in `auto-mode-alist' previously did: tell Emacs to use the
tools defined here when opening a Git commit message file buffer.  It
does so by adding `git-commit-setup-check-buffer' to `find-file-hook'.

Because this logic is defined in `git-commit-mode.el' and not built into
Emacs, it is no longer sufficient to autoload that library.  It has to
be loaded.  If it isn't loaded then the code which could cause it to be
loaded also isn't loaded yet.  Magit loads `git-commit-mode', so this
should not cause any problems for most users.  However users who do not
also use Magit will have to require this library in their init file.
There is no way around it.  All attempts to autoload the dispatch logic
would end up as being effectively equivalent to:

  ;;;###autoload (require 'git-commit-mode)

When appropriate, i.e. when the file opened actually is a Git commit
message file `git-commit-setup-check-buffer' then calls
`git-commit-setup', which does the following:

* Turn on `with-editor-mode', and add the commit specific hook functions
  to the `with-editor' hooks.  After this `git-commit-mode' does not
  have to worry about anything related to finishing the edit session
  logic anymore.

* Turn on the major mode.  Currently this can only be configured
  globally using the new option `git-commit-major-mode', but the idea
  is that `git config' can be used to set per repository major modes.

* Turn on `git-commit-mode'.  All that this mode now does is to setup
  the "pseudo header" and the "message history" key bindings.

* Setup font-locking and the comment logic using
  `git-commit-setup-font-lock'.  This currently cannot be disabled or
  further customized.

* Set `save-place' to nil and possibly modify the text
  slightly (inserting a newline).  This also cannot be disabled.

* Run the `git-commit-setup-hook'.  This is a user customizable hook
  that can be used to disable several things that were forced upon the
  user in the old implementation.  This can also be used to add
  additional features.

It is possible to change the major mode while editing the commit
message.  This is not generally recommended but it does not mess up any
of the most important features that without special steps would be lost
by the mode change.  This is done by making some variables permanently
buffer-local and by re-running `git-commit-setup-font-lock' after the
mode change.  However some of the auxiliary features that were enabled
by `git-commit-setup-hook' might end up being disabled.
Merge branch 'n/with-editor-2' into next