about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el1360
1 files changed, 1360 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el
new file mode 100644
index 0000000000..22dced2f6f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el
@@ -0,0 +1,1360 @@
+;;; magit-mode.el --- create and refresh Magit buffers  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements the abstract major-mode `magit-mode' from
+;; which almost all other Magit major-modes derive.  The code in here
+;; is mostly concerned with creating and refreshing Magit buffers.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+
+(require 'magit-section)
+(require 'magit-git)
+(require 'magit-popup)
+
+;; For `magit-display-buffer-fullcolumn-most-v1' from `git-commit'
+(defvar git-commit-mode)
+;; For `magit-xref-insert-buttons' from `magit'
+(defvar magit-diff-show-xref-buttons)
+(defvar magit-revision-show-xref-buttons)
+;; For `magit-refresh' and `magit-refresh-all'
+(declare-function magit-auto-revert-buffers "magit-autorevert" ())
+;; For `magit-refresh-buffer'
+(declare-function magit-process-unset-mode-line-error-status "magit-process" ())
+
+(require 'format-spec)
+(require 'help-mode)
+
+;;; Options
+
+(defcustom magit-mode-hook
+  '(magit-load-config-extensions
+    magit-xref-setup)
+  "Hook run when entering a mode derived from Magit mode."
+  :group 'magit-modes
+  :type 'hook
+  :options '(magit-load-config-extensions
+             magit-xref-setup
+             bug-reference-mode))
+
+(defcustom magit-mode-setup-hook
+  '(magit-maybe-save-repository-buffers
+    magit-set-buffer-margin)
+  "Hook run by `magit-mode-setup'.
+
+This is run right after displaying the buffer and right before
+generating or updating its content.  `magit-mode-hook' and other,
+more specific, `magit-mode-*-hook's on the other hand are run
+right before displaying the buffer.  Usually one of these hooks
+should be used instead of this one."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-modes
+  :type 'hook
+  :options '(magit-maybe-save-repository-buffers
+             magit-set-buffer-margin))
+
+(defcustom magit-pre-refresh-hook '(magit-maybe-save-repository-buffers)
+  "Hook run before refreshing in `magit-refresh'.
+
+This hook, or `magit-post-refresh-hook', should be used
+for functions that are not tied to a particular buffer.
+
+To run a function with a particular buffer current, use
+`magit-refresh-buffer-hook' and use `derived-mode-p'
+inside your function."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-refresh
+  :type 'hook
+  :options '(magit-maybe-save-repository-buffers))
+
+(defcustom magit-post-refresh-hook nil
+  "Hook run after refreshing in `magit-refresh'.
+
+This hook, or `magit-pre-refresh-hook', should be used
+for functions that are not tied to a particular buffer.
+
+To run a function with a particular buffer current, use
+`magit-refresh-buffer-hook' and use `derived-mode-p'
+inside your function."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-refresh
+  :type 'hook)
+
+(defcustom magit-display-buffer-function 'magit-display-buffer-traditional
+  "The function used display a Magit buffer.
+
+All Magit buffers (buffers whose major-modes derive from
+`magit-mode') are displayed using `magit-display-buffer',
+which in turn uses the function specified here."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type '(radio (function-item magit-display-buffer-traditional)
+                (function-item magit-display-buffer-same-window-except-diff-v1)
+                (function-item magit-display-buffer-fullframe-status-v1)
+                (function-item magit-display-buffer-fullframe-status-topleft-v1)
+                (function-item magit-display-buffer-fullcolumn-most-v1)
+                (function-item display-buffer)
+                (function :tag "Function")))
+
+(defcustom magit-pre-display-buffer-hook '(magit-save-window-configuration)
+  "Hook run by `magit-display-buffer' before displaying the buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(magit-save-window-configuration))
+
+(defcustom magit-post-display-buffer-hook '(magit-maybe-set-dedicated)
+  "Hook run by `magit-display-buffer' after displaying the buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(magit-maybe-set-dedicated))
+
+(defcustom magit-generate-buffer-name-function
+  'magit-generate-buffer-name-default-function
+  "The function used to generate the name for a Magit buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type '(radio (function-item magit-generate-buffer-name-default-function)
+                (function :tag "Function")))
+
+(defcustom magit-buffer-name-format "%x%M%v: %t%x"
+  "The format string used to name Magit buffers.
+
+The following %-sequences are supported:
+
+`%m' The name of the major-mode, but with the `-mode' suffix
+     removed.
+
+`%M' Like \"%m\" but abbreviate `magit-status-mode' as `magit'.
+
+`%v' The value the buffer is locked to, in parentheses, or an
+     empty string if the buffer is not locked to a value.
+
+`%V' Like \"%v\", but the string is prefixed with a space, unless
+     it is an empty string.
+
+`%t' The top-level directory of the working tree of the
+     repository, or if `magit-uniquify-buffer-names' is non-nil
+     an abbreviation of that.
+
+`%x' If `magit-uniquify-buffer-names' is nil \"*\", otherwise the
+     empty string.  Due to limitations of the `uniquify' package,
+     buffer names must end with the path.
+
+`%T' Obsolete, use \"%t%x\" instead.  Like \"%t\", but append an
+     asterisk if and only if `magit-uniquify-buffer-names' is nil.
+
+The value should always contain \"%m\" or \"%M\", \"%v\" or
+\"%V\", and \"%t\" (or the obsolete \"%T\").
+
+If `magit-uniquify-buffer-names' is non-nil, then the value must
+end with \"%t\" or \"%t%x\" (or the obsolete \"%T\").  See issue
+#2841.
+
+This is used by `magit-generate-buffer-name-default-function'.
+If another `magit-generate-buffer-name-function' is used, then
+it may not respect this option, or on the contrary it may
+support additional %-sequences."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-buffers
+  :type 'string)
+
+(defcustom magit-uniquify-buffer-names t
+  "Whether to uniquify the names of Magit buffers."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type 'boolean)
+
+(defcustom magit-bury-buffer-function 'magit-restore-window-configuration
+  "The function used to bury or kill the current Magit buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type '(radio (function-item quit-window)
+                (function-item magit-mode-quit-window)
+                (function-item magit-restore-window-configuration)
+                (function :tag "Function")))
+
+(defcustom magit-use-sticky-arguments t
+  "How to reuse arguments from existing diff and log buffers.
+
+nil       Always use the default value of the variable
+          `magit-log-arguments' for log commands.  Likewise,
+          always use the default value of the variable
+          `magit-diff-arguments' for diff command calls.
+
+current   If the mode of the current buffer is derived from
+          `magit-log-mode' or `magit-diff-mode', reuse the
+          arguments from that buffer instead of those given by
+          the variable `magit-log-arguments' or
+          `magit-diff-arguments', respectively.
+
+t         Like `current', but if the mode of the current buffer
+          is not derived from `magit-log-mode' or
+          `magit-diff-mode', use the arguments from the current
+          repository's active (i.e. non-locked) `magit-log-mode'
+          or `magit-diff-mode' buffer, respectively, if it
+          exists.
+
+          Note that commands that generate a
+          `magit-revision-mode' or `magit-stash-mode' buffer will
+          also collect their diff arguments from the active
+          `magit-diff-mode' buffer.
+
+In general, there is a separation between the \"sticky\"
+arguments for log and diff buffers, but there is one special
+case: if the current buffer is a log buffer,
+`magit-show-commit' (considered a diff command) uses the file
+filter from the log buffer."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-buffers
+  :type '(choice (const :tag "disabled" nil)
+                 (const :tag "sticky for current" current)
+                 (const :tag "sticky" t)))
+
+(defcustom magit-region-highlight-hook
+  '(magit-section-update-region magit-diff-update-hunk-region)
+  "Functions used to highlight the region.
+
+Each function is run with the current section as only argument
+until one of them returns non-nil.  If all functions return nil,
+then fall back to regular region highlighting."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refresh
+  :type 'hook
+  :options '(magit-section-update-region magit-diff-update-hunk-region))
+
+(defcustom magit-refresh-verbose nil
+  "Whether to revert Magit buffers verbosely."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refresh
+  :type 'boolean)
+
+(defcustom magit-refresh-buffer-hook nil
+  "Normal hook for `magit-refresh-buffer' to run after refreshing."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refresh
+  :type 'hook)
+
+(defcustom magit-refresh-status-buffer t
+  "Whether the status buffer is refreshed after running git.
+
+When this is non-nil, then the status buffer is automatically
+refreshed after running git for side-effects, in addition to the
+current Magit buffer, which is always refreshed automatically.
+
+Only set this to nil after exhausting all other options to
+improve performance."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-refresh
+  :group 'magit-status
+  :type 'boolean)
+
+(defcustom magit-save-repository-buffers t
+  "Whether to save file-visiting buffers when appropriate.
+
+If non-nil, then all modified file-visiting buffers belonging
+to the current repository may be saved before running Magit
+commands and before creating or refreshing Magit buffers.
+If `dontask', then this is done without user intervention, for
+any other non-nil value the user has to confirm each save.
+
+The default is t to avoid surprises, but `dontask' is the
+recommended value."
+  :group 'magit-essentials
+  :group 'magit-buffers
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Save without asking" dontask)))
+
+(defcustom magit-keep-region-overlay nil
+  "Whether to keep the region overlay when there is a valid selection.
+
+By default Magit removes the regular region overlay if, and only
+if, that region constitutes a valid selection as understood by
+Magit commands.  Otherwise it does not remove that overlay, and
+the region looks like it would in other buffers.
+
+There are two types of such valid selections: hunk-internal
+regions and regions that select two or more sibling sections.
+In such cases Magit removes the region overlay and instead
+highlights a slightly larger range.  All text (for hunk-internal
+regions) or the headings of all sections (for sibling selections)
+that are inside that range (not just inside the region) are acted
+on by commands such as the staging command.  This buffer range
+begins at the beginning of the line on which the region begins
+and ends at the end of the line on which the region ends.
+
+Because Magit acts on this larger range and not the region, it is
+actually quite important to visualize that larger range.  If we
+don't do that, then one might think that these commands act on
+the region instead.  If you want to *also* visualize the region,
+then set this option to t.  But please note that when the region
+does *not* constitute a valid selection, then the region is
+*always* visualized as usual, and that it is usually under such
+circumstances that you want to use a non-magit command to act on
+the region.
+
+Besides keeping the region overlay, setting this option to t also
+causes all face properties, except for `:foreground', to be
+ignored for the faces used to highlight headings of selected
+sections.  This avoids the worst conflicts that result from
+displaying the region and the selection overlays at the same
+time.  We are not interested in dealing with other conflicts.
+In fact we *already* provide a way to avoid all of these
+conflicts: *not* changing the value of this option.
+
+It should be clear by now that we consider it a mistake to set
+this to display the region when the Magit selection is also
+visualized, but since it has been requested a few times and
+because it doesn't cost much to offer this option we do so.
+However that might change.  If the existence of this option
+starts complicating other things, then it will be removed."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-miscellaneous
+  :type 'boolean)
+
+;;; Magit Mode
+
+(defvar magit-mode-map
+  (let ((map (make-keymap)))
+    (suppress-keymap map t)
+    (cond ((featurep 'jkl)
+           (define-key map   [return]  'magit-visit-thing)
+           (define-key map [C-return]  'magit-dired-jump)
+           (define-key map   [tab]     'magit-section-toggle)
+           (define-key map [C-tab]     'magit-section-cycle)
+           (define-key map [M-tab]     'magit-section-cycle-diffs)
+           (define-key map [S-tab]     'magit-section-cycle-global)
+           (define-key map (kbd "M-o") 'magit-section-up)
+           (define-key map (kbd   "i") 'magit-section-backward)
+           (define-key map (kbd   "k") 'magit-section-forward)
+           (define-key map (kbd "M-i") 'magit-section-backward-sibling)
+           (define-key map (kbd "M-k") 'magit-section-forward-sibling)
+           (define-key map (kbd   "p") 'magit-push-popup)
+           (define-key map (kbd   ",") 'magit-delete-thing)
+           (define-key map (kbd   ";") 'magit-file-untrack)
+           (define-key map (kbd "C-c C-i") 'magit-gitignore-popup))
+          (t
+           (define-key map [C-return]  'magit-visit-thing)
+           (define-key map (kbd "C-m") 'magit-visit-thing)
+           (define-key map (kbd "C-M-i") 'magit-dired-jump)
+           (define-key map (kbd "C-i") 'magit-section-toggle)
+           (define-key map [C-tab]     'magit-section-cycle)
+           (define-key map [M-tab]     'magit-section-cycle-diffs)
+           ;; [backtab] is the most portable binding for Shift+Tab.
+           (define-key map [backtab]   'magit-section-cycle-global)
+           (define-key map (kbd   "^") 'magit-section-up)
+           (define-key map (kbd   "p") 'magit-section-backward)
+           (define-key map (kbd   "n") 'magit-section-forward)
+           (define-key map (kbd "M-p") 'magit-section-backward-sibling)
+           (define-key map (kbd "M-n") 'magit-section-forward-sibling)
+           (define-key map (kbd   "P") 'magit-push-popup)
+           (define-key map (kbd   "k") 'magit-delete-thing)
+           (define-key map (kbd   "K") 'magit-file-untrack)
+           (define-key map (kbd   "i") 'magit-gitignore)
+           (define-key map (kbd   "I") 'magit-gitignore-popup)))
+    (define-key map (kbd "SPC") 'magit-diff-show-or-scroll-up)
+    (define-key map (kbd "DEL") 'magit-diff-show-or-scroll-down)
+    (define-key map "+"         'magit-diff-more-context)
+    (define-key map "-"         'magit-diff-less-context)
+    (define-key map "0"         'magit-diff-default-context)
+    (define-key map "1"         'magit-section-show-level-1)
+    (define-key map "2"         'magit-section-show-level-2)
+    (define-key map "3"         'magit-section-show-level-3)
+    (define-key map "4"         'magit-section-show-level-4)
+    (define-key map (kbd "M-1") 'magit-section-show-level-1-all)
+    (define-key map (kbd "M-2") 'magit-section-show-level-2-all)
+    (define-key map (kbd "M-3") 'magit-section-show-level-3-all)
+    (define-key map (kbd "M-4") 'magit-section-show-level-4-all)
+    (define-key map "$" 'magit-process-buffer)
+    (define-key map "%" 'magit-worktree-popup)
+    (define-key map "a" 'magit-cherry-apply)
+    (define-key map "A" 'magit-cherry-pick-popup)
+    (define-key map "b" 'magit-branch-popup)
+    (define-key map "B" 'magit-bisect-popup)
+    (define-key map "c" 'magit-commit-popup)
+    (define-key map "d" 'magit-diff-popup)
+    (define-key map "D" 'magit-diff-refresh-popup)
+    (define-key map "e" 'magit-ediff-dwim)
+    (define-key map "E" 'magit-ediff-popup)
+    (define-key map "f" 'magit-fetch-popup)
+    (define-key map "F" 'magit-pull-popup)
+    (define-key map "g" 'magit-refresh)
+    (define-key map "G" 'magit-refresh-all)
+    (define-key map "h" 'magit-dispatch-popup)
+    (define-key map "?" 'magit-dispatch-popup)
+    (define-key map "l" 'magit-log-popup)
+    (define-key map "L" 'magit-log-refresh-popup)
+    (define-key map "m" 'magit-merge-popup)
+    (define-key map "M" 'magit-remote-popup)
+    (define-key map "o" 'magit-submodule-popup)
+    (define-key map "O" 'magit-subtree-popup)
+    (define-key map "q" 'magit-mode-bury-buffer)
+    (define-key map "r" 'magit-rebase-popup)
+    (define-key map "R" 'magit-file-rename)
+    (define-key map "t" 'magit-tag-popup)
+    (define-key map "T" 'magit-notes-popup)
+    (define-key map "s" 'magit-stage-file)
+    (define-key map "S" 'magit-stage-modified)
+    (define-key map "u" 'magit-unstage-file)
+    (define-key map "U" 'magit-unstage-all)
+    (define-key map "v" 'magit-revert-no-commit)
+    (define-key map "V" 'magit-revert-popup)
+    (define-key map "w" 'magit-am-popup)
+    (define-key map "W" 'magit-patch-popup)
+    (define-key map "x" 'magit-reset)
+    (define-key map "X" 'magit-reset-popup)
+    (define-key map "y" 'magit-show-refs-popup)
+    (define-key map "Y" 'magit-cherry)
+    (define-key map "z" 'magit-stash-popup)
+    (define-key map "Z" 'magit-stash-popup)
+    (define-key map ":" 'magit-git-command)
+    (define-key map "!" 'magit-run-popup)
+    (define-key map (kbd "C-c C-b") 'magit-browse-thing)
+    (define-key map (kbd "C-c C-c") 'magit-dispatch-popup)
+    (define-key map (kbd "C-c C-e") 'magit-dispatch-popup)
+    (define-key map (kbd "C-x a")   'magit-add-change-log-entry)
+    (define-key map (kbd "C-x 4 a") 'magit-add-change-log-entry-other-window)
+    (define-key map (kbd "C-w")     'magit-copy-section-value)
+    (define-key map (kbd "M-w")     'magit-copy-buffer-revision)
+    (define-key map [remap evil-previous-line] 'evil-previous-visual-line)
+    (define-key map [remap evil-next-line] 'evil-next-visual-line)
+    map)
+  "Parent keymap for all keymaps of modes derived from `magit-mode'.")
+
+(defun magit-delete-thing ()
+  "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which deletes the thing at point."
+  (interactive)
+  (user-error "There is no thing at point that could be deleted"))
+
+(defun magit-visit-thing ()
+  "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which visits the thing at point."
+  (interactive)
+  (if (eq magit-current-popup 'magit-dispatch-popup)
+      (progn (setq magit-current-popup nil)
+             (call-interactively (key-binding (this-command-keys))))
+    (user-error "There is no thing at point that could be visited")))
+
+(defun magit-browse-thing ()
+  "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which visits the thing at point using `browse-url'."
+  (interactive)
+  (user-error "There is no thing at point that could be browsed"))
+
+(easy-menu-define magit-mode-menu magit-mode-map
+  "Magit menu"
+  '("Magit"
+    ["Refresh" magit-refresh t]
+    ["Refresh all" magit-refresh-all t]
+    "---"
+    ["Stage" magit-stage t]
+    ["Stage modified" magit-stage-modified t]
+    ["Unstage" magit-unstage t]
+    ["Reset index" magit-reset-index t]
+    ["Commit" magit-commit-popup t]
+    ["Add log entry" magit-commit-add-log t]
+    ["Tag" magit-tag t]
+    "---"
+    ["Diff working tree" magit-diff-working-tree t]
+    ["Diff" magit-diff t]
+    ("Log"
+     ["Log" magit-log t]
+     ["Reflog" magit-reflog t]
+     ["Extended..." magit-log-popup t])
+    "---"
+    ["Cherry pick" magit-cherry-pick t]
+    ["Revert commit" magit-revert-popup t]
+    "---"
+    ["Ignore" magit-gitignore t]
+    ["Ignore locally" magit-gitignore-locally t]
+    ["Discard" magit-discard t]
+    ["Reset head" magit-reset-head t]
+    ["Stash" magit-stash t]
+    ["Snapshot" magit-snapshot t]
+    "---"
+    ["Branch..." magit-checkout t]
+    ["Merge" magit-merge t]
+    ["Ediff resolve" magit-ediff-resolve t]
+    ["Rebase..." magit-rebase-popup t]
+    "---"
+    ["Push" magit-push t]
+    ["Pull" magit-pull t]
+    ["Remote update" magit-fetch-all t]
+    ("Submodule"
+     ["Submodule update" magit-submodule-update t]
+     ["Submodule update and init" magit-submodule-setup t]
+     ["Submodule init" magit-submodule-init t]
+     ["Submodule sync" magit-submodule-sync t])
+    "---"
+    ("Extensions")
+    "---"
+    ["Display Git output" magit-process-buffer t]
+    ["Quit Magit" magit-mode-bury-buffer t]))
+
+(defun magit-load-config-extensions ()
+  "Load Magit extensions that are defined at the Git config layer."
+  (dolist (ext (magit-get-all "magit.extension"))
+    (let ((sym (intern (format "magit-%s-mode" ext))))
+      (when (fboundp sym)
+        (funcall sym 1)))))
+
+(define-derived-mode magit-mode special-mode "Magit"
+  "Parent major mode from which Magit major modes inherit.
+
+Magit is documented in info node `(magit)'."
+  :group 'magit-modes
+  (buffer-disable-undo)
+  (setq truncate-lines t)
+  (setq buffer-read-only t)
+  (setq-local line-move-visual t) ; see #1771
+  (setq show-trailing-whitespace nil)
+  (setq list-buffers-directory (abbreviate-file-name default-directory))
+  (hack-dir-local-variables-non-file-buffer)
+  (make-local-variable 'text-property-default-nonsticky)
+  (push (cons 'keymap t) text-property-default-nonsticky)
+  (add-hook 'post-command-hook #'magit-section-update-highlight t t)
+  (add-hook 'deactivate-mark-hook #'magit-section-update-highlight t t)
+  (setq-local redisplay-highlight-region-function 'magit-highlight-region)
+  (setq-local redisplay-unhighlight-region-function 'magit-unhighlight-region)
+  (when (bound-and-true-p global-linum-mode)
+    (linum-mode -1))
+  (when (and (fboundp 'nlinum-mode)
+             (bound-and-true-p global-nlinum-mode))
+    (nlinum-mode -1))
+  (when (and (fboundp 'display-line-numbers-mode)
+             (bound-and-true-p global-display-line-numbers-mode))
+    (display-line-numbers-mode -1))
+  (add-hook 'kill-buffer-hook 'magit-preserve-section-visibility-cache))
+
+(defvar-local magit-region-overlays nil)
+
+(defun magit-delete-region-overlays ()
+  (mapc #'delete-overlay magit-region-overlays)
+  (setq magit-region-overlays nil))
+
+(defun magit-highlight-region (start end window rol)
+  (magit-delete-region-overlays)
+  (if (and (run-hook-with-args-until-success 'magit-region-highlight-hook
+                                             (magit-current-section))
+           (not magit-keep-region-overlay)
+           (not (= (line-number-at-pos start)
+                   (line-number-at-pos end)))
+           ;; (not (eq (car-safe last-command-event) 'mouse-movement))
+           )
+      (funcall (default-value 'redisplay-unhighlight-region-function) rol)
+    (funcall (default-value 'redisplay-highlight-region-function)
+             start end window rol)))
+
+(defun magit-unhighlight-region (rol)
+  (setq magit-section-highlighted-section nil)
+  (magit-delete-region-overlays)
+  (funcall (default-value 'redisplay-unhighlight-region-function) rol))
+
+(defvar-local magit-refresh-args nil
+  "The arguments used to refresh the current buffer.")
+(put 'magit-refresh-args 'permanent-local t)
+
+(defvar-local magit-previous-section nil)
+(put 'magit-previous-section 'permanent-local t)
+
+(defun magit-mode-setup (mode &rest args)
+  "Setup up a MODE buffer using ARGS to generate its content."
+  (magit-mode-setup-internal mode args))
+
+(defun magit-mode-setup-internal (mode args &optional locked)
+  "Setup up a MODE buffer using ARGS to generate its content.
+When optional LOCKED is non-nil, then create a buffer that is
+locked to its value, which is derived from MODE and ARGS."
+  (let ((buffer (magit-mode-get-buffer
+                 mode t nil
+                 (and locked (magit-buffer-lock-value mode args))))
+        (section (magit-current-section)))
+    (with-current-buffer buffer
+      (setq magit-previous-section section)
+      (setq magit-refresh-args args)
+      (funcall mode))
+    (magit-display-buffer buffer)
+    (with-current-buffer buffer
+      (run-hooks 'magit-mode-setup-hook)
+      (magit-refresh-buffer))))
+
+(defvar magit-display-buffer-noselect nil
+  "If non-nil, then `magit-display-buffer' doesn't call `select-window'.")
+
+(defun magit-display-buffer (buffer)
+  "Display BUFFER in some window and maybe select it.
+
+Display the buffer using `magit-display-buffer-function' and
+then, unless `magit-display-buffer-noselect' is non-nil, select
+the window which was used to display the buffer.
+
+Also run the hooks `magit-pre-display-buffer-hook'
+and `magit-post-display-buffer-hook'."
+  (with-current-buffer buffer
+    (run-hooks 'magit-pre-display-buffer-hook))
+  (let ((window (funcall magit-display-buffer-function buffer)))
+    (unless magit-display-buffer-noselect
+      (select-frame-set-input-focus
+       (window-frame
+        (select-window window)))))
+  (with-current-buffer buffer
+    (run-hooks 'magit-post-display-buffer-hook)))
+
+(defun magit-display-buffer-traditional (buffer)
+  "Display BUFFER the way this has traditionally been done."
+  (display-buffer
+   buffer (if (and (derived-mode-p 'magit-mode)
+                   (not (memq (with-current-buffer buffer major-mode)
+                              '(magit-process-mode
+                                magit-revision-mode
+                                magit-diff-mode
+                                magit-stash-mode
+                                magit-status-mode))))
+              '(display-buffer-same-window)
+            nil))) ; display in another window
+
+(defun magit-display-buffer-same-window-except-diff-v1 (buffer)
+  "Display BUFFER in the selected window except for some modes.
+If a buffer's `major-mode' derives from `magit-diff-mode' or
+`magit-process-mode', display it in another window.  Display all
+other buffers in the selected window."
+  (display-buffer
+   buffer (if (with-current-buffer buffer
+                (derived-mode-p 'magit-diff-mode 'magit-process-mode))
+              nil  ; display in another window
+            '(display-buffer-same-window))))
+
+(defun magit--display-buffer-fullframe (buffer alist)
+  (when-let ((window (or (display-buffer-reuse-window buffer alist)
+                         (display-buffer-same-window buffer alist)
+                         (display-buffer-pop-up-window buffer alist)
+                         (display-buffer-use-some-window buffer alist))))
+    (delete-other-windows window)
+    window))
+
+(defun magit-display-buffer-fullframe-status-v1 (buffer)
+  "Display BUFFER, filling entire frame if BUFFER is a status buffer.
+Otherwise, behave like `magit-display-buffer-traditional'."
+  (if (eq (with-current-buffer buffer major-mode)
+          'magit-status-mode)
+      (display-buffer buffer '(magit--display-buffer-fullframe))
+    (magit-display-buffer-traditional buffer)))
+
+(defun magit--display-buffer-topleft (buffer alist)
+  (or (display-buffer-reuse-window buffer alist)
+      (when-let ((window2 (display-buffer-pop-up-window buffer alist)))
+        (let ((window1 (get-buffer-window))
+              (buffer1 (current-buffer))
+              (buffer2 (window-buffer window2))
+              (w2-quit-restore (window-parameter window2 'quit-restore)))
+          (set-window-buffer window1 buffer2)
+          (set-window-buffer window2 buffer1)
+          (select-window window2)
+          ;; Swap some window state that `magit-mode-quit-window' and
+          ;; `quit-restore-window' inspect.
+          (set-window-prev-buffers window2 (cdr (window-prev-buffers window1)))
+          (set-window-prev-buffers window1 nil)
+          (set-window-parameter window2 'magit-dedicated
+                                (window-parameter window1 'magit-dedicated))
+          (set-window-parameter window1 'magit-dedicated t)
+          (set-window-parameter window1 'quit-restore
+                                (list 'window 'window
+                                      (nth 2 w2-quit-restore)
+                                      (nth 3 w2-quit-restore)))
+          (set-window-parameter window2 'quit-restore nil)
+          window1))))
+
+(defun magit-display-buffer-fullframe-status-topleft-v1 (buffer)
+  "Display BUFFER, filling entire frame if BUFFER is a status buffer.
+When BUFFER derives from `magit-diff-mode' or
+`magit-process-mode', try to display BUFFER to the top or left of
+the current buffer rather than to the bottom or right, as
+`magit-display-buffer-fullframe-status-v1' would.  Whether the
+split is made vertically or horizontally is determined by
+`split-window-preferred-function'."
+  (display-buffer
+   buffer
+   (cond ((eq (with-current-buffer buffer major-mode)
+              'magit-status-mode)
+          '(magit--display-buffer-fullframe))
+         ((with-current-buffer buffer
+            (derived-mode-p 'magit-diff-mode 'magit-process-mode))
+          '(magit--display-buffer-topleft))
+         (t
+          '(display-buffer-same-window)))))
+
+(defun magit--display-buffer-fullcolumn (buffer alist)
+  (when-let ((window (or (display-buffer-reuse-window buffer alist)
+                         (display-buffer-same-window buffer alist)
+                         (display-buffer-below-selected buffer alist))))
+    (delete-other-windows-vertically window)
+    window))
+
+(defun magit-display-buffer-fullcolumn-most-v1 (buffer)
+  "Display BUFFER using the full column except in some cases.
+For most cases where BUFFER's `major-mode' derives from
+`magit-mode', display it in the selected window and grow that
+window to the full height of the frame, deleting other windows in
+that column as necessary.  However, display BUFFER in another
+window if 1) BUFFER's mode derives from `magit-process-mode', or
+2) BUFFER's mode derives from `magit-diff-mode', provided that
+the mode of the current buffer derives from `magit-log-mode' or
+`magit-cherry-mode'."
+  (display-buffer
+   buffer
+   (cond ((and (or git-commit-mode
+                   (derived-mode-p 'magit-log-mode 'magit-cherry-mode))
+               (with-current-buffer buffer
+                 (derived-mode-p 'magit-diff-mode)))
+          nil)
+         ((with-current-buffer buffer
+            (derived-mode-p 'magit-process-mode))
+          nil)
+         (t
+          '(magit--display-buffer-fullcolumn)))))
+
+(defun magit-maybe-set-dedicated ()
+  "Mark the selected window as dedicated if appropriate.
+
+If a new window was created to display the buffer, then remember
+that fact.  That information is used by `magit-mode-quit-window',
+to determine whether the window should be deleted when its last
+Magit buffer is buried."
+  (let ((window (get-buffer-window (current-buffer))))
+    (when (and (window-live-p window)
+               (not (window-prev-buffers window)))
+      (set-window-parameter window 'magit-dedicated t))))
+
+(defvar-local magit--default-directory nil
+  "Value of `default-directory' when buffer is generated.
+This exists to prevent a let-bound `default-directory' from
+tricking `magit-mode-get-buffer' or `magit-mode-get-buffers' into
+thinking a buffer belongs to a repo that it doesn't.")
+(put 'magit--default-directory 'permanent-local t)
+
+(defun magit-mode-get-buffers ()
+  (let ((topdir (magit-toplevel)))
+    (--filter (with-current-buffer it
+                (and (derived-mode-p 'magit-mode)
+                     (equal magit--default-directory topdir)))
+              (buffer-list))))
+
+(defvar-local magit-buffer-locked-p nil)
+(put 'magit-buffer-locked-p 'permanent-local t)
+
+(defun magit-mode-get-buffer (mode &optional create frame value)
+  (if-let ((topdir (magit-toplevel)))
+      (or (--first (with-current-buffer it
+                     (and (eq major-mode mode)
+                          (equal magit--default-directory topdir)
+                          (if value
+                              (and magit-buffer-locked-p
+                                   (equal (magit-buffer-lock-value) value))
+                            (not magit-buffer-locked-p))))
+                   (if frame
+                       (mapcar #'window-buffer
+                               (window-list (unless (eq frame t) frame)))
+                     (buffer-list)))
+          (and create
+               (let ((default-directory topdir))
+                 (magit-generate-new-buffer mode value))))
+    (magit--not-inside-repository-error)))
+
+(defun magit-generate-new-buffer (mode &optional value)
+  (let* ((name (funcall magit-generate-buffer-name-function mode value))
+         (buffer (generate-new-buffer name)))
+    (with-current-buffer buffer
+      (setq magit--default-directory default-directory)
+      (setq magit-buffer-locked-p (and value t))
+      (magit-restore-section-visibility-cache mode))
+    (when magit-uniquify-buffer-names
+      (add-to-list 'uniquify-list-buffers-directory-modes mode)
+      (with-current-buffer buffer
+        (setq list-buffers-directory (abbreviate-file-name default-directory)))
+      (let ((uniquify-buffer-name-style
+             (if (memq uniquify-buffer-name-style '(nil forward))
+                 'post-forward-angle-brackets
+               uniquify-buffer-name-style)))
+        (uniquify-rationalize-file-buffer-names
+         name (file-name-directory (directory-file-name default-directory))
+         buffer)))
+    buffer))
+
+(defun magit-generate-buffer-name-default-function (mode &optional value)
+  "Generate buffer name for a MODE buffer in the current repository.
+The returned name is based on `magit-buffer-name-format' and
+takes `magit-uniquify-buffer-names' and VALUE, if non-nil, into
+account."
+  (let ((m (substring (symbol-name mode) 0 -5))
+        (v (and value (format "%s" (if (listp value) value (list value)))))
+        (n (if magit-uniquify-buffer-names
+               (file-name-nondirectory
+                (directory-file-name default-directory))
+             (abbreviate-file-name default-directory))))
+    (format-spec
+     magit-buffer-name-format
+     `((?m . ,m)
+       (?M . ,(if (eq mode 'magit-status-mode) "magit" m))
+       (?v . ,(or v ""))
+       (?V . ,(if v (concat " " v) ""))
+       (?t . ,n)
+       (?x . ,(if magit-uniquify-buffer-names "" "*"))
+       (?T . ,(if magit-uniquify-buffer-names n (concat n "*")))))))
+
+(defun magit-toggle-buffer-lock ()
+  "Lock the current buffer to its value or unlock it.
+
+Locking a buffer to its value prevents it from being reused to
+display another value.  The name of a locked buffer contains its
+value, which allows telling it apart from other locked buffers
+and the unlocked buffer.
+
+Not all Magit buffers can be locked to their values, for example
+it wouldn't make sense to lock a status buffer.
+
+There can only be a single unlocked buffer using a certain
+major-mode per repository.  So when a buffer is being unlocked
+and another unlocked buffer already exists for that mode and
+repository, then the former buffer is instead deleted and the
+latter is displayed in its place."
+  (interactive)
+  (if magit-buffer-locked-p
+      (if-let ((unlocked (magit-mode-get-buffer major-mode)))
+          (let ((locked (current-buffer)))
+            (switch-to-buffer unlocked nil t)
+            (kill-buffer locked))
+        (setq magit-buffer-locked-p nil)
+        (rename-buffer (funcall magit-generate-buffer-name-function
+                                major-mode)))
+    (if-let ((value (magit-buffer-lock-value)))
+        (if-let ((locked (magit-mode-get-buffer major-mode nil nil value)))
+            (let ((unlocked (current-buffer)))
+              (switch-to-buffer locked nil t)
+              (kill-buffer unlocked))
+          (setq magit-buffer-locked-p t)
+          (rename-buffer (funcall magit-generate-buffer-name-function
+                                  major-mode value)))
+      (user-error "Buffer has no value it could be locked to"))))
+
+(defvar magit-buffer-lock-functions nil
+  "Provide buffer-locking support for third-party modes.
+An alist of symbols to functions.
+
+The symbol must be the major-mode the locked buffer will have.
+
+The function must take a list of arguments and return a value
+that identifies the buffer (i.e., its 'lock value').  If the
+third-party mode is invoked as
+
+    (magit-mode-setup-internal #\\='my-mode \\='(1 2 3) t)
+
+the function will be invoked as
+
+    (apply lock-func \\='(1 2 3))
+
+if the cons (my-mode . lock-func) is in this list.
+
+This variable is intended for third-party extensions;
+`magit-buffer-lock-value' implements all built-in behavior.
+
+See also `magit-toggle-buffer-lock'.")
+
+(cl-defun magit-buffer-lock-value
+    (&optional (mode major-mode)
+               (args magit-refresh-args))
+  "Find an appropriate buffer lock value for MODE under ARGS.
+See also `magit-buffer-lock-functions'."
+  (cl-case mode
+    (magit-cherry-mode
+     (pcase-let ((`(,upstream ,head) args))
+       (concat head ".." upstream)))
+    (magit-diff-mode
+     (pcase-let ((`(,rev-or-range ,const ,_args ,files) args))
+       (nconc (cons (or rev-or-range
+                        (if (member "--cached" const)
+                            (progn (setq const (delete "--cached" const))
+                                   'staged)
+                          'unstaged))
+                    const)
+              (and files (cons "--" files)))))
+    (magit-log-mode
+     (pcase-let ((`(,revs ,_args ,files) args))
+       (if (and revs files)
+           (append revs (cons "--" files))
+         (append revs files))))
+    (magit-refs-mode
+     (pcase-let ((`(,ref ,args) args))
+       (cons (or ref "HEAD") args)))
+    (magit-revision-mode
+     (pcase-let ((`(,rev ,_const ,_args ,files) args))
+       (if files (cons rev files) (list rev))))
+    ((magit-reflog-mode   ; (ref ~args)
+      magit-stash-mode    ; (stash _const _args _files)
+      magit-stashes-mode) ; (ref)
+     (car args))
+    (t
+     (--when-let (cdr (assq mode magit-buffer-lock-functions))
+       (apply it args)))))
+
+(defun magit-mode-bury-buffer (&optional kill-buffer)
+  "Bury the current buffer.
+With a prefix argument, kill the buffer instead.
+This is done using `magit-bury-buffer-function'."
+  (interactive "P")
+  (funcall magit-bury-buffer-function kill-buffer))
+
+(defun magit-mode-quit-window (kill-buffer)
+  "Quit the selected window and bury its buffer.
+
+This behaves similar to `quit-window', but when the window
+was originally created to display a Magit buffer and the
+current buffer is the last remaining Magit buffer that was
+ever displayed in the selected window, then delete that
+window."
+  (if (or (one-window-p)
+          (--first (let ((buffer (car it)))
+                     (and (not (eq buffer (current-buffer)))
+                          (buffer-live-p buffer)
+                          (or (not (window-parameter nil 'magit-dedicated))
+                              (with-current-buffer buffer
+                                (derived-mode-p 'magit-mode
+                                                'magit-process-mode)))))
+                   (window-prev-buffers)))
+      (quit-window kill-buffer)
+    (let ((window (selected-window)))
+      (quit-window kill-buffer)
+      (when (window-live-p window)
+        (delete-window window)))))
+
+;;; Refresh Magit Buffers
+
+(defvar inhibit-magit-refresh nil)
+
+(defun magit-refresh ()
+  "Refresh some buffers belonging to the current repository.
+
+Refresh the current buffer if its major mode derives from
+`magit-mode', and refresh the corresponding status buffer.
+
+Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
+  (interactive)
+  (unless inhibit-magit-refresh
+    (unwind-protect
+        (let ((start (current-time))
+              (magit--refresh-cache (or magit--refresh-cache
+                                        (list (cons 0 0)))))
+          (when magit-refresh-verbose
+            (message "Refreshing magit..."))
+          (magit-run-hook-with-benchmark 'magit-pre-refresh-hook)
+          (when (derived-mode-p 'magit-mode)
+            (magit-refresh-buffer))
+          (--when-let (and magit-refresh-status-buffer
+                           (not (derived-mode-p 'magit-status-mode))
+                           (magit-mode-get-buffer 'magit-status-mode))
+            (with-current-buffer it
+              (magit-refresh-buffer)))
+          (magit-auto-revert-buffers)
+          (magit-run-hook-with-benchmark 'magit-post-refresh-hook)
+          (when magit-refresh-verbose
+            (message "Refreshing magit...done (%.3fs, cached %s/%s)"
+                     (float-time (time-subtract (current-time) start))
+                     (caar magit--refresh-cache)
+                     (+ (caar magit--refresh-cache)
+                        (cdar magit--refresh-cache)))))
+      (run-hooks 'magit-unwind-refresh-hook))))
+
+(defun magit-refresh-all ()
+  "Refresh all buffers belonging to the current repository.
+
+Refresh all Magit buffers belonging to the current repository,
+and revert buffers that visit files located inside the current
+repository.
+
+Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
+  (interactive)
+  (magit-run-hook-with-benchmark 'magit-pre-refresh-hook)
+  (dolist (buffer (magit-mode-get-buffers))
+    (with-current-buffer buffer (magit-refresh-buffer)))
+  (magit-auto-revert-buffers)
+  (magit-run-hook-with-benchmark 'magit-post-refresh-hook))
+
+(defvar-local magit-refresh-start-time nil)
+
+(defun magit-refresh-buffer ()
+  "Refresh the current Magit buffer."
+  (setq magit-refresh-start-time (current-time))
+  (let ((refresh (intern (format "%s-refresh-buffer"
+                                 (substring (symbol-name major-mode) 0 -5))))
+        (magit--refresh-cache (or magit--refresh-cache (list (cons 0 0)))))
+    (when (functionp refresh)
+      (when magit-refresh-verbose
+        (message "Refreshing buffer `%s'..." (buffer-name)))
+      (let* ((buffer (current-buffer))
+             (windows
+              (--mapcat (with-selected-window it
+                          (with-current-buffer buffer
+                            (when-let ((section (magit-current-section)))
+                              (list
+                               (nconc (list it section)
+                                      (magit-refresh-get-relative-position))))))
+                        (or (get-buffer-window-list buffer nil t)
+                            (list (selected-window))))))
+        (deactivate-mark)
+        (setq magit-section-highlight-overlays nil)
+        (setq magit-section-highlighted-section nil)
+        (setq magit-section-highlighted-sections nil)
+        (setq magit-section-unhighlight-sections nil)
+        (magit-process-unset-mode-line-error-status)
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (save-excursion
+            (apply refresh magit-refresh-args)))
+        (dolist (window windows)
+          (with-selected-window (car window)
+            (with-current-buffer buffer
+              (apply #'magit-section-goto-successor (cdr window)))))
+        (run-hooks 'magit-refresh-buffer-hook)
+        (magit-section-update-highlight)
+        (set-buffer-modified-p nil))
+      (when magit-refresh-verbose
+        (message "Refreshing buffer `%s'...done (%.3fs)" (buffer-name)
+                 (float-time (time-subtract (current-time)
+                                            magit-refresh-start-time)))))))
+
+(defun magit-refresh-get-relative-position ()
+  (when-let ((section (magit-current-section)))
+    (let ((start (oref section start)))
+      (list (count-lines start (point))
+            (- (point) (line-beginning-position))
+            (and (magit-hunk-section-p section)
+                 (region-active-p)
+                 (progn (goto-char (line-beginning-position))
+                        (when  (looking-at "^[-+]") (forward-line))
+                        (while (looking-at "^[ @]") (forward-line))
+                        (let ((beg (point)))
+                          (cond ((looking-at "^[-+]")
+                                 (forward-line)
+                                 (while (looking-at "^[-+]") (forward-line))
+                                 (while (looking-at "^ ")    (forward-line))
+                                 (forward-line -1)
+                                 (regexp-quote (buffer-substring-no-properties
+                                                beg (line-end-position))))
+                                (t t)))))))))
+
+;;; Save File-Visiting Buffers
+
+(defvar disable-magit-save-buffers nil)
+
+(defun magit-pre-command-hook ()
+  (setq disable-magit-save-buffers nil))
+(add-hook 'pre-command-hook #'magit-pre-command-hook)
+
+(defvar magit-after-save-refresh-buffers nil)
+
+(defun magit-after-save-refresh-buffers ()
+  (dolist (buffer magit-after-save-refresh-buffers)
+    (when (buffer-live-p buffer)
+      (with-current-buffer buffer
+        (magit-refresh-buffer))))
+  (setq magit-after-save-refresh-buffers nil)
+  (remove-hook 'post-command-hook 'magit-after-save-refresh-buffers))
+
+(defun magit-after-save-refresh-status ()
+  "Refresh the status buffer of the current repository.
+
+This function is intended to be added to `after-save-hook'.
+
+If the status buffer does not exist or the file being visited in
+the current buffer isn't inside the working tree of a repository,
+then do nothing.
+
+Note that refreshing a Magit buffer is done by re-creating its
+contents from scratch, which can be slow in large repositories.
+If you are not satisfied with Magit's performance, then you
+should obviously not add this function to that hook."
+  (when (and (not disable-magit-save-buffers)
+             (magit-inside-worktree-p t))
+    (--when-let (ignore-errors (magit-mode-get-buffer 'magit-status-mode))
+      (add-to-list 'magit-after-save-refresh-buffers it)
+      (add-hook 'post-command-hook 'magit-after-save-refresh-buffers))))
+
+(defun magit-maybe-save-repository-buffers ()
+  "Maybe save file-visiting buffers belonging to the current repository.
+Do so if `magit-save-repository-buffers' is non-nil.  You should
+not remove this from any hooks, instead set that variable to nil
+if you so desire."
+  (when (and magit-save-repository-buffers
+             (not disable-magit-save-buffers))
+    (setq disable-magit-save-buffers t)
+    (let ((msg (current-message)))
+      (magit-save-repository-buffers
+       (eq magit-save-repository-buffers 'dontask))
+      (when (and msg
+                 (current-message)
+                 (not (equal msg (current-message))))
+        (message "%s" msg)))))
+
+(add-hook 'magit-pre-refresh-hook #'magit-maybe-save-repository-buffers)
+(add-hook 'magit-pre-call-git-hook #'magit-maybe-save-repository-buffers)
+(add-hook 'magit-pre-start-git-hook #'magit-maybe-save-repository-buffers)
+
+(defvar-local magit-inhibit-refresh-save nil)
+
+(defun magit-save-repository-buffers (&optional arg)
+  "Save file-visiting buffers belonging to the current repository.
+After any buffer where `buffer-save-without-query' is non-nil
+is saved without asking, the user is asked about each modified
+buffer which visits a file in the current repository.  Optional
+argument (the prefix) non-nil means save all with no questions."
+  (interactive "P")
+  (when-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
+    (let ((remote (file-remote-p topdir))
+          (save-some-buffers-action-alist
+           `((?Y (lambda (buffer)
+                   (with-current-buffer buffer
+                     (setq buffer-save-without-query t)
+                     (save-buffer)))
+                 "to save the current buffer and remember choice")
+             (?N (lambda (buffer)
+                   (with-current-buffer buffer
+                     (setq magit-inhibit-refresh-save t)))
+                 "to skip the current buffer and remember choice")
+             ,@save-some-buffers-action-alist)))
+      (save-some-buffers
+       arg (lambda ()
+             (and (not magit-inhibit-refresh-save)
+                  buffer-file-name
+                  (file-exists-p (file-name-directory buffer-file-name))
+                  ;; Avoid needlessly connecting to unrelated remotes.
+                  (equal (file-remote-p buffer-file-name)
+                         remote)
+                  (string-prefix-p topdir (file-truename buffer-file-name))
+                  (equal (magit-rev-parse-safe "--show-toplevel")
+                         topdir)))))))
+
+;;; Restore Window Configuration
+
+(defvar magit-inhibit-save-previous-winconf nil)
+
+(defvar-local magit-previous-window-configuration nil)
+(put 'magit-previous-window-configuration 'permanent-local t)
+
+(defun magit-save-window-configuration ()
+  "Save the current window configuration.
+
+Later, when the buffer is buried, it may be restored by
+`magit-restore-window-configuration'."
+  (if magit-inhibit-save-previous-winconf
+      (when (eq magit-inhibit-save-previous-winconf 'unset)
+        (setq magit-previous-window-configuration nil))
+    (unless (get-buffer-window (current-buffer) (selected-frame))
+      (setq magit-previous-window-configuration
+            (current-window-configuration)))))
+
+(defun magit-restore-window-configuration (&optional kill-buffer)
+  "Bury or kill the current buffer and restore previous window configuration."
+  (let ((winconf magit-previous-window-configuration)
+        (buffer (current-buffer))
+        (frame (selected-frame)))
+    (quit-window kill-buffer (selected-window))
+    (when (and winconf (equal frame (window-configuration-frame winconf)))
+      (set-window-configuration winconf)
+      (when (buffer-live-p buffer)
+        (with-current-buffer buffer
+          (setq magit-previous-window-configuration nil))))))
+
+;;; Buffer History
+
+(defun magit-go-backward ()
+  "Move backward in current buffer's history."
+  (interactive)
+  (if help-xref-stack
+      (help-xref-go-back (current-buffer))
+    (user-error "No previous entry in buffer's history")))
+
+(defun magit-go-forward ()
+  "Move forward in current buffer's history."
+  (interactive)
+  (if help-xref-forward-stack
+      (help-xref-go-forward (current-buffer))
+    (user-error "No next entry in buffer's history")))
+
+(defun magit-insert-xref-buttons (&optional _)
+  "Insert xref buttons."
+  (when (or help-xref-stack help-xref-forward-stack)
+    (when help-xref-stack
+      (magit-xref-insert-button help-back-label 'magit-xref-backward))
+    (when help-xref-forward-stack
+      (when help-xref-stack
+        (insert " "))
+      (magit-xref-insert-button help-forward-label 'magit-xref-forward))))
+
+(defun magit-xref-insert-button (label type)
+  (magit-insert-section (button label)
+    (insert-text-button label 'type type
+                        'help-args (list (current-buffer)))))
+
+(define-button-type 'magit-xref-backward
+  :supertype 'help-back
+  'mouse-face 'magit-section-highlight
+  'help-echo (purecopy "mouse-2, RET: go back to previous history entry"))
+
+(define-button-type 'magit-xref-forward
+  :supertype 'help-forward
+  'mouse-face 'magit-section-highlight
+  'help-echo (purecopy "mouse-2, RET: go back to next history entry"))
+
+(defun magit-xref-setup ()
+  "Insert backward/forward buttons if the major-mode supports it.
+Currently `magit-log-mode', `magit-reflog-mode',
+`magit-diff-mode', and `magit-revision-mode' support it"
+  (when (memq major-mode '(magit-log-mode
+                           magit-reflog-mode
+                           magit-diff-mode
+                           magit-revision-mode))
+    (when help-xref-stack-item
+      (push (cons (point) help-xref-stack-item) help-xref-stack)
+      (setq help-xref-forward-stack nil))
+    (when (called-interactively-p 'interactive)
+      (--when-let (nthcdr 10 help-xref-stack)
+        (setcdr it nil)))
+    (setq help-xref-stack-item
+          `(magit-xref-restore ,default-directory ,@magit-refresh-args))))
+
+(defun magit-xref-restore (&rest args)
+  (magit-xref-setup)
+  (setq default-directory  (car args))
+  (setq magit-refresh-args (cdr args))
+  (magit-refresh-buffer))
+
+;;; Repository-Local Cache
+
+(defvar magit-repository-local-cache nil
+  "Alist mapping `magit-toplevel' paths to alists of key/value pairs.")
+
+(defun magit-repository-local-repository ()
+  "Return the key for the current repository."
+  (or (bound-and-true-p magit--default-directory)
+      (magit-toplevel)))
+
+(defun magit-repository-local-set (key value &optional repository)
+  "Set the repository-local VALUE for KEY.
+
+Unless specified, REPOSITORY is the current buffer's repository.
+
+If REPOSITORY is nil (meaning there is no current repository),
+then the value is not cached, and we return nil."
+  (let* ((repokey (or repository (magit-repository-local-repository)))
+         (cache (assoc repokey magit-repository-local-cache)))
+    ;; Don't cache values for a nil REPOSITORY, as the 'set' and 'get'
+    ;; calls for some KEY may happen in unrelated contexts.
+    (when repokey
+      (if cache
+          (let ((keyvalue (assoc key (cdr cache))))
+            (if keyvalue
+                ;; Update pre-existing value for key.
+                (setcdr keyvalue value)
+              ;; No such key in repository-local cache.
+              (push (cons key value) (cdr cache))))
+        ;; No cache for this repository.
+        (push (cons repokey (list (cons key value)))
+              magit-repository-local-cache)))))
+
+(defun magit-repository-local-exists-p (key &optional repository)
+  "Non-nil when a repository-local value exists for KEY.
+
+Returns a (KEY . value) cons cell.
+
+The KEY is matched using `equal'.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+  (let* ((repokey (or repository (magit-repository-local-repository)))
+         (cache (assoc repokey magit-repository-local-cache)))
+    (and cache
+         (assoc key (cdr cache)))))
+
+(defun magit-repository-local-get (key &optional default repository)
+  "Return the repository-local value for KEY.
+
+Return DEFAULT if no value for KEY exists.
+
+The KEY is matched using `equal'.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+  (let ((keyvalue (magit-repository-local-exists-p key repository)))
+    (if keyvalue
+        (cdr keyvalue)
+      default)))
+
+(defun magit-repository-local-delete (key &optional repository)
+  "Delete the repository-local value for KEY.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+  (let* ((repokey (or repository (magit-repository-local-repository)))
+         (cache (assoc repokey magit-repository-local-cache)))
+    (when cache
+      ;; There is no `assoc-delete-all'.
+      (setf (cdr cache)
+            (cl-delete key (cdr cache) :key #'car :test #'equal)))))
+
+(defun magit-zap-caches ()
+  "Zap caches for the current repository.
+Remove the repository's entry from `magit-repository-cache'
+and set `magit-section-visibility-cache' to nil in all of the
+repository's Magit buffers."
+  (interactive)
+  (magit-with-toplevel
+    (setq magit-repository-local-cache
+          (cl-delete default-directory
+                     magit-repository-local-cache
+                     :key #'car :test #'equal)))
+  (dolist (buffer (magit-mode-get-buffers))
+    (with-current-buffer buffer
+      (setq magit-section-visibility-cache nil))))
+
+;;; Utilities
+
+(defun magit-run-hook-with-benchmark (hook)
+  (when hook
+    (if magit-refresh-verbose
+        (let ((start (current-time)))
+          (message "Running %s..." hook)
+          (run-hooks hook)
+          (message "Running %s...done (%.3fs)" hook
+                   (float-time (time-subtract (current-time) start))))
+      (run-hooks hook))))
+
+(provide 'magit-mode)
+;;; magit-mode.el ends here