branch: elpa/magit
commit a47b5098c812b7a7932df802378cb754e3ad8639
Author: Jonas Bernoulli <[email protected]>
Commit: Jonas Bernoulli <[email protected]>
Support displaying visibility indicator in left margin
Closes #5424.
---
lisp/magit-margin.el | 60 +++++++++++++++++++++++++++++----------------------
lisp/magit-section.el | 53 +++++++++++++++++++++++++++++++++++++--------
2 files changed, 78 insertions(+), 35 deletions(-)
diff --git a/lisp/magit-margin.el b/lisp/magit-margin.el
index 1771fee93c4..6803c6f05eb 100644
--- a/lisp/magit-margin.el
+++ b/lisp/magit-margin.el
@@ -129,35 +129,43 @@ does not carry to other options."
;;; Core
-(defun magit-set-buffer-margins (&optional reset refresh)
- (when-let ((option (magit--right-margin-option)))
- (let* ((default (symbol-value option))
- (default-width (nth 2 default)))
- (when (or reset (not magit--right-margin-config))
- (setq magit--right-margin-config (copy-sequence default)))
- (pcase-let ((`(,enable ,style ,_width ,details ,details-width)
- magit--right-margin-config))
- (when (functionp default-width)
- (setf (nth 2 magit--right-margin-config)
- (funcall default-width style details details-width)))
- (dolist (window (get-buffer-window-list nil nil 0))
- (with-selected-window window
- (magit-set-window-margins window)
- (if enable
- (add-hook 'window-configuration-change-hook
- #'magit-set-window-margins nil t)
- (remove-hook 'window-configuration-change-hook
- #'magit-set-window-margins t))))
- (when (and enable (or refresh magit--right-margin-delayed))
- (magit-refresh-buffer))))))
+(defun magit-set-buffer-margins (&optional reset-right refresh-right)
+ (let ((lmargin nil)
+ (rmargin nil)
+ (roption (magit--right-margin-option)))
+ (when (or lmargin roption)
+ (when roption
+ (let* ((default (symbol-value roption))
+ (default-width (nth 2 default)))
+ (when (or reset-right (not magit--right-margin-config))
+ (setq magit--right-margin-config (copy-sequence default)))
+ (pcase-let ((`(,enable ,style ,_width ,details ,details-width)
+ magit--right-margin-config))
+ (setq rmargin enable)
+ (when (functionp default-width)
+ (setf (nth 2 magit--right-margin-config)
+ (funcall default-width style details details-width))))))
+ (dolist (window (get-buffer-window-list nil nil 0))
+ (with-selected-window window
+ (magit-set-window-margins window)
+ (if (or lmargin rmargin)
+ (add-hook 'window-configuration-change-hook
+ #'magit-set-window-margins nil t)
+ (remove-hook 'window-configuration-change-hook
+ #'magit-set-window-margins t))))
+ (when (and rmargin (or refresh-right magit--right-margin-delayed))
+ (magit-refresh-buffer)))))
(defun magit-set-window-margins (&optional window)
(when (or window (setq window (get-buffer-window)))
- (with-selected-window window
- (set-window-margins
- nil (car (window-margins))
- (and (magit--right-margin-active)
- (nth 2 magit--right-margin-config))))))
+ (pcase-let ((`(,left . ,right) (window-margins)))
+ (with-selected-window window
+ (set-window-margins
+ nil
+ (if (characterp (car magit-section-visibility-indicator)) 1 left)
+ (if (magit--right-margin-active)
+ (nth 2 magit--right-margin-config)
+ right))))))
(cl-defun magit-make-margin-overlay (&optional string (previous-line nil
sline))
"Display STRING in the margin of the previous (or current) line.
diff --git a/lisp/magit-section.el b/lisp/magit-section.el
index 8e9dbf8d952..16c3fdda724 100644
--- a/lisp/magit-section.el
+++ b/lisp/magit-section.el
@@ -201,7 +201,7 @@ entries of this alist."
"Whether and how to indicate that a section can be expanded/collapsed.
If nil, then don't show any indicators.
-Otherwise the value has to have one of these two forms:
+Otherwise the value has to have one of these three forms:
\(EXPANDABLE-BITMAP . COLLAPSIBLE-BITMAP)
@@ -212,6 +212,11 @@ Otherwise the value has to have one of these two forms:
To provide extra padding around the indicator, set
`left-fringe-width' in `magit-mode-hook'.
+\(EXPANDABLE-CHAR . COLLAPSIBLE-CHAR)
+
+ In this case every section that can be expanded or collapsed
+ gets an indicator in the left margin.
+
\(STRING . BOOLEAN)
In this case STRING (usually an ellipsis) is shown at the end
@@ -235,6 +240,9 @@ Otherwise the value has to have one of these two forms:
(cons :tag "Use custom fringe indicators"
(variable :tag "Expandable bitmap variable")
(variable :tag "Collapsible bitmap variable"))
+ (cons :tag "Use margin indicators"
+ (char :tag "Expandable char" ?+)
+ (char :tag "Collapsible char" ?-))
(cons :tag "Use ellipses at end of headings"
(string :tag "Ellipsis" "…")
(choice :tag "Use face kludge"
@@ -360,6 +368,24 @@ but that ship has sailed, thus this option."
"Face used for child counts at the end of some section headings."
:group 'magit-section-faces)
+(defface magit-left-margin '((t :inherit default))
+ "Face used for the left margin.
+
+Currently this is only used for section visibility indicators, and only
+when `magit-section-visibility-indicator' is configured to show them in
+the margin.
+
+Due to limitations of how the margin works in Emacs, this is only used
+for those parts of the margin that actually display an indicator. For
+that reason you should probably avoid setting the background color.
+
+Reasonable values include ((t)), which causes the indicator to inherit
+the look of the heading (including section highlighting, if any), and
+\((t :inherit default), which prevents that and causes the margin to
+look like regular un-styled text in the buffer. Building on that, you
+can make it look different, e.g., ((t :inherit default :weight bold)."
+ :group 'magit-section-faces)
+
;;; Classes
(defvar magit--current-section-hook nil
@@ -391,9 +417,10 @@ but that ship has sailed, thus this option."
(defvar-keymap magit-section-heading-map
:doc "Keymap used in the heading line of all expandable sections.
This keymap is used in addition to the section-specific keymap, if any."
- "<double-down-mouse-1>" #'ignore
- "<double-mouse-1>" #'magit-mouse-toggle-section
- "<double-mouse-2>" #'magit-mouse-toggle-section)
+ "<double-down-mouse-1>" #'ignore
+ "<double-mouse-1>" #'magit-mouse-toggle-section
+ "<double-mouse-2>" #'magit-mouse-toggle-section
+ "<left-margin> <mouse-1>" #'magit-mouse-toggle-section)
(defvar-keymap magit-section-mode-map
:doc "Parent keymap for keymaps of modes derived from `magit-section-mode'."
@@ -1968,18 +1995,26 @@ When `magit-section-preserve-visibility' is nil, return
nil."
(cdr magit-section-visibility-indicator)))
(kind (cl-typecase (car magit-section-visibility-indicator)
(symbol 'fringe)
+ (character 'margin)
(string 'ellipsis))))
(pcase kind
- ('fringe
- (let ((ov (magit--overlay-at beg 'magit-vis-indicator 'fringe)))
+ ((or 'fringe 'margin)
+ (let ((ov (magit--overlay-at beg 'magit-vis-indicator kind)))
(unless ov
(setq ov (make-overlay beg eoh nil t))
(overlay-put ov 'evaporate t)
- (overlay-put ov 'magit-vis-indicator 'fringe))
+ (overlay-put ov 'magit-vis-indicator kind))
(overlay-put
ov 'before-string
- (propertize "fringe" 'display
- `(left-fringe ,indicator fringe)))))
+ (pcase kind
+ ('fringe
+ (propertize "fringe" 'display
+ `(left-fringe ,indicator fringe)))
+ ('margin
+ (propertize "margin" 'display
+ `((margin left-margin)
+ ,(propertize (string indicator)
+ 'face 'magit-left-margin))))))))
('ellipsis
(let ((ov (magit--overlay-at (1- eoh) 'magit-vis-indicator 'eoh)))
(cond ((oref section hidden)