New commands to show/hide outlines by regexp (bug#49731)

* lisp/outline.el (outline-mode-prefix-map): Bind "/ s" to
'outline-show-by-heading-regexp', and "/ h" to
'outline-hide-by-heading-regexp'.
(outline-show-by-heading-regexp)
(outline-hide-by-heading-regexp): New commands.
(outline-hidden-headings-regexp): New helper function.
This commit is contained in:
Juri Linkov 2024-06-03 20:18:46 +03:00
parent a525cfb3af
commit 4395f4d453
2 changed files with 50 additions and 0 deletions

View file

@ -184,6 +184,12 @@ Set 'describe-mode-outline' to nil to get back the old behavior.
** Outline mode
*** New commands to show/hide outlines by regexp.
'/ h' ('outline-hide-by-heading-regexp') asks for a regexp and then
hides the body lines of all outlines whose heading lines match the
regexp. '/ s' ('outline-show-by-heading-regexp') does the same but
shows the matched outlines.
+++
*** 'outline-minor-mode' is supported in tree-sitter major modes.
It can be used in all tree-sitter major modes that set either the

View file

@ -92,6 +92,8 @@ imitate the function `looking-at'.")
(define-key map "\C-o" 'outline-hide-other)
(define-key map "\C-^" 'outline-move-subtree-up)
(define-key map "\C-v" 'outline-move-subtree-down)
(keymap-set map "/ s" #'outline-show-by-heading-regexp)
(keymap-set map "/ h" #'outline-hide-by-heading-regexp)
(define-key map [(control ?<)] 'outline-promote)
(define-key map [(control ?>)] 'outline-demote)
(define-key map "\C-m" 'outline-insert-heading)
@ -1661,6 +1663,48 @@ LEVEL, decides of subtree visibility according to
beg end)))
(run-hooks 'outline-view-change-hook)))
(defun outline-show-by-heading-regexp (regexp)
"Show outlines whose headings match REGEXP."
(interactive (list (read-regexp "Regexp to show outlines")))
(let (outline-view-change-hook)
(outline-map-region
(lambda ()
(when (string-match-p regexp (buffer-substring (pos-bol) (pos-eol)))
(outline-show-branches) ;; To reveal all parent headings
(outline-show-entry)))
(point-min) (point-max)))
(run-hooks 'outline-view-change-hook))
(defun outline-hide-by-heading-regexp (regexp)
"Hide outlines whose headings match REGEXP."
(interactive (list (read-regexp "Regexp to hide outlines")))
(let (outline-view-change-hook)
(outline-map-region
(lambda ()
(when (string-match-p regexp (buffer-substring (pos-bol) (pos-eol)))
(outline-hide-subtree)))
(point-min) (point-max)))
(run-hooks 'outline-view-change-hook))
(defun outline-hidden-headings-regexp ()
"Return a regexp that matches all currently hidden outlines.
This is useful to save the hidden outlines and restore them later,
for example, after reverting the buffer."
(let ((headings))
(outline-map-region
(lambda ()
(when (save-excursion
(outline-end-of-heading)
(seq-some (lambda (o) (eq (overlay-get o 'invisible)
'outline))
(overlays-at (point))))
(push (buffer-substring (pos-bol) (pos-eol)) headings)))
(point-min) (point-max))
(when headings
(mapconcat (lambda (heading)
(concat "\\`" (regexp-quote heading) "\\'"))
(nreverse headings) "\\|"))))
;;; Visibility cycling