Add buttons to outlining and tweak `C-h b' buffer
* lisp/help.el (describe-bindings-outline): Change default to t. (describe-bindings): Tweak the look and remove the explanation. * lisp/outline.el (outline-minor-mode-use-buttons): (outline-minor-mode-buttons): New user options. (outline-hide-subtree): Update buttons. (outline--make-button, outline--make-button-overlay) (outline--insert-open-button, outline--insert-close-button) (outline--fix-up-all-buttons): New functions.
This commit is contained in:
parent
744acbd384
commit
57030b90d5
4 changed files with 112 additions and 14 deletions
|
@ -996,6 +996,13 @@ specific file (@pxref{File Variables}).
|
||||||
major mode's special commands. (The variable
|
major mode's special commands. (The variable
|
||||||
@code{outline-minor-mode-prefix} controls the prefix used.)
|
@code{outline-minor-mode-prefix} controls the prefix used.)
|
||||||
|
|
||||||
|
@vindex outline-minor-mode-use-buttons
|
||||||
|
If @code{outline-minor-mode-use-buttons} is non-@code{nil}, Outline
|
||||||
|
minor mode will use buttons (at the start of the header lines) in
|
||||||
|
addition to ellipsis to show that a section is hidden. Using
|
||||||
|
@kbd{RET} (or clicking on the button with a mouse) will toggle
|
||||||
|
displaying the section.
|
||||||
|
|
||||||
@vindex outline-minor-mode-cycle
|
@vindex outline-minor-mode-cycle
|
||||||
If the @code{outline-minor-mode-cycle} user option is
|
If the @code{outline-minor-mode-cycle} user option is
|
||||||
non-@code{nil}, the @kbd{TAB} and @kbd{S-TAB} keys are enabled on the
|
non-@code{nil}, the @kbd{TAB} and @kbd{S-TAB} keys are enabled on the
|
||||||
|
|
15
etc/NEWS
15
etc/NEWS
|
@ -48,6 +48,10 @@ time.
|
||||||
|
|
||||||
** Help
|
** Help
|
||||||
|
|
||||||
|
---
|
||||||
|
*** 'C-h b' uses outlining by default.
|
||||||
|
Set 'describe-bindings-outline' to nil to get the old behaviour.
|
||||||
|
|
||||||
---
|
---
|
||||||
*** Jumping to function/variable source now saves mark before moving point.
|
*** Jumping to function/variable source now saves mark before moving point.
|
||||||
Jumping to source from "*Help*" buffer moves the point when the source
|
Jumping to source from "*Help*" buffer moves the point when the source
|
||||||
|
@ -57,6 +61,17 @@ buffer is already open. Now, the old point is pushed to mark ring.
|
||||||
*** New key bindings in *Help* buffers: 'n' and 'p'.
|
*** New key bindings in *Help* buffers: 'n' and 'p'.
|
||||||
These will take you (respectively) to the next and previous "page".
|
These will take you (respectively) to the next and previous "page".
|
||||||
|
|
||||||
|
** Outline Minor Mode
|
||||||
|
|
||||||
|
+++
|
||||||
|
*** New user option 'outline-minor-mode-use-buttons'.
|
||||||
|
If non-nil, Outline Minor Mode will use buttons to hide/show outlines
|
||||||
|
in addition to the ellipsis.
|
||||||
|
|
||||||
|
---
|
||||||
|
*** New user option 'outline-minor-mode-buttons'.
|
||||||
|
This is a list of pairs of open/close strings used to display buttons.
|
||||||
|
|
||||||
** Fonts
|
** Fonts
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
17
lisp/help.el
17
lisp/help.el
|
@ -561,11 +561,11 @@ To record all your input, use `open-dribble-file'."
|
||||||
'font-lock-face 'help-key-binding
|
'font-lock-face 'help-key-binding
|
||||||
'face 'help-key-binding))
|
'face 'help-key-binding))
|
||||||
|
|
||||||
(defcustom describe-bindings-outline nil
|
(defcustom describe-bindings-outline t
|
||||||
"Non-nil enables outlines in the output buffer of `describe-bindings'."
|
"Non-nil enables outlines in the output buffer of `describe-bindings'."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'help
|
:group 'help
|
||||||
:version "28.1")
|
:version "29.1")
|
||||||
|
|
||||||
(defun describe-bindings (&optional prefix buffer)
|
(defun describe-bindings (&optional prefix buffer)
|
||||||
"Display a buffer showing a list of all defined keys, and their definitions.
|
"Display a buffer showing a list of all defined keys, and their definitions.
|
||||||
|
@ -592,18 +592,19 @@ or a buffer name."
|
||||||
(setq-local outline-level (lambda () 1))
|
(setq-local outline-level (lambda () 1))
|
||||||
(setq-local outline-minor-mode-cycle t
|
(setq-local outline-minor-mode-cycle t
|
||||||
outline-minor-mode-highlight t)
|
outline-minor-mode-highlight t)
|
||||||
|
(setq-local outline-minor-mode-use-buttons t)
|
||||||
(outline-minor-mode 1)
|
(outline-minor-mode 1)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
(let ((inhibit-read-only t))
|
(let ((inhibit-read-only t))
|
||||||
(goto-char (point-min))
|
|
||||||
(insert (substitute-command-keys
|
|
||||||
(concat "\\<outline-minor-mode-cycle-map>Type "
|
|
||||||
"\\[outline-cycle] or \\[outline-cycle-buffer] "
|
|
||||||
"on headings to cycle their visibility.\n\n")))
|
|
||||||
;; Hide the longest body
|
;; Hide the longest body
|
||||||
(when (and (re-search-forward "Key translations" nil t)
|
(when (and (re-search-forward "Key translations" nil t)
|
||||||
(fboundp 'outline-cycle))
|
(fboundp 'outline-cycle))
|
||||||
(outline-cycle))))))))
|
(outline-cycle))
|
||||||
|
;; Hide ^Ls.
|
||||||
|
(while (search-forward "\n\f\n" nil t)
|
||||||
|
(put-text-property (1+ (match-beginning 0)) (1- (match-end 0))
|
||||||
|
'invisible t))))))))
|
||||||
|
|
||||||
(defun where-is (definition &optional insert)
|
(defun where-is (definition &optional insert)
|
||||||
"Print message listing key sequences that invoke the command DEFINITION.
|
"Print message listing key sequences that invoke the command DEFINITION.
|
||||||
|
|
|
@ -272,6 +272,21 @@ in the file it applies to.")
|
||||||
(defvar outline-font-lock-faces
|
(defvar outline-font-lock-faces
|
||||||
[outline-1 outline-2 outline-3 outline-4
|
[outline-1 outline-2 outline-3 outline-4
|
||||||
outline-5 outline-6 outline-7 outline-8])
|
outline-5 outline-6 outline-7 outline-8])
|
||||||
|
|
||||||
|
(defcustom outline-minor-mode-use-buttons nil
|
||||||
|
"If non-nil, use clickable buttons on the headings.
|
||||||
|
The `outline-minor-mode-buttons' variable specifies how the
|
||||||
|
buttons should look."
|
||||||
|
:type 'boolean
|
||||||
|
:version "29.1")
|
||||||
|
|
||||||
|
(defcustom outline-minor-mode-buttons
|
||||||
|
'(("▶️". "🔽")
|
||||||
|
("▶" . "▼"))
|
||||||
|
"List of close/open pairs to use if using buttons."
|
||||||
|
:type 'sexp
|
||||||
|
:version "29.1")
|
||||||
|
|
||||||
|
|
||||||
(defvar outline-level #'outline-level
|
(defvar outline-level #'outline-level
|
||||||
"Function of no args to compute a header's nesting level in an outline.
|
"Function of no args to compute a header's nesting level in an outline.
|
||||||
|
@ -388,6 +403,8 @@ faces to major mode's faces."
|
||||||
(goto-char (match-beginning 0))
|
(goto-char (match-beginning 0))
|
||||||
(not (get-text-property (point) 'face))))
|
(not (get-text-property (point) 'face))))
|
||||||
(overlay-put overlay 'face (outline-font-lock-face)))
|
(overlay-put overlay 'face (outline-font-lock-face)))
|
||||||
|
(when outline-minor-mode-use-buttons
|
||||||
|
(outline--insert-open-button))
|
||||||
(when outline-minor-mode-cycle
|
(when outline-minor-mode-cycle
|
||||||
(overlay-put overlay 'keymap outline-minor-mode-cycle-map)))
|
(overlay-put overlay 'keymap outline-minor-mode-cycle-map)))
|
||||||
(goto-char (match-end 0))))))
|
(goto-char (match-end 0))))))
|
||||||
|
@ -923,11 +940,64 @@ Note that this does not hide the lines preceding the first heading line."
|
||||||
|
|
||||||
(define-obsolete-function-alias 'show-all #'outline-show-all "25.1")
|
(define-obsolete-function-alias 'show-all #'outline-show-all "25.1")
|
||||||
|
|
||||||
(defun outline-hide-subtree ()
|
(defun outline-hide-subtree (&optional event)
|
||||||
"Hide everything after this heading at deeper levels."
|
"Hide everything after this heading at deeper levels.
|
||||||
(interactive)
|
If non-nil, EVENT should be a mouse event."
|
||||||
|
(interactive (list last-nonmenu-event))
|
||||||
|
(mouse-set-point event)
|
||||||
|
(when (and outline-minor-mode-use-buttons outline-minor-mode)
|
||||||
|
(outline--insert-close-button))
|
||||||
(outline-flag-subtree t))
|
(outline-flag-subtree t))
|
||||||
|
|
||||||
|
(defun outline--make-button (type)
|
||||||
|
(cl-loop for (close . open) in outline-minor-mode-buttons
|
||||||
|
when (and (char-displayable-p (aref close 0))
|
||||||
|
(char-displayable-p (aref open 0)))
|
||||||
|
return (concat (if (eq type 'close)
|
||||||
|
close
|
||||||
|
open)
|
||||||
|
" " (buffer-substring (point) (1+ (point))))))
|
||||||
|
|
||||||
|
(defun outline--make-button-overlay (type)
|
||||||
|
(let ((o (seq-find (lambda (o)
|
||||||
|
(overlay-get o 'outline-button))
|
||||||
|
(overlays-at (point)))))
|
||||||
|
(unless o
|
||||||
|
(setq o (make-overlay (point) (1+ (point))))
|
||||||
|
(overlay-put o 'outline-button t))
|
||||||
|
(overlay-put o 'display (outline--make-button type))
|
||||||
|
o))
|
||||||
|
|
||||||
|
(defun outline--insert-open-button ()
|
||||||
|
(save-excursion
|
||||||
|
(beginning-of-line)
|
||||||
|
(let ((o (outline--make-button-overlay 'open)))
|
||||||
|
(overlay-put o 'help-echo "Click to hide")
|
||||||
|
(overlay-put o 'keymap
|
||||||
|
(define-keymap
|
||||||
|
["RET"] #'outline-hide-subtree
|
||||||
|
["<follow-link>"] 'mouse-face
|
||||||
|
["<mouse-2>"] #'outline-hide-subtree)))))
|
||||||
|
|
||||||
|
(defun outline--insert-close-button ()
|
||||||
|
(save-excursion
|
||||||
|
(beginning-of-line)
|
||||||
|
(let ((o (outline--make-button-overlay 'close)))
|
||||||
|
(overlay-put o 'help-echo "Click to show")
|
||||||
|
(overlay-put o 'keymap
|
||||||
|
(define-keymap
|
||||||
|
["RET"] #'outline-show-subtree
|
||||||
|
["<follow-link>"] 'mouse-face
|
||||||
|
["<mouse-2>"] #'outline-show-subtree)))))
|
||||||
|
|
||||||
|
(defun outline--fix-up-all-buttons ()
|
||||||
|
(outline-map-region
|
||||||
|
(lambda ()
|
||||||
|
(if (eq (outline--cycle-state) 'show-all)
|
||||||
|
(outline--insert-open-button)
|
||||||
|
(outline--insert-close-button)))
|
||||||
|
(point-min) (point-max)))
|
||||||
|
|
||||||
(define-obsolete-function-alias 'hide-subtree #'outline-hide-subtree "25.1")
|
(define-obsolete-function-alias 'hide-subtree #'outline-hide-subtree "25.1")
|
||||||
|
|
||||||
(defun outline-hide-leaves ()
|
(defun outline-hide-leaves ()
|
||||||
|
@ -943,9 +1013,12 @@ Note that this does not hide the lines preceding the first heading line."
|
||||||
|
|
||||||
(define-obsolete-function-alias 'hide-leaves #'outline-hide-leaves "25.1")
|
(define-obsolete-function-alias 'hide-leaves #'outline-hide-leaves "25.1")
|
||||||
|
|
||||||
(defun outline-show-subtree ()
|
(defun outline-show-subtree (&optional event)
|
||||||
"Show everything after this heading at deeper levels."
|
"Show everything after this heading at deeper levels."
|
||||||
(interactive)
|
(interactive (list last-nonmenu-event))
|
||||||
|
(mouse-set-point event)
|
||||||
|
(when (and outline-minor-mode-use-buttons outline-minor-mode)
|
||||||
|
(outline--insert-open-button))
|
||||||
(outline-flag-subtree nil))
|
(outline-flag-subtree nil))
|
||||||
|
|
||||||
(define-obsolete-function-alias 'show-subtree #'outline-show-subtree "25.1")
|
(define-obsolete-function-alias 'show-subtree #'outline-show-subtree "25.1")
|
||||||
|
@ -1295,7 +1368,9 @@ Return either 'hide-all, 'headings-only, or 'show-all."
|
||||||
(t
|
(t
|
||||||
(outline-show-all)
|
(outline-show-all)
|
||||||
(setq outline--cycle-buffer-state 'show-all)
|
(setq outline--cycle-buffer-state 'show-all)
|
||||||
(message "Show all")))))
|
(message "Show all")))
|
||||||
|
(when outline-minor-mode-use-buttons
|
||||||
|
(outline--fix-up-all-buttons))))
|
||||||
|
|
||||||
(defvar outline-navigation-repeat-map
|
(defvar outline-navigation-repeat-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue