diff --git a/lisp/outline.el b/lisp/outline.el index 5ac0f0707f1..d933bd4a444 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -92,6 +92,8 @@ outline-mode-prefix-map (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,42 @@ outline--show-headings-up-to-level beg end))) (run-hooks 'outline-view-change-hook))) +(defun outline-show-by-heading-regexp (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) + (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 () + (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)) + (mapconcat (lambda (heading) + (regexp-quote heading)) + (nreverse headings) "\\|"))) + ;;; Visibility cycling