From fad64a23e38fbc43cee121db78f00e255df3ecd8 Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Thu, 1 Feb 2024 13:58:20 -0800 Subject: [PATCH] [WIP] Make outline.el able to handle buffers with field properties * lisp/outline.el (outline-back-to-heading, outline-on-heading-p) (outline-next-visible-heading, outline-mark-subtree) (outline-hide-sublevels, outline--insert-button) (outline--fix-up-all-buttons): Inhibit field text motion. * lisp/eshell/em-prompt.el (eshell-outline-search): New function (for testing only). (eshell-prompt-initialize): Initialize outline-mode variables. --- lisp/eshell/em-prompt.el | 14 +++++++++++++- lisp/outline.el | 32 +++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el index 3662c1fa895..bf3a24689f8 100644 --- a/lisp/eshell/em-prompt.el +++ b/lisp/eshell/em-prompt.el @@ -107,6 +107,14 @@ eshell-prompt-repeat-map ;;; Functions: +(defun eshell-outline-search (&optional bound move backward looking-at) + "Search for outline headings. See `outline-search-function'." + ;; FIXME: This probably isn't the right way to do things. Does it + ;; work with multiline prompts? Still, it's useful for a proof of + ;; concept. + (outline-search-text-property 'field 'prompt bound move backward + looking-at)) + (define-minor-mode eshell-prompt-mode "Minor mode for eshell-prompt module. @@ -117,7 +125,11 @@ eshell-prompt-initialize "Initialize the prompting code." (unless eshell-non-interactive-p (add-hook 'eshell-post-command-hook 'eshell-emit-prompt nil t) - (eshell-prompt-mode))) + (eshell-prompt-mode) + + (setq-local outline-search-function #'eshell-outline-search + outline-level (lambda () 1) + outline-minor-mode-use-buttons 'in-margins))) (defun eshell-emit-prompt () "Emit a prompt if eshell is being used interactively." diff --git a/lisp/outline.el b/lisp/outline.el index b50708c1a7b..e7e8d269640 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -686,7 +686,8 @@ 'outline-before-first-heading (defun outline-back-to-heading (&optional invisible-ok) "Move to previous heading line, or beg of this line if it's a heading. Only visible heading lines are considered, unless INVISIBLE-OK is non-nil." - (beginning-of-line) + (let ((inhibit-field-text-motion t)) + (beginning-of-line)) (or (outline-on-heading-p invisible-ok) (let (found) (save-excursion @@ -705,7 +706,8 @@ outline-on-heading-p "Return t if point is on a (visible) heading line. If INVISIBLE-OK is non-nil, an invisible heading line is ok too." (save-excursion - (beginning-of-line) + (let ((inhibit-field-text-motion t)) + (beginning-of-line)) (and (bolp) (or invisible-ok (not (outline-invisible-p))) (if outline-search-function (funcall outline-search-function nil nil nil t) @@ -941,9 +943,10 @@ outline-next-visible-heading A heading line is one that starts with a `*' (or that `outline-regexp' matches)." (interactive "p") - (if (< arg 0) - (beginning-of-line) - (end-of-line)) + (let ((inhibit-field-text-motion t)) + (if (< arg 0) + (beginning-of-line) + (end-of-line))) (let ((regexp (unless outline-search-function (concat "^\\(?:" outline-regexp "\\)"))) found-heading-p) @@ -963,7 +966,9 @@ outline-next-visible-heading (re-search-forward regexp nil 'move))) (outline-invisible-p (match-beginning 0)))) (setq arg (1- arg))) - (if found-heading-p (beginning-of-line)))) + (if found-heading-p + (let ((inhibit-field-text-motion t)) + (beginning-of-line))))) (defun outline-previous-visible-heading (arg) "Move to the previous heading line. @@ -980,7 +985,8 @@ outline-mark-subtree (let ((beg)) (if (outline-on-heading-p) ;; we are already looking at a heading - (beginning-of-line) + (let ((inhibit-field-text-motion t)) + (beginning-of-line)) ;; else go back to previous heading (outline-previous-visible-heading 1)) (setq beg (point)) @@ -1183,7 +1189,8 @@ outline-hide-sublevels (cond (current-prefix-arg (prefix-numeric-value current-prefix-arg)) ((save-excursion - (beginning-of-line) + (let ((inhibit-field-text-motion t)) + (beginning-of-line)) (if outline-search-function (funcall outline-search-function nil nil nil t) (looking-at outline-regexp))) @@ -1834,13 +1841,15 @@ outline--create-button-icons (defun outline--insert-button (type) (with-silent-modifications (save-excursion - (beginning-of-line) + (let ((inhibit-field-text-motion t)) + (beginning-of-line)) (let ((icon (nth (if (eq type 'close) 1 0) outline--button-icons)) (o (seq-find (lambda (o) (overlay-get o 'outline-button)) (overlays-at (point))))) (unless o (when (eq outline-minor-mode-use-buttons 'insert) - (let ((inhibit-read-only t)) + (let ((inhibit-read-only t) + (inhibit-field-text-motion t)) (insert (apply #'propertize " " (text-properties-at (point)))) (beginning-of-line))) (setq o (make-overlay (point) (1+ (point)))) @@ -1866,7 +1875,8 @@ outline--fix-up-all-buttons (when from (save-excursion (goto-char from) - (setq from (line-beginning-position)))) + (let ((inhibit-field-text-motion t)) + (setq from (line-beginning-position))))) (outline-map-region (lambda () (let ((close-p (save-excursion -- 2.25.1