* lisp/outline.el (outline-minor-mode-use-margins): New user option.
(outline--use-margins, outline--use-buttons, outline--use-rtl): New buffer-local internal variables. (outline-open, outline-close): Move :ascent center to default of define-icon. Use ASCII-art for text. Fix docstring and help-echo. (outline-close-rtl, outline-open-in-margins) (outline-close-in-margins, outline-close-rtl-in-margins): New icon definitions. (outline-minor-mode-highlight-buffer): Remove outline--insert-open-button since initial outline--fix-up-all-buttons is added now to outline-minor-mode. (outline-minor-mode): Set buffer-local outline--use-buttons, outline--use-margins and outline--use-rtl. Show/hide margins for outline--use-margins. Add hook after-change-functions for editable buffers. Move outline--fix-up-all-buttons for both cases: font-lock and non-font-lock. (outline--use-buttons-p): Remove function. (outline--make-button-overlay): Use outline--use-rtl icon outline-close-rtl. (outline--make-margin-overlay): New function. (outline--insert-open-button, outline--insert-close-button): Add optional arg 'use-margins'. (outline--fix-up-all-buttons): Call outline--insert-close-button and outline--insert-open-button with arg outline--use-margins. (outline-cycle-buffer): Remove outline--fix-up-all-buttons that is already called from outline-flag-region. * lisp/emacs-lisp/icons.el (icons--create): Handle keywords :rotation and :ascent with the default value 'center (bug#57813). * doc/emacs/text.texi (Outline Mode): Mention outline-minor-mode-use-margins.
This commit is contained in:
parent
c6d3d97bf5
commit
0a15956f49
4 changed files with 160 additions and 39 deletions
|
@ -1003,6 +1003,11 @@ 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-use-margins
|
||||
If @code{outline-minor-mode-use-margins} is non-@code{nil}, Outline
|
||||
minor mode will use the window margins in addition to ellipsis to show
|
||||
that a section is hidden.
|
||||
|
||||
@vindex outline-minor-mode-cycle
|
||||
If the @code{outline-minor-mode-cycle} user option is
|
||||
non-@code{nil}, the @kbd{TAB} and @kbd{S-@key{TAB}} keys are enabled on the
|
||||
|
|
13
etc/NEWS
13
etc/NEWS
|
@ -962,7 +962,14 @@ or is itself too long.
|
|||
*** 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. The default is nil in editing modes, but
|
||||
non-nil in 'special-mode' and its derivatives.
|
||||
non-nil in 'help-mode' and its derivatives.
|
||||
|
||||
+++
|
||||
*** New user option 'outline-minor-mode-use-margins'.
|
||||
If non-nil, Outline Minor Mode will use the window margins to
|
||||
hide/show outlines in addition to the ellipsis. The default is
|
||||
non-nil in 'special-mode' and its derivatives, and it can be used in
|
||||
editing modes.
|
||||
|
||||
** Windows
|
||||
|
||||
|
@ -1489,8 +1496,8 @@ characters instead of just 'SPC' and 'TAB'.
|
|||
This mode adds some highlighting, fixes the 'M-q' command, and has
|
||||
commands for doing maintenance of the Emacs NEWS files. In addition,
|
||||
this mode turns on 'outline-minor-mode', and thus displays
|
||||
customizable icons (see 'icon-preference') on heading lines. To
|
||||
disable these icons, customize 'outline-minor-mode-use-buttons' to a
|
||||
customizable icons (see 'icon-preference') in the margins. To
|
||||
disable these icons, customize 'outline-minor-mode-use-margins' to a
|
||||
nil value.
|
||||
|
||||
---
|
||||
|
|
|
@ -202,7 +202,11 @@ present if the icon is represented by an image."
|
|||
:height (if (eq height 'line)
|
||||
(window-default-line-height)
|
||||
height)
|
||||
:scale 1 :ascent 'center)
|
||||
:scale 1
|
||||
:rotation (plist-get keywords :rotation)
|
||||
:ascent (if (plist-member keywords :ascent)
|
||||
(plist-get keywords :ascent)
|
||||
'center))
|
||||
(create-image file))))))
|
||||
|
||||
(cl-defmethod icons--create ((_type (eql 'emoji)) icon _keywords)
|
||||
|
|
175
lisp/outline.el
175
lisp/outline.el
|
@ -292,25 +292,65 @@ buffers (yet) -- that will be amended in a future version."
|
|||
:safe #'booleanp
|
||||
:version "29.1")
|
||||
|
||||
(defvar-local outline--use-buttons nil
|
||||
"Non-nil when buffer displays clickable buttons on the headings.")
|
||||
|
||||
(defvar-local outline--use-rtl nil
|
||||
"Non-nil when direction of clickable buttons is right-to-left.")
|
||||
|
||||
(defcustom outline-minor-mode-use-margins '(derived-mode . special-mode)
|
||||
"Whether to display clickable buttons in the margins.
|
||||
The value should be a `buffer-match-p' condition.
|
||||
|
||||
These buttons can be used to hide and show the body under the heading.
|
||||
Note that this feature is meant to be used in editing buffers."
|
||||
:type 'buffer-predicate
|
||||
:safe #'booleanp
|
||||
:version "29.1")
|
||||
|
||||
(defvar-local outline--use-margins nil
|
||||
"Non-nil when buffer displays clickable buttons in the margins.")
|
||||
|
||||
(define-icon outline-open nil
|
||||
'((image "outline-open.svg" "outline-open.pbm"
|
||||
:height 15 :ascent center)
|
||||
'((image "outline-open.svg" "outline-open.pbm" :height 15)
|
||||
(emoji "🔽")
|
||||
(symbol " ▼ ")
|
||||
(text " open "))
|
||||
"Icon used for buttons for opening a section in outline buffers."
|
||||
(text " v "))
|
||||
"Icon used for buttons for opened sections in outline buffers."
|
||||
:version "29.1"
|
||||
:help-echo "Close this section")
|
||||
|
||||
(define-icon outline-close nil
|
||||
'((image "outline-close.svg" "outline-close.pbm" :height 15)
|
||||
(emoji "▶️")
|
||||
(symbol " ▶ ")
|
||||
(text " > "))
|
||||
"Icon used for buttons for closed sections in outline buffers."
|
||||
:version "29.1"
|
||||
:help-echo "Open this section")
|
||||
|
||||
(define-icon outline-close nil
|
||||
'((image "outline-close.svg" "outline-close.pbm"
|
||||
:height 15 :ascent center)
|
||||
(emoji "▶️")
|
||||
(symbol " ▶ ")
|
||||
(text " close "))
|
||||
"Icon used for buttons for closing a section in outline buffers."
|
||||
:version "29.1"
|
||||
:help-echo "Close this section")
|
||||
(define-icon outline-close-rtl outline-close
|
||||
'((image "outline-close.svg" "outline-close.pbm" :height 15 :rotation 180)
|
||||
(emoji "◀️")
|
||||
(symbol " ◀ ")
|
||||
(text " < "))
|
||||
"Right-to-left icon used for buttons in closed outline sections."
|
||||
:version "29.1")
|
||||
|
||||
(define-icon outline-open-in-margins outline-open
|
||||
'((image "outline-open.svg" "outline-open.pbm" :height 10))
|
||||
"Icon used for buttons for opened sections in margins."
|
||||
:version "29.1")
|
||||
|
||||
(define-icon outline-close-in-margins outline-close
|
||||
'((image "outline-open.svg" "outline-open.pbm" :height 10 :rotation -90))
|
||||
"Icon used for buttons for closed sections in margins."
|
||||
:version "29.1")
|
||||
|
||||
(define-icon outline-close-rtl-in-margins outline-close-rtl
|
||||
'((image "outline-open.svg" "outline-open.pbm" :height 10 :rotation 90))
|
||||
"Right-to-left icon used for closed sections in margins."
|
||||
:version "29.1")
|
||||
|
||||
|
||||
(defvar outline-level #'outline-level
|
||||
|
@ -439,9 +479,7 @@ outline font-lock faces to those of major mode."
|
|||
(when (or (memq outline-minor-mode-highlight '(append override))
|
||||
(and (eq outline-minor-mode-highlight t)
|
||||
(not (get-text-property (match-beginning 0) 'face))))
|
||||
(overlay-put overlay 'face (outline-font-lock-face)))
|
||||
(when (outline--use-buttons-p)
|
||||
(outline--insert-open-button)))
|
||||
(overlay-put overlay 'face (outline-font-lock-face))))
|
||||
(goto-char (match-end 0))))))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -456,13 +494,37 @@ See the command `outline-mode' for more information on this mode."
|
|||
(key-description outline-minor-mode-prefix) outline-mode-prefix-map)
|
||||
(if outline-minor-mode
|
||||
(progn
|
||||
(cond
|
||||
((buffer-match-p outline-minor-mode-use-margins (current-buffer))
|
||||
(setq-local outline--use-margins t))
|
||||
((buffer-match-p outline-minor-mode-use-buttons (current-buffer))
|
||||
(setq-local outline--use-buttons t)))
|
||||
(when (and (or outline--use-buttons outline--use-margins)
|
||||
(eq (current-bidi-paragraph-direction) 'right-to-left))
|
||||
(setq-local outline--use-rtl t))
|
||||
(when outline--use-margins
|
||||
(if outline--use-rtl
|
||||
(setq-local right-margin-width (1+ right-margin-width))
|
||||
(setq-local left-margin-width (1+ left-margin-width)))
|
||||
(setq-local fringes-outside-margins t)
|
||||
;; Force display of margins
|
||||
(set-window-buffer nil (window-buffer)))
|
||||
(when (or outline--use-buttons outline--use-margins)
|
||||
(add-hook 'after-change-functions
|
||||
(lambda (beg end _len)
|
||||
(when outline--use-buttons
|
||||
(remove-overlays beg end 'outline-button t))
|
||||
(when outline--use-margins
|
||||
(remove-overlays beg end 'outline-margin t))
|
||||
(outline--fix-up-all-buttons beg end))
|
||||
nil t))
|
||||
(when outline-minor-mode-highlight
|
||||
(if (and global-font-lock-mode (font-lock-specified-p major-mode))
|
||||
(progn
|
||||
(font-lock-add-keywords nil outline-font-lock-keywords t)
|
||||
(font-lock-flush)
|
||||
(outline--fix-up-all-buttons))
|
||||
(font-lock-flush))
|
||||
(outline-minor-mode-highlight-buffer)))
|
||||
(outline--fix-up-all-buttons)
|
||||
;; Turn off this mode if we change major modes.
|
||||
(add-hook 'change-major-mode-hook
|
||||
(lambda () (outline-minor-mode -1))
|
||||
|
@ -476,16 +538,19 @@ See the command `outline-mode' for more information on this mode."
|
|||
(font-lock-remove-keywords nil outline-font-lock-keywords))
|
||||
(remove-overlays nil nil 'outline-overlay t)
|
||||
(font-lock-flush))
|
||||
(when outline--use-margins
|
||||
(if outline--use-rtl
|
||||
(setq-local right-margin-width (1- right-margin-width))
|
||||
(setq-local left-margin-width (1- left-margin-width)))
|
||||
(setq-local fringes-outside-margins nil)
|
||||
;; Force removal of margins
|
||||
(set-window-buffer nil (window-buffer)))
|
||||
(setq line-move-ignore-invisible nil)
|
||||
;; Cause use of ellipses for invisible text.
|
||||
(remove-from-invisibility-spec '(outline . t))
|
||||
;; When turning off outline mode, get rid of any outline hiding.
|
||||
(outline-show-all)))
|
||||
|
||||
(defun outline--use-buttons-p ()
|
||||
(and outline-minor-mode
|
||||
(buffer-match-p outline-minor-mode-use-buttons (current-buffer))))
|
||||
|
||||
(defvar-local outline-heading-alist ()
|
||||
"Alist associating a heading for every possible level.
|
||||
Each entry is of the form (HEADING . LEVEL).
|
||||
|
@ -1000,8 +1065,11 @@ If non-nil, EVENT should be a mouse event."
|
|||
(overlay-put o 'follow-link 'mouse-face)
|
||||
(overlay-put o 'mouse-face 'highlight)
|
||||
(overlay-put o 'outline-button t))
|
||||
(let ((icon
|
||||
(icon-elements (if (eq type 'close) 'outline-close 'outline-open)))
|
||||
(let ((icon (icon-elements (if (eq type 'close)
|
||||
(if outline--use-rtl
|
||||
'outline-close-rtl
|
||||
'outline-close)
|
||||
'outline-open)))
|
||||
(inhibit-read-only t))
|
||||
;; In editing buffers we use overlays only, but in other buffers
|
||||
;; we use a mix of text properties, text and overlays to make
|
||||
|
@ -1015,10 +1083,40 @@ If non-nil, EVENT should be a mouse event."
|
|||
(overlay-put o 'face (plist-get icon 'face))))
|
||||
o))
|
||||
|
||||
(defun outline--insert-open-button ()
|
||||
(defun outline--make-margin-overlay (type)
|
||||
(let ((o (seq-find (lambda (o)
|
||||
(overlay-get o 'outline-margin))
|
||||
(overlays-at (point)))))
|
||||
(unless o
|
||||
(setq o (make-overlay (point) (1+ (point))))
|
||||
(overlay-put o 'follow-link 'mouse-face)
|
||||
(overlay-put o 'mouse-face 'highlight)
|
||||
(overlay-put o 'outline-margin t))
|
||||
(let ((icon (icon-elements (if (eq type 'close)
|
||||
(if outline--use-rtl
|
||||
'outline-close-rtl-in-margins
|
||||
'outline-close-in-margins)
|
||||
'outline-open-in-margins)))
|
||||
(inhibit-read-only t))
|
||||
(overlay-put
|
||||
o 'before-string
|
||||
(propertize " " 'display
|
||||
`((margin ,(if outline--use-rtl
|
||||
'right-margin 'left-margin))
|
||||
,(or (plist-get icon 'image)
|
||||
(plist-get icon 'string))))))
|
||||
o))
|
||||
|
||||
(defun outline--insert-open-button (&optional use-margins)
|
||||
(with-silent-modifications
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(beginning-of-line)
|
||||
(if use-margins
|
||||
(let ((o (outline--make-margin-overlay 'open)))
|
||||
(overlay-put o 'help-echo "Click to hide")
|
||||
(overlay-put o 'keymap
|
||||
(define-keymap
|
||||
"<mouse-2>" #'outline-hide-subtree)))
|
||||
(when (derived-mode-p 'special-mode)
|
||||
(let ((inhibit-read-only t))
|
||||
(insert " ")
|
||||
|
@ -1028,12 +1126,19 @@ If non-nil, EVENT should be a mouse event."
|
|||
(overlay-put o 'keymap
|
||||
(define-keymap
|
||||
"RET" #'outline-hide-subtree
|
||||
"<mouse-2>" #'outline-hide-subtree))))))
|
||||
"<mouse-2>" #'outline-hide-subtree
|
||||
"<left-margin> <mouse-1>" #'outline-hide-subtree)))))))
|
||||
|
||||
(defun outline--insert-close-button ()
|
||||
(defun outline--insert-close-button (&optional use-margins)
|
||||
(with-silent-modifications
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(beginning-of-line)
|
||||
(if use-margins
|
||||
(let ((o (outline--make-margin-overlay 'close)))
|
||||
(overlay-put o 'help-echo "Click to show")
|
||||
(overlay-put o 'keymap
|
||||
(define-keymap
|
||||
"<mouse-2>" #'outline-show-subtree)))
|
||||
(when (derived-mode-p 'special-mode)
|
||||
(let ((inhibit-read-only t))
|
||||
(insert " ")
|
||||
|
@ -1043,10 +1148,11 @@ If non-nil, EVENT should be a mouse event."
|
|||
(overlay-put o 'keymap
|
||||
(define-keymap
|
||||
"RET" #'outline-show-subtree
|
||||
"<mouse-2>" #'outline-show-subtree))))))
|
||||
"<mouse-2>" #'outline-show-subtree
|
||||
"<left-margin> <mouse-1>" #'outline-show-subtree)))))))
|
||||
|
||||
(defun outline--fix-up-all-buttons (&optional from to)
|
||||
(when (outline--use-buttons-p)
|
||||
(when (or outline--use-buttons outline--use-margins)
|
||||
(when from
|
||||
(save-excursion
|
||||
(goto-char from)
|
||||
|
@ -1057,8 +1163,8 @@ If non-nil, EVENT should be a mouse event."
|
|||
(outline-end-of-heading)
|
||||
(seq-some (lambda (o) (eq (overlay-get o 'invisible) 'outline))
|
||||
(overlays-at (point))))
|
||||
(outline--insert-close-button)
|
||||
(outline--insert-open-button)))
|
||||
(outline--insert-close-button outline--use-margins)
|
||||
(outline--insert-open-button outline--use-margins)))
|
||||
(or from (point-min)) (or to (point-max)))))
|
||||
|
||||
(define-obsolete-function-alias 'hide-subtree #'outline-hide-subtree "25.1")
|
||||
|
@ -1627,8 +1733,7 @@ With a prefix argument, show headings up to that LEVEL."
|
|||
(t
|
||||
(outline-show-all)
|
||||
(setq outline--cycle-buffer-state 'show-all)
|
||||
(message "Show all")))
|
||||
(outline--fix-up-all-buttons)))
|
||||
(message "Show all")))))
|
||||
|
||||
|
||||
(defvar-keymap outline-navigation-repeat-map
|
||||
|
|
Loading…
Add table
Reference in a new issue