From 9e034d3921653cef9211e2be6f37cb5aa2bf4db2 Mon Sep 17 00:00:00 2001 From: bw Date: Sat, 16 May 2026 17:24:56 -0400 Subject: [PATCH 1/2] hui:copy-message-length - Add this defcustom to limit length of msg If `hui:copy-message-length' is set to 0, disables messages when {C-w} or {M-w} is called interactively and Hyperbole is active. Do not copy or kill a 'thing' if point is on a whitespace character. Update doc of hui and kotl-mode copy and kill commands to reflect operation on any kind of 'thing', not just delimited things. hui:indicate-copied-region - Add to centralize display of copied text. --- ChangeLog | 17 +++++++++++ hui.el | 72 ++++++++++++++++++++++++++++++++-------------- kotl/kotl-mode.el | 15 ++++++---- man/hyperbole.texi | 19 ++++++------ 4 files changed, 87 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb89895f..85c48f2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2026-05-16 Bob Weiner +* man/hyperbole.texi (Default Hyperbole Bindings): Update doc for {M-w} to copy + things, not just delimited things. + (Koutliner Keys): Update doc for {C-w} to kill/copy things, + not just delimited things. + +* hui.el (hui:copy-to-register, hui:kill-ring-save): Change "Saved selectable + thing" to "Copied selectable thing" to better match regurlar emacs. Also + call 'query-replace-descr' to prevent newline display within 'thing'. + (hui:indicate-copied-region): Add to centralize display of copied + text and call from the above two functions. + (hui:copy-message-length): Add this defcustom with default of 40 + and use in the prior function. + (hui:kill-ring-save, hui:copy-to-register, hui:kill-region): Don't + copy a 'thing' if point is on whitespace. Update doc strings. + kotl/kotl-mode.el (kotl-mode:kill-region): Don't kill a 'thing' if point + is on whitespace. + * kotl/kotl-mode.el (kotl-mode:split-cell): Fix to ensure point within a valid cell position and fix to not modify label-separator and leave a stray character in the original cell when splitting at the first diff --git a/hui.el b/hui.el index 7b34b23d..66122505 100644 --- a/hui.el +++ b/hui.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 19-Sep-91 at 21:42:03 -;; Last-Mod: 15-Mar-26 at 17:46:14 by Bob Weiner +;; Last-Mod: 16-May-26 at 17:37:57 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -62,6 +62,10 @@ ;;; Public variables ;;; ************************************************************************ +(defcustom hui:copy-message-length 40 + "Maximum character length of the message displayed after copying text. + Set to 0 for no message.") + (defcustom hui:ebut-prompt-for-action nil "Non-nil prompts for a button-specific action on explicit button creation." :type 'boolean @@ -108,9 +112,14 @@ copying some text between START and END, but we're copying the region. Interactively, reads the register using `register-read-with-preview'. -If called interactively, `transient-mark-mode' is non-nil, and -there is no active region, copy any delimited selectable thing at -point; see `hui:delimited-selectable-thing'." +If called interactively, `transient-mark-mode' is non-nil, there is no +active region, and point is not on a whitespace character, then copy the +selectable thing at point including any delimiters; see +`hui:selectable-thing-and-bounds'. + +Interactively, display a message with `hui:copy-message-length' characters +of the text copied unless that variable is set to 0, in which case no +message is shown." (interactive (list (register-read-with-preview "Copy to register: ") (when mark-active (region-beginning)) (when mark-active (region-end)) @@ -133,6 +142,7 @@ point; see `hui:delimited-selectable-thing'." ((and interactive-flag transient-mark-mode (not (use-region-p)) + (not (looking-at "\\s-")) (prog1 (setq thing-and-bounds (hui:selectable-thing-and-bounds) thing (nth 1 thing-and-bounds) @@ -151,10 +161,7 @@ point; see `hui:delimited-selectable-thing'." (setq deactivate-mark t) (cond (delete-flag) (interactive-flag - (cond (thing - (message "Saved selectable thing: %s" thing)) - ((mark t) - (indicate-copied-region)))))))) + (hui:indicate-copied-region thing)))))) ;; In "hyperbole.el", use this to override the {C-w} command from ;; either "completion.el" or "simple.el" when hyperbole-mode is active @@ -174,7 +181,11 @@ Any command that calls this function is a \"kill command\". If the previous command was also a kill command, the text killed this time appends to the text killed last time to make one entry in the kill ring. -Patched to remove the most recent completion." +Patched to remove the most recent completion. + +When `transient-mark-mode' is non-nil, there is no active region, and point +is not on a whitespace character, then kill the selectable thing at point +including any delimiters; see `hui:selectable-thing-and-bounds'." ;; Pass mark first, then point, because the order matters when ;; calling `kill-append'. (interactive (list (when mark-active (mark)) @@ -191,7 +202,8 @@ Patched to remove the most recent completion." ;; if in one of `hui-select-ignore-quoted-sexp-modes'. ((let* ((major-mode 'fundamental-mode) thing-and-bounds) - (when (setq thing-and-bounds (hui:selectable-thing-and-bounds)) + (when (and (not (looking-at "\\s-")) + (setq thing-and-bounds (hui:selectable-thing-and-bounds))) (setq beg (nth 2 thing-and-bounds) end (nth 3 thing-and-bounds) region nil) @@ -203,8 +215,8 @@ Patched to remove the most recent completion." (hui:kill-region-internal beg end region))) ;; In "hyperbole.el", use this to override the {M-w} command from -;; "simple.el" when hyperbole-mode is active to allow copying kcell -;; references, active regions and delimited areas (like sexpressions). +;; "simple.el" when `hyperbole-mode' is active to allow copying kcell +;; references, active regions and things (like sexpressions). ;;;###autoload (defun hui:kill-ring-save (beg end &optional region) "Save the active region or thing at point as if killed, but don't kill it. @@ -212,9 +224,10 @@ In Transient Mark mode, deactivate the mark. If `interprogram-cut-function' is non-nil, also save the text for a window system cut and paste. -If called interactively, `transient-mark-mode' is non-nil, and -there is no active region, copy any delimited selectable thing at -point; see `hui:delimited-selectable-thing'. +If called interactively, `transient-mark-mode' is non-nil, there is no +active region, and point is not on a whitespace character, then copy the +selectable thing at point including any delimiters; see +`hui:selectable-thing-and-bounds'. If you want to append the killed region to the last killed text, use \\[append-next-kill] before \\[kill-ring-save]. @@ -229,7 +242,11 @@ non-nil, in which case ignore BEG and END, and save the current region instead. This command is similar to `copy-region-as-kill', except that it gives -visual feedback indicating the extent of the region being copied." +visual feedback indicating the extent of the region being copied. + +Interactively, display a message with `hui:copy-message-length' characters +of the text copied unless that variable is set to 0, in which case no +message is shown." ;; Pass mark first, then point, because the order matters when ;; calling `kill-append'. (interactive (list (when mark-active (mark)) @@ -254,7 +271,8 @@ visual feedback indicating the extent of the region being copied." ;; suppressing use of `hui-select-syntax-table' ;; if in one of `hui-select-ignore-quoted-sexp-modes'. (let ((major-mode 'fundamental-mode)) - (setq thing (nth 1 (hui:selectable-thing-and-bounds)))) + (unless (looking-at "\\s-") + (setq thing (nth 1 (hui:selectable-thing-and-bounds))))) (if (stringp thing) (progn (kill-new thing) (setq deactivate-mark t)) @@ -267,10 +285,7 @@ visual feedback indicating the extent of the region being copied." ;; This use of `called-interactively-p' is correct because the ;; code it controls just gives the user visual feedback. (when (called-interactively-p 'interactive) - (cond (thing - (message "Saved selectable thing: %s" thing)) - ((mark t) - (indicate-copied-region)))))) + (hui:indicate-copied-region thing)))) ;;; ************************************************************************ ;;; Public functions @@ -1522,6 +1537,21 @@ runs this command." (hui:ibut-message edit-flag)) edit-flag))) +(defun hui:indicate-copied-region (thing &optional message-len) + "Indicate that string THING or the region text has been copied. +Should be used when a command is called interactively." + (unless message-len + (setq message-len hui:copy-message-length)) + (cond ((zerop message-len) + nil) + (thing + ;; Don't say "killed" or "saved"; that is misleading. + (message "Copied selectable thing: %s" + ;; Don't show newlines literally + (query-replace-descr + (seq-take thing message-len)))) + ((mark t) + (indicate-copied-region message-len)))) ;;; ************************************************************************ ;;; Private functions - used only within Hyperbole diff --git a/kotl/kotl-mode.el b/kotl/kotl-mode.el index 8c363eb6..f29c1636 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: 16-May-26 at 11:55:50 by Bob Weiner +;; Last-Mod: 16-May-26 at 17:18:12 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -791,12 +791,14 @@ With optional COPY-FLAG equal to t, copy region to kill ring but does not kill it. With COPY-FLAG any other non-nil value, return region as a string without affecting kill ring. -If called interactively, `transient-mark-mode' is non-nil, and -there is no active region, copy any delimited selectable thing at -point; see `hui:delimited-selectable-thing'. +If called interactively, `transient-mark-mode' is non-nil, there is no +active region, and point is not on a whitespace character, then kill/copy +the selectable thing at point including any delimiters; see +`hui:selectable-thing-and-bounds'. -If the buffer is read-only and COPY-FLAG is nil, the region will not be deleted -but it will be copied to the kill ring and then an error will be signaled. +If the buffer is read-only and COPY-FLAG is nil, the region will not be +deleted but it will be copied to the kill ring and then an error will be +signaled. If a completion is active, this aborts the completion only." (interactive @@ -819,6 +821,7 @@ If a completion is active, this aborts the completion only." ((and (memq this-command kill-commands) transient-mark-mode (not (use-region-p)) + (not (looking-at "\\s-")) (setq thing-and-bounds (hui:selectable-thing-and-bounds) thing (nth 1 thing-and-bounds) start (nth 2 thing-and-bounds) diff --git a/man/hyperbole.texi b/man/hyperbole.texi index 666392c8..425348c1 100644 --- a/man/hyperbole.texi +++ b/man/hyperbole.texi @@ -7,7 +7,7 @@ @c Author: Bob Weiner @c @c Orig-Date: 6-Nov-91 at 11:18:03 -@c Last-Mod: 29-Mar-26 at 23:39:42 by Bob Weiner +@c Last-Mod: 16-May-26 at 17:20:08 by Bob Weiner @c %**start of header (This is for running Texinfo on a region.) @setfilename hyperbole.info @@ -30,8 +30,8 @@ @set txicodequoteundirected @set txicodequotebacktick -@set UPDATED March 29, 2026 -@set UPDATED-MONTH March 2026 +@set UPDATED May 16, 2026 +@set UPDATED-MONTH May 2026 @set EDITION 9.0.2pre @set VERSION 9.0.2pre @@ -171,7 +171,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 Edition 9.0.2pre
-Printed March 29, 2026.
+Printed May 16, 2026.
 
   Published by the Free Software Foundation, Inc.
   Author:    Bob Weiner
@@ -213,7 +213,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 @example
 Edition 9.0.2pre
-March 29, 2026 @c AUTO-REPLACE-ON-SAVE
+May 16, 2026 @c AUTO-REPLACE-ON-SAVE
 
 
   Published by the Free Software Foundation, Inc.
@@ -9506,7 +9506,7 @@ region only when it is active/highlighted.  When there is no active region,
 @item in a Koutline klink, copies the klink;
 @item in a Koutline cell, outside any klink, copies a klink reference to the current cell;
 @item on a Hyperbole button, copies the text of the button excluding delimiters;
-@item at the start of a paired delimiter, copy the text including the delimiters.
+@item on a thing (not at whitespace), copy the text of the thing including any delimiters.
 @end enumerate
 
 @cindex key binding, C-x r s
@@ -9935,9 +9935,10 @@ With optional COPY-P equal to t, copy region to kill ring but don't
 kill it.  With COPY-P any other non-nil value, return region as a
 string without affecting the kill ring.
 
-If called interactively and there is no active region, copy any
-delimited selectable thing at point; see the documentation for
-@code{hui:delimited-selectable-thing}.
+If called interactively, @code{transient-mark-mode} is non-nil,
+there is no active region, and point is not on a whitespace character,
+then kill/copy the selectable thing at point including any delimiters;
+see @code{hui:selectable-thing-and-bounds}.
 
 If the buffer is read-only and COPY-P is nil, the region will not be
 deleted but it will be copied to the kill ring and then an error will be

From aff25ef74a013ca2aa6704f7489c18b402b6c9da Mon Sep 17 00:00:00 2001
From: bw 
Date: Sat, 16 May 2026 17:50:41 -0400
Subject: [PATCH 2/2] hui:indicate-copied-region - Double quote 'thing' and add
 ellipses

---
 hui.el | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hui.el b/hui.el
index 66122505..0d2e7f16 100644
--- a/hui.el
+++ b/hui.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    19-Sep-91 at 21:42:03
-;; Last-Mod:     16-May-26 at 17:37:57 by Bob Weiner
+;; Last-Mod:     16-May-26 at 17:49:30 by Bob Weiner
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -1545,11 +1545,14 @@ Should be used when a command is called interactively."
   (cond ((zerop message-len)
          nil)
         (thing
-         ;; Don't say "killed" or "saved"; that is misleading.
-         (message "Copied selectable thing: %s"
-	          ;; Don't show newlines literally
-	          (query-replace-descr
-                   (seq-take thing message-len))))
+         (let ((thing-excerpt (seq-take thing message-len)))
+           ;; Don't say "killed" or "saved"; that is misleading.
+           (message "Copied selectable thing: \"%s%s\""
+	            ;; Don't show newlines literally
+	            (query-replace-descr thing-excerpt)
+                    (if (< (length thing-excerpt) (length thing))
+                        "..."
+                      ""))))
 	((mark t)
 	 (indicate-copied-region message-len))))