diff options
| author | Juri Linkov | 2024-06-10 09:34:15 +0300 |
|---|---|---|
| committer | Juri Linkov | 2024-06-10 09:34:15 +0300 |
| commit | 1a5aa16066bb5180eb92d9c0bfc8cb2c0ce4a4d0 (patch) | |
| tree | d76ceb3f84ad5fa6c7ed76272778d359f9227146 | |
| parent | bd80717d8e762c7559f66d297cdb6144e3f7f958 (diff) | |
| download | emacs-1a5aa16066bb5180eb92d9c0bfc8cb2c0ce4a4d0.tar.gz emacs-1a5aa16066bb5180eb92d9c0bfc8cb2c0ce4a4d0.zip | |
* lisp/outline.el: Improve new feature of preserving outlines after revert.
(outline-minor-mode): Move adding hook 'outline-revert-buffer-rehighlight'
to the same code branch that calls 'outline-minor-mode-highlight-buffer'.
(outline-revert-buffer-rehighlight): Remove same conditions
already existing in 'outline-minor-mode'.
(outline-hidden-headings-regexp): Remove function.
(outline-hidden-headings-paths)
(outline-hidden-headings-restore-paths): New functions
that save and restore complete paths instead of flat regexps.
(outline-revert-buffer-restore-visibility): Use
'outline-hidden-headings-paths' and
'outline-hidden-headings-restore-paths'.
| -rw-r--r-- | lisp/outline.el | 72 |
1 files changed, 46 insertions, 26 deletions
diff --git a/lisp/outline.el b/lisp/outline.el index 4d74b30dba4..c19ee9cf0f6 100644 --- a/lisp/outline.el +++ b/lisp/outline.el | |||
| @@ -574,7 +574,10 @@ See the command `outline-mode' for more information on this mode." | |||
| 574 | (progn | 574 | (progn |
| 575 | (font-lock-add-keywords nil outline-font-lock-keywords t) | 575 | (font-lock-add-keywords nil outline-font-lock-keywords t) |
| 576 | (font-lock-flush)) | 576 | (font-lock-flush)) |
| 577 | (outline-minor-mode-highlight-buffer))) | 577 | (progn |
| 578 | (outline-minor-mode-highlight-buffer) | ||
| 579 | (add-hook 'revert-buffer-restore-functions | ||
| 580 | #'outline-revert-buffer-rehighlight nil t)))) | ||
| 578 | (outline--fix-up-all-buttons) | 581 | (outline--fix-up-all-buttons) |
| 579 | ;; Turn off this mode if we change major modes. | 582 | ;; Turn off this mode if we change major modes. |
| 580 | (add-hook 'change-major-mode-hook | 583 | (add-hook 'change-major-mode-hook |
| @@ -582,8 +585,6 @@ See the command `outline-mode' for more information on this mode." | |||
| 582 | nil t) | 585 | nil t) |
| 583 | (add-hook 'revert-buffer-restore-functions | 586 | (add-hook 'revert-buffer-restore-functions |
| 584 | #'outline-revert-buffer-restore-visibility nil t) | 587 | #'outline-revert-buffer-restore-visibility nil t) |
| 585 | (add-hook 'revert-buffer-restore-functions | ||
| 586 | #'outline-revert-buffer-rehighlight nil t) | ||
| 587 | (setq-local line-move-ignore-invisible t) | 588 | (setq-local line-move-ignore-invisible t) |
| 588 | ;; Cause use of ellipses for invisible text. | 589 | ;; Cause use of ellipses for invisible text. |
| 589 | (add-to-invisibility-spec '(outline . t)) | 590 | (add-to-invisibility-spec '(outline . t)) |
| @@ -1696,44 +1697,63 @@ LEVEL, decides of subtree visibility according to | |||
| 1696 | (point-min) (point-max))) | 1697 | (point-min) (point-max))) |
| 1697 | (run-hooks 'outline-view-change-hook)) | 1698 | (run-hooks 'outline-view-change-hook)) |
| 1698 | 1699 | ||
| 1699 | (defun outline-hidden-headings-regexp () | 1700 | (defun outline-hidden-headings-paths () |
| 1700 | "Return a regexp that matches all currently hidden outlines. | 1701 | "Return a hash with headings of currently hidden outlines. |
| 1701 | This is useful to save the hidden outlines and restore them later, | 1702 | Every hash key is a list whose elements compose a complete path |
| 1702 | for example, after reverting the buffer." | 1703 | of headings descending from the top level down to the bottom level. |
| 1703 | (let ((headings)) | 1704 | This is useful to save the hidden outlines and restore them later |
| 1705 | after reverting the buffer." | ||
| 1706 | (let ((paths (make-hash-table :test #'equal)) | ||
| 1707 | current-path) | ||
| 1704 | (outline-map-region | 1708 | (outline-map-region |
| 1705 | (lambda () | 1709 | (lambda () |
| 1706 | (when (save-excursion | 1710 | (let* ((level (funcall outline-level)) |
| 1707 | (outline-end-of-heading) | 1711 | (heading (buffer-substring-no-properties (pos-bol) (pos-eol))) |
| 1708 | (seq-some (lambda (o) (eq (overlay-get o 'invisible) | 1712 | path) |
| 1709 | 'outline)) | 1713 | (while (and current-path (>= (cdar current-path) level)) |
| 1710 | (overlays-at (point)))) | 1714 | (pop current-path)) |
| 1711 | (push (buffer-substring (pos-bol) (pos-eol)) headings))) | 1715 | (push (cons heading level) current-path) |
| 1716 | (when (save-excursion | ||
| 1717 | (outline-end-of-heading) | ||
| 1718 | (seq-some (lambda (o) (eq (overlay-get o 'invisible) | ||
| 1719 | 'outline)) | ||
| 1720 | (overlays-at (point)))) | ||
| 1721 | (setf (gethash (mapcar #'car current-path) paths) t)))) | ||
| 1712 | (point-min) (point-max)) | 1722 | (point-min) (point-max)) |
| 1713 | (when headings | 1723 | paths)) |
| 1714 | (mapconcat (lambda (heading) | 1724 | |
| 1715 | (concat "\\`" (regexp-quote heading) "\\'")) | 1725 | (defun outline-hidden-headings-restore-paths (paths) |
| 1716 | (nreverse headings) "\\|")))) | 1726 | "Restore hidden outlines from a hash of hidden headings. |
| 1727 | This is useful after reverting the buffer to restore the outlines | ||
| 1728 | hidden by `outline-hidden-headings-paths'." | ||
| 1729 | (let (current-path outline-view-change-hook) | ||
| 1730 | (outline-map-region | ||
| 1731 | (lambda () | ||
| 1732 | (let* ((level (funcall outline-level)) | ||
| 1733 | (heading (buffer-substring (pos-bol) (pos-eol))) | ||
| 1734 | path) | ||
| 1735 | (while (and current-path (>= (cdar current-path) level)) | ||
| 1736 | (pop current-path)) | ||
| 1737 | (push (cons heading level) current-path) | ||
| 1738 | (when (gethash (mapcar #'car current-path) paths) | ||
| 1739 | (outline-hide-subtree)))) | ||
| 1740 | (point-min) (point-max)))) | ||
| 1717 | 1741 | ||
| 1718 | (defun outline-revert-buffer-restore-visibility () | 1742 | (defun outline-revert-buffer-restore-visibility () |
| 1719 | "Preserve visibility when reverting buffer under `outline-minor-mode'. | 1743 | "Preserve visibility when reverting buffer under `outline-minor-mode'. |
| 1720 | This function restores the visibility of outlines after the buffer | 1744 | This function restores the visibility of outlines after the buffer |
| 1721 | under `outline-minor-mode' is reverted by `revert-buffer'." | 1745 | under `outline-minor-mode' is reverted by `revert-buffer'." |
| 1722 | (let ((regexp (outline-hidden-headings-regexp))) | 1746 | (let ((paths (outline-hidden-headings-paths))) |
| 1723 | (when regexp | 1747 | (unless (hash-table-empty-p paths) |
| 1724 | (lambda () | 1748 | (lambda () |
| 1725 | (outline-hide-by-heading-regexp regexp))))) | 1749 | (outline-hidden-headings-restore-paths paths))))) |
| 1726 | 1750 | ||
| 1727 | (defun outline-revert-buffer-rehighlight () | 1751 | (defun outline-revert-buffer-rehighlight () |
| 1728 | "Rehighlight outlines when reverting buffer under `outline-minor-mode'. | 1752 | "Rehighlight outlines when reverting buffer under `outline-minor-mode'. |
| 1729 | This function rehighlights outlines after the buffer under | 1753 | This function rehighlights outlines after the buffer under |
| 1730 | `outline-minor-mode' is reverted by `revert-buffer' when font-lock | 1754 | `outline-minor-mode' is reverted by `revert-buffer' when font-lock |
| 1731 | can't update highlighting for `outline-minor-mode-highlight'." | 1755 | can't update highlighting for `outline-minor-mode-highlight'." |
| 1732 | (when (and outline-minor-mode-highlight | 1756 | (lambda () (outline-minor-mode-highlight-buffer))) |
| 1733 | (not (and global-font-lock-mode | ||
| 1734 | (font-lock-specified-p major-mode)))) | ||
| 1735 | (lambda () | ||
| 1736 | (outline-minor-mode-highlight-buffer)))) | ||
| 1737 | 1757 | ||
| 1738 | 1758 | ||
| 1739 | ;;; Visibility cycling | 1759 | ;;; Visibility cycling |