|
|
- ;;; magit-bookmark.el --- bookmark support for Magit -*- lexical-binding: t -*-
-
- ;; Copyright (C) 2010-2019 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>
-
- ;; Inspired by an earlier implementation by Yuri Khan.
-
- ;; 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:
-
- ;; Support for bookmarks for most Magit buffers.
-
- ;;; Code:
-
- (eval-when-compile
- (require 'subr-x))
-
- (require 'magit)
- (require 'bookmark)
-
- ;;; Core
-
- (defun magit--make-bookmark ()
- "Create a bookmark for the current Magit buffer.
- Input values are the major-mode's `magit-bookmark-name' method,
- and the buffer-local values of the variables referenced in its
- `magit-bookmark-variables' property."
- (if (plist-member (symbol-plist major-mode) 'magit-bookmark-variables)
- (let ((bookmark (bookmark-make-record-default 'no-file)))
- (bookmark-prop-set bookmark 'handler 'magit--handle-bookmark)
- (bookmark-prop-set bookmark 'mode major-mode)
- (bookmark-prop-set bookmark 'filename (magit-toplevel))
- (bookmark-prop-set bookmark 'defaults (list (magit-bookmark-name)))
- (dolist (var (get major-mode 'magit-bookmark-variables))
- (bookmark-prop-set bookmark var (symbol-value var)))
- (bookmark-prop-set
- bookmark 'magit-hidden-sections
- (--keep (and (oref it hidden)
- (cons (oref it type)
- (if (derived-mode-p 'magit-stash-mode)
- (replace-regexp-in-string
- (regexp-quote magit-buffer-revision)
- magit-buffer-revision-hash
- (oref it value))
- (oref it value))))
- (oref magit-root-section children)))
- bookmark)
- (user-error "Bookmarking is not implemented for %s buffers" major-mode)))
-
- ;;;###autoload
- (defun magit--handle-bookmark (bookmark)
- "Open a bookmark created by `magit--make-bookmark'.
- Call the `magit-*-setup-buffer' function of the the major-mode
- with the variables' values as arguments, which were recorded by
- `magit--make-bookmark'. Ignore `magit-display-buffer-function'."
- (let ((buffer (let ((default-directory (bookmark-get-filename bookmark))
- (mode (bookmark-prop-get bookmark 'mode))
- (magit-display-buffer-function #'identity)
- (magit-display-buffer-noselect t))
- (apply (intern (format "%s-setup-buffer"
- (substring (symbol-name mode) 0 -5)))
- (--map (bookmark-prop-get bookmark it)
- (get mode 'magit-bookmark-variables))))))
- (set-buffer buffer) ; That is the interface we have to adhere to.
- (when-let ((hidden (bookmark-prop-get bookmark 'magit-hidden-sections)))
- (with-current-buffer buffer
- (dolist (child (oref magit-root-section children))
- (if (member (cons (oref child type)
- (oref child value))
- hidden)
- (magit-section-hide child)
- (magit-section-show child)))))
- nil))
-
- (cl-defgeneric magit-bookmark-name ()
- "Return name for bookmark to current buffer."
- (format "%s%s"
- (substring (symbol-name major-mode) 0 -5)
- (if-let ((vars (get major-mode 'magit-bookmark-variables)))
- (cl-mapcan (lambda (var)
- (let ((val (symbol-value var)))
- (if (and val (atom val))
- (list val)
- val)))
- vars)
- "")))
-
- ;;; Diff
- ;;;; Diff
-
- (put 'magit-diff-mode 'magit-bookmark-variables
- '(magit-buffer-range-hashed
- magit-buffer-typearg
- magit-buffer-diff-args
- magit-buffer-diff-files))
-
- (cl-defmethod magit-bookmark-name (&context (major-mode magit-diff-mode))
- (format "magit-diff(%s%s)"
- (pcase (magit-diff-type)
- (`staged "staged")
- (`unstaged "unstaged")
- (`committed magit-buffer-range)
- (`undefined
- (delq nil (list magit-buffer-typearg magit-buffer-range-hashed))))
- (if magit-buffer-diff-files
- (concat " -- " (mapconcat #'identity magit-buffer-diff-files " "))
- "")))
-
- ;;;; Revision
-
- (put 'magit-revision-mode 'magit-bookmark-variables
- '(magit-buffer-revision-hash
- magit-buffer-diff-args
- magit-buffer-diff-files))
-
- (cl-defmethod magit-bookmark-name (&context (major-mode magit-revision-mode))
- (format "magit-revision(%s %s)"
- (magit-rev-abbrev magit-buffer-revision)
- (if magit-buffer-diff-files
- (mapconcat #'identity magit-buffer-diff-files " ")
- (magit-rev-format "%s" magit-buffer-revision))))
-
- ;;;; Stash
-
- (put 'magit-stash-mode 'magit-bookmark-variables
- '(magit-buffer-revision-hash
- magit-buffer-diff-args
- magit-buffer-diff-files))
-
- (cl-defmethod magit-bookmark-name (&context (major-mode magit-stash-mode))
- (format "magit-stash(%s %s)"
- (magit-rev-abbrev magit-buffer-revision)
- (if magit-buffer-diff-files
- (mapconcat #'identity magit-buffer-diff-files " ")
- (magit-rev-format "%s" magit-buffer-revision))))
-
- ;;; Log
- ;;;; Log
-
- (put 'magit-log-mode 'magit-bookmark-variables
- '(magit-buffer-revisions
- magit-buffer-log-args
- magit-buffer-log-files))
-
- (cl-defmethod magit-bookmark-name (&context (major-mode magit-log-mode))
- (format "magit-log(%s%s)"
- (mapconcat #'identity magit-buffer-revisions " ")
- (if magit-buffer-log-files
- (concat " -- " (mapconcat #'identity magit-buffer-log-files " "))
- "")))
-
- ;;;; Cherry
-
- (put 'magit-cherry-mode 'magit-bookmark-variables
- '(magit-buffer-refname
- magit-buffer-upstream))
-
- (cl-defmethod magit-bookmark-name (&context (major-mode magit-cherry-mode))
- (format "magit-cherry(%s > %s)"
- magit-buffer-refname
- magit-buffer-upstream))
-
- ;;;; Reflog
-
- (put 'magit-reflog-mode 'magit-bookmark-variables
- '(magit-buffer-refname))
-
- (cl-defmethod magit-bookmark-name (&context (major-mode magit-reflog-mode))
- (format "magit-reflog(%s)" magit-buffer-refname))
-
- ;;; Misc
-
- (put 'magit-status-mode 'magit-bookmark-variables nil)
-
- (put 'magit-refs-mode 'magit-bookmark-variables
- '(magit-buffer-upstream
- magit-buffer-arguments))
-
- (put 'magit-stashes-mode 'magit-bookmark-variables nil)
-
- (cl-defmethod magit-bookmark-name (&context (major-mode magit-stashes-mode))
- (format "magit-states(%s)" magit-buffer-refname))
-
- ;;; _
- (provide 'magit-bookmark)
- ;;; magit-bookmark.el ends here
|