branch: externals/hyperbole
commit 68564a0f0dad26e711f9d3530a317dc37e79690a
Author: Bob Weiner <[email protected]>
Commit: Bob Weiner <[email protected]>
Enable HyRolo's extended reveal-mode used in *HyRolo* buffer
hypb:add-to-invisibility-spec: Add and use wherever
'add-to-invisbility-spec' was.
hyrolo.el (hyrolo-file-suffix-regexp): Allow for suffix .outl
to invoke outline mode in addition to .otl.
---
ChangeLog | 13 +++
hload-path.el | 4 +-
hypb.el | 19 +++-
hyrolo.el | 261 +++++++++++++++++++++++++++++++++++++++---------------
kotl/kotl-mode.el | 5 +-
5 files changed, 224 insertions(+), 78 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0ca9e05fde..d7b1509a74 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
+2024-01-23 Bob Weiner <[email protected]>
+
+* hyrolo.el (hyrolo-reveal-ignore-this-command,
hyrolo-reveal-open-new-overlays,
+ hyrolo-reveal-close-old-overlays, reveal-post-command):
+ Enable Hyperbole extended version of 'reveal-mode' that supports
'org-fold'.
+
2024-01-21 Bob Weiner <[email protected]>
+* hypb.el (hypb:add-to-invisibility-spec): Add and use wherever
+ 'add-to-invisbility-spec' was.
+
+* hload-path.el (auto-mode-alist):
+ hyrolo.el (hyrolo-file-suffix-regexp): Allow for suffix .outl to invoke
outline
+ mode in addition to .otl.
+
* hmouse-tag.el (smart-emacs-lisp-mode-p ,smart-lisp-mode-p): Change to use
'derived-mode-p' rather than checking for 'major-mode' matches directly.
(smart-emacs-lisp-mode-p): Add optional 'skip-identifier-flag'.
diff --git a/hload-path.el b/hload-path.el
index b306fc2950..98a5d645a9 100644
--- a/hload-path.el
+++ b/hload-path.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 29-Jun-16 at 14:39:33
-;; Last-Mod: 24-Dec-23 at 00:41:54 by Bob Weiner
+;; Last-Mod: 21-Jan-24 at 23:38:30 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -69,7 +69,7 @@ directory separator character.")
;;; Emacs Outline settings for .otl files
;;; ************************************************************************
-(add-to-list 'auto-mode-alist '("\\.otl\\'" . outline-mode))
+(add-to-list 'auto-mode-alist '("\\.ou?tl\\'" . outline-mode))
;;; ************************************************************************
;;; Hyperbole test importation settings
diff --git a/hypb.el b/hypb.el
index 6d97427a1a..f8eea040a9 100644
--- a/hypb.el
+++ b/hypb.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 6-Oct-91 at 03:42:38
-;; Last-Mod: 20-Jan-24 at 20:22:08 by Mats Lidell
+;; Last-Mod: 21-Jan-24 at 23:24:46 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -120,6 +120,23 @@ It must end with a space."
;;; Public functions
;;; ************************************************************************
+;; Adapted from "subr.el" but doesn't add if ELEMENT already exists
+(defun hypb:add-to-invisibility-spec (element)
+ "Add ELEMENT to `buffer-invisibility-spec'.
+See documentation for `buffer-invisibility-spec' for the kind of elements
+that can be added.
+
+If `buffer-invisibility-spec' isn't a list before calling this
+function, `buffer-invisibility-spec' will afterwards be a list
+with the value `(t ELEMENT)'. This means that if text exists
+that invisibility values that aren't either `t' or ELEMENT, that
+text will become visible."
+ (if (eq buffer-invisibility-spec t)
+ (setq buffer-invisibility-spec (list t)))
+ (unless (member element buffer-invisibility-spec)
+ (setq buffer-invisibility-spec
+ (cons element buffer-invisibility-spec))))
+
;;;###autoload
(defun hypb:activate-interaction-log-mode ()
"Configure and enable the interaction-log package for use with Hyperbole.
diff --git a/hyrolo.el b/hyrolo.el
index c054a11e35..53ac4b9d3d 100644
--- a/hyrolo.el
+++ b/hyrolo.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 7-Jun-89 at 22:08:29
-;; Last-Mod: 21-Jan-24 at 10:54:37 by Bob Weiner
+;; Last-Mod: 23-Jan-24 at 18:56:27 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -32,7 +32,7 @@
(require 'hversion)
(require 'hmail)
(require 'hsys-org) ;; For `hsys-org-cycle-bob-file-list'
-(require 'hypb) ;; For `hypb:mail-address-regexp'
+(require 'hypb) ;; For `hypb:mail-address-regexp' and
`hypb:add-to-invisibility-spec'
(require 'outline)
(require 'package)
(require 'reveal)
@@ -264,7 +264,7 @@ The match is after matching to
`hyrolo-hdr-and-entry-regexp'.")
(defconst hyrolo-markdown-suffix-regexp
"md\\|markdown\\|mkd\\|mdown\\|mkdn\\|mdwn"
"Regexp matching Markdown file suffixes.")
-(defcustom hyrolo-file-suffix-regexp (concat "\\.\\(kotl?\\|org\\|otl\\|"
+(defcustom hyrolo-file-suffix-regexp (concat "\\.\\(kotl?\\|org\\|ou?tl\\|"
hyrolo-markdown-suffix-regexp
"\\)$")
"File suffix regexp used to select files to search with HyRolo."
:type 'string
@@ -942,6 +942,7 @@ of matches for the file of matches at point."
(<= levels-to-show 0))
(not (integerp levels-to-show))))
(setq levels-to-show 100))
+ (setq hyrolo-this-command-ignore-reveal t)
(hyrolo-show-levels levels-to-show))
(defun hyrolo-previous-match ()
@@ -1143,6 +1144,7 @@ Useful when bound to a mouse key."
Top-level matches are those with the lowest outline level among the
matched entries."
(interactive)
+ (setq-local hyrolo-reveal-ignore-this-command t)
(hyrolo-show-levels 1))
(defun hyrolo-verify ()
@@ -1458,7 +1460,7 @@ otherwise just use the cdr of the item."
(defun hyrolo-helm-org-rifle (&optional context-only-flag)
"Search with helm and interactively show all matches from `hyrolo-file-list'.
Prompt for the search pattern.
-Search readable .org and .otl files only. With optional prefix
+Search readable .org, .otl and .outl files only. With optional prefix
arg CONTEXT-ONLY-FLAG, show one extra line only of context around
a matching line, rather than entire entries."
(interactive "P")
@@ -1467,7 +1469,7 @@ a matching line, rather than entire entries."
(require 'helm-org-rifle)
(let ((files (seq-filter (lambda (f)
(and (stringp f)
- (string-match "\\.\\(org\\|otl\\)$" f)
+ (string-match "\\.\\(org\\|ou?tl\\)$" f)
(file-readable-p f)))
(hyrolo-get-file-list)))
;; Next 2 local settings used by helm-org-rifle-files call below
@@ -1502,11 +1504,11 @@ entries."
;;;###autoload
(defun hyrolo-helm-org-rifle-directories (&optional context-only-flag &rest
dirs)
"Interactively search over Emacs outline format files in rest of DIRS.
-Search readable .org and .otl files only. With optional prefix
+Search readable .org, .otl and .outl files only. With optional prefix
arg CONTEXT-ONLY-FLAG, show one extra line only of context around
a matching line, rather than entire entries."
(interactive "P")
- (let ((hyrolo-file-list (hypb:filter-directories "\\.\\(org\\|otl\\)$"
dirs)))
+ (let ((hyrolo-file-list (hypb:filter-directories "\\.\\(org\\|ou?tl\\)$"
dirs)))
(hyrolo-helm-org-rifle context-only-flag)))
;;;###autoload
@@ -1773,15 +1775,17 @@ Return number of matching entries found."
(hyrolo-add-match pattern entry-start
(point)))))))
num-found))
(when (and (> num-found 0) (not count-only))
- ;; Require a final blank line so that `outline-hide-sublevels'
won't hide
- ;; it and combine with any next file header.
- (when (/= (char-after (1- (point-max))) ?\n)
- (save-excursion
- (goto-char (point-max))
- (insert "\n")))
- (hyrolo--cache-major-mode (current-buffer)))
+ (with-current-buffer hyrolo-display-buffer
+ ;; Require a final blank line in `hyrolo-display-buffer'
+ ;; so that `outline-hide-sublevels' won't hide it and
+ ;; combine with any next file header.
+ (when (/= (char-after (1- (point-max))) ?\n)
+ (save-excursion
+ (goto-char (point-max))
+ (newline))))
+ (hyrolo--cache-major-mode actual-buf))
(when (< stuck-negative-point 0)
- (pop-to-buffer (current-buffer))
+ (pop-to-buffer actual-buf)
(goto-char (- stuck-negative-point))
(error "(hyrolo-grep-file): Stuck looping in buffer \"%s\" at
position %d"
(buffer-name) (point)))
@@ -1872,7 +1876,7 @@ See the command `outline-mode' for more information on
this mode."
nil t)
(setq-local line-move-ignore-invisible t)
;; Cause use of ellipses for invisible text.
- (add-to-invisibility-spec '(outline . t)))
+ (hypb:add-to-invisibility-spec '(outline . t)))
;; disable minor mode
(when (and (boundp 'outline-minor-mode-cycle) outline-minor-mode-cycle)
(remove-overlays nil nil 'outline-overlay t))
@@ -1906,26 +1910,22 @@ Calls the functions given by `hyrolo-mode-hook'.
;; decrements it by one. -- rsw, 2023-11-17
outline-level #'hyrolo-outline-level)
+ ;; Can't cycle because {TAB} moves to next match
(when (boundp 'outline-minor-mode-cycle)
- (setq-local
- ;; Can't cycle because {TAB} moves to next match
- outline-minor-mode-cycle nil))
+ (setq-local outline-minor-mode-cycle nil))
+ ;; For speed reasons, don't want to ever font-lock in this mode
(when (boundp 'outline-minor-mode-highlight)
- (setq-local
- ;; For speed reasons, don't want to ever font-lock
- ;; in this mode
- outline-minor-mode-highlight nil)))
+ (setq-local outline-minor-mode-highlight nil)))
(use-local-map hyrolo-mode-map)
(set-syntax-table hyrolo-mode-syntax-table)
(hyrolo-outline-minor-mode 1) ;; no keymap
- ;; !! TODO: Disable this until can get it working right with the
- ;; enabling of outline-minor-mode when switch major modes in *HyRolo*
- ;; typically using hyrolo-funcall-match or hyrolo-map-matches.
- ;; (unless (eq major-mode 'hyrolo-mode)
- ;; (reveal-mode 1)) ;; Expose hidden text as move into it.
+ (setq-local reveal-around-mark nil)
+ (unless (or (eq major-mode 'hyrolo-mode)
+ hyrolo-reveal-ignore-this-command)
+ (reveal-mode 1)) ;; Expose hidden text as move into it.
;; Do this after reveal-mode is enabled.
(setq major-mode 'hyrolo-mode
@@ -2203,8 +2203,13 @@ nil for WHICH, or do not pass any argument)."
(if current-prefix-arg nil 'subtree)))))
(hyrolo-funcall-match (lambda () (outline-promote which)) t))
-;;; Don't need to override but alias them for completeness
-(defalias 'hyrolo-outline-show-all 'outline-show-all)
+(defun hyrolo-outline-show-all ()
+ "Show all of the text in the HyRolo display buffer."
+ (interactive)
+ (setq-local hyrolo-reveal-ignore-this-command t)
+ (outline-show-all))
+
+;;; Don't need to override but alias this for completeness
(defalias 'hyrolo-outline-show-branches 'outline-show-branches)
(defun hyrolo-outline-show-children (&optional level)
@@ -2668,18 +2673,22 @@ Any non-nil value returned is a cons of (<entry-name> .
<entry-source>)."
"Basic Org mode for use in HyRolo display match searches."
(require 'org)
;; Don't actually derive from org-mode to avoid its costly setup but
- ;; set its parent mode property to org-mode so can `derived-mode-p'
+ ;; set its parent mode property to org-mode so `derived-mode-p'
;; checks will pass.
(put 'hyrolo-org-mode 'derived-mode-parent 'org-mode)
+ (font-lock-mode -1) ;; Never font-lock in this mode to keep it fast
+
(when (featurep 'org-fold) ;; newer Org versions
+ (setq org-fold-core-style 'overlays) ;; Make compatible with reveal minor
mode
(when (and org-link-descriptive
(eq org-fold-core-style 'overlays))
- (add-to-invisibility-spec '(org-link)))
+ (hypb:add-to-invisibility-spec '(org-link)))
(org-fold-initialize (or (and (stringp org-ellipsis) (not (equal ""
org-ellipsis)) org-ellipsis)
"..."))
(make-local-variable 'org-link-descriptive)
- (when (eq org-fold-core-style 'overlays) (add-to-invisibility-spec
'(org-hide-block . t)))
+ (when (eq org-fold-core-style 'overlays)
+ (hypb:add-to-invisibility-spec '(org-hide-block . t)))
(if org-link-descriptive
(org-fold-core-set-folding-spec-property (car
org-link--link-folding-spec) :visible nil)
(org-fold-core-set-folding-spec-property (car
org-link--link-folding-spec) :visible t)))
@@ -2693,13 +2702,14 @@ Any non-nil value returned is a cons of (<entry-name> .
<entry-source>)."
outline-regexp (concat hyrolo-hdr-prefix-regexp "^\\(\\*+\\)\\(
\\)")
outline-level #'hyrolo-org-outline-level)
(use-local-map org-mode-map)
- (font-lock-mode -1) ;; Never font-lock in this mode to keep it fast
;; Modify a few syntax entries
(modify-syntax-entry ?\" "\"")
(modify-syntax-entry ?\\ "_")
(modify-syntax-entry ?~ "_")
(modify-syntax-entry ?< "(>")
- (modify-syntax-entry ?> ")<"))
+ (modify-syntax-entry ?> ")<")
+
+ (reveal-mode 1))
(defun hyrolo-org-outline-level ()
"Compute the outline level of the heading at point.
@@ -2982,7 +2992,10 @@ proper major mode."
(hyrolo-back-to-visible-point)
;; This pause forces a window redisplay that maximizes the
;; entries displayed for any final location of point.
- (sit-for 0.0001)))))
+ ;; Comment it out for now and see how well movement
+ ;; cmds work.
+ ;; (sit-for 0.0001)
+ ))))
(let ((outline-regexp hyrolo-hdr-and-entry-regexp))
(funcall func)))))
@@ -3125,49 +3138,153 @@ Add `hyrolo-hdr-regexp' to
`hyrolo-hdr-and-entry-regexp' and `outline-regexp'."
(substitute-key-definition otl-cmd hyrolo-cmd hyrolo-mode-map)))
outline-mode-prefix-map)))
-;;; Integrate reveal-mode with HyRolo.
-;;; NOTE: !! TODO: This does not yet work so is not enabled in `hyrolo-mode'
yet,
-;;; thus the `reveal-post-command' below is not yet used.
+;;; ************************************************************************
+;;; hyrolo-reveal - Extend reveal-mode to support Org mode org-fold
+;;; ************************************************************************
+
+(defvar hyrolo-reveal-ignore-this-command nil
+ "Set this non-nil in any command that should ignore `hyrolo-reveal-mode'.")
+
+(defun hyrolo-reveal-open-new-overlays (old-ols)
+ (let ((repeat t))
+ (while repeat
+ (setq repeat nil)
+ (dolist (ol (nconc (when (and reveal-around-mark mark-active)
+ (overlays-at (mark)))
+ (overlays-at (point))))
+ (setq old-ols (delq ol old-ols))
+ (when (overlay-start ol) ;Check it's still live.
+ ;; We either have an invisible overlay, or a display
+ ;; overlay. Always reveal invisible text, but only reveal
+ ;; display properties if `reveal-toggle-invisible' is
+ ;; present.
+ (let ((inv (overlay-get ol (if (derived-mode-p 'org-mode)
'org-invisible 'invisible)))
+ (disp (and (overlay-get ol 'display)
+ (overlay-get ol 'reveal-toggle-invisible)))
+ open)
+ (when (and (or (and inv
+ ;; There's an `invisible' property.
+ ;; Make sure it's actually invisible,
+ ;; and ellipsized.
+ (and (consp buffer-invisibility-spec)
+ (cdr (assq inv
buffer-invisibility-spec))))
+ disp)
+ (or (setq open
+ (or (overlay-get ol 'reveal-toggle-invisible)
+ (and (symbolp inv)
+ (get inv 'reveal-toggle-invisible))
+ (overlay-get
+ ol 'isearch-open-invisible-temporary)))
+ (overlay-get ol 'isearch-open-invisible)
+ (and (consp buffer-invisibility-spec)
+ (cdr (assq inv buffer-invisibility-spec)))))
+ (when inv
+ (overlay-put ol 'reveal-invisible inv))
+ (push (cons (selected-window) ol) reveal-open-spots)
+ (if (null open)
+ (if (derived-mode-p 'org-mode)
+ (org-fold-region (overlay-start ol) (overlay-end ol) nil
'headline)
+ (overlay-put ol 'invisible nil))
+ ;; Use the provided opening function and repeat (since the
+ ;; opening function might have hidden a subpart around point
+ ;; or moved/killed some of the overlays).
+ (setq repeat t)
+ (condition-case err
+ (funcall open ol nil)
+ (error (message "!!Reveal-show (funcall %s %s nil): %s !!"
+ open ol err)
+ ;; Let's default to a meaningful behavior to avoid
+ ;; getting stuck in an infinite loop.
+ (setq repeat nil)
+ (if (derived-mode-p 'org-mode)
+ (org-fold-region (overlay-start ol) (overlay-end
ol) nil 'headline)
+ (overlay-put ol 'invisible nil)))))))))))
+ old-ols)
+
+(defun hyrolo-reveal-close-old-overlays (old-ols)
+ (if (or track-mouse ;Don't close in the middle of a click.
+ (not (eq reveal-last-tick
+ (setq reveal-last-tick (buffer-modified-tick)))))
+ ;; The buffer was modified since last command: let's refrain from
+ ;; closing any overlay because it tends to behave poorly when
+ ;; inserting text at the end of an overlay (basically the overlay
+ ;; should be rear-advance when it's open, but things like
+ ;; outline-minor-mode make it non-rear-advance because it's
+ ;; a better choice when it's closed).
+ nil
+ ;; The last command was only a point motion or some such
+ ;; non-buffer-modifying command. Let's close whatever can be closed.
+ (dolist (ol old-ols)
+ (if (and (overlay-start ol) ;Check it's still live.
+ (>= (point) (save-excursion
+ (goto-char (overlay-start ol))
+ (line-beginning-position 1)))
+ (<= (point) (save-excursion
+ (goto-char (overlay-end ol))
+ (line-beginning-position 2)))
+ ;; If the application has moved the overlay to some other
+ ;; buffer, we'd better reset the buffer to its
+ ;; original state.
+ (eq (current-buffer) (overlay-buffer ol)))
+ ;; Still near the overlay: keep it open.
+ nil
+ ;; Really close it.
+ (let* ((inv (overlay-get ol 'reveal-invisible))
+ (open (or (overlay-get ol 'reveal-toggle-invisible)
+ (get inv 'reveal-toggle-invisible)
+ (overlay-get ol 'isearch-open-invisible-temporary))))
+ (if (and (overlay-start ol) ;Check it's still live.
+ open)
+ (condition-case err
+ (funcall open ol t)
+ (error (message "!!Reveal-hide (funcall %s %s t): %s !!"
+ open ol err)))
+ (if (derived-mode-p 'org-mode)
+ (org-fold-region (overlay-start ol) (overlay-end ol) nil
'headline)
+ (overlay-put ol 'invisible nil)))
+ ;; Remove the overlay from the list of open spots.
+ (overlay-put ol 'reveal-invisible nil)
+ (setq reveal-open-spots
+ (delq (rassoc ol reveal-open-spots)
+ reveal-open-spots)))))))
;; Note that `outline-reveal-toggle-invisible' is the function
;; stored in the `outline' `reveal-toggle-invisible' property. It
-;; is called from `reveal-open-new-overlays' and -
-;; `reveal-close-old-overlays' which are called from within
+;; is called from `hyrolo-reveal-open-new-overlays' and
+;; `hyrolo-reveal-close-old-overlays' which are called from within
;; `reveal-post-command' on `post-command-hook'. Below we update
;; `reveal-post-command' to work with HyRolo.
(defun reveal-post-command ()
- ;; Refresh the spots that might have changed.
- ;; `Refreshing' here means to try and re-hide the corresponding text.
- ;; We don't refresh everything correctly:
- ;; - we only refresh spots in the current window.
- ;; FIXME: do we actually know that (current-buffer) = (window-buffer) ?
- (with-local-quit
- (with-demoted-errors "Reveal: %s"
- (let ((old-ols
- (delq nil
- (mapcar
- (lambda (x)
- ;; We refresh any spot in the current window as well
- ;; as any spots associated with a dead window or
- ;; a window which does not show this buffer any more.
- (cond
- ((eq (car x) (selected-window)) (cdr x))
- ((not (and (window-live-p (car x))
- (eq (window-buffer (car x))
- (current-buffer))))
- ;; Adopt this since it's owned by a window that's
- ;; either not live or at least not showing this
- ;; buffer any more.
- (setcar x (selected-window))
- (cdr x))))
- reveal-open-spots))))
- (hyrolo-funcall-match
- (lambda ()
- (setq old-ols (reveal-open-new-overlays old-ols))
- (when reveal-auto-hide
- (reveal-close-old-overlays old-ols)))
- t)))))
+ (if hyrolo-reveal-ignore-this-command
+ (setq hyrolo-reveal-ignore-this-command nil)
+ ;; Refresh the spots that might have changed.
+ ;; `Refreshing' here means to try and re-hide the corresponding text.
+ ;; We don't refresh everything correctly:
+ ;; - we only refresh spots in the current window.
+ ;; FIXME: do we actually know that (current-buffer) = (window-buffer) ?
+ (with-local-quit
+ (with-demoted-errors "Reveal: %s"
+ (let ((old-ols
+ (delq nil
+ (mapcar
+ (lambda (x)
+ ;; We refresh any spot in the current window as well
+ ;; as any spots associated with a dead window or
+ ;; a window which does not show this buffer any more.
+ (cond
+ ((eq (car x) (selected-window)) (cdr x))
+ ((not (and (window-live-p (car x))
+ (eq (window-buffer (car x))
+ (current-buffer))))
+ ;; Adopt this since it's owned by a window that's
+ ;; either not live or at least not showing this
+ ;; buffer any more.
+ (setcar x (selected-window))
+ (cdr x))))
+ reveal-open-spots))))
+ (setq old-ols (hyrolo-reveal-open-new-overlays old-ols))
+ (hyrolo-reveal-close-old-overlays old-ols))))))
;;; ************************************************************************
;;; hyrolo-file-list - initialize cache if this is already set when loading
diff --git a/kotl/kotl-mode.el b/kotl/kotl-mode.el
index 0471c49b0a..a641d9ebd6 100644
--- a/kotl/kotl-mode.el
+++ b/kotl/kotl-mode.el
@@ -3,7 +3,7 @@
;; Author: Bob Weiner
;;
;; Orig-Date: 6/30/93
-;; Last-Mod: 20-Jan-24 at 15:43:01 by Mats Lidell
+;; Last-Mod: 21-Jan-24 at 23:26:00 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
@@ -186,8 +186,7 @@ It provides the following keys:
outline-level #'hyrolo-outline-level
outline-regexp hyrolo-hdr-and-entry-regexp))
;;
- (when (fboundp 'add-to-invisibility-spec)
- (add-to-invisibility-spec '(outline . t)))
+ (hypb:add-to-invisibility-spec '(outline . t))
(setq indent-line-function 'kotl-mode:indent-line
indent-region-function 'kotl-mode:indent-region
outline-isearch-open-invisible-function
'kotl-mode:isearch-open-invisible