Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
2026-05-16 Bob Weiner <rsw@gnu.org>

* 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
Expand Down
75 changes: 54 additions & 21 deletions hui.el
Original file line number Diff line number Diff line change
Expand Up @@ -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:49:30 by Bob Weiner
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
;;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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))
Expand All @@ -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)
Expand All @@ -203,18 +215,19 @@ 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.
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].
Expand All @@ -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))
Expand All @@ -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))
Expand All @@ -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
Expand Down Expand Up @@ -1522,6 +1537,24 @@ 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
(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))))

;;; ************************************************************************
;;; Private functions - used only within Hyperbole
Expand Down
15 changes: 9 additions & 6 deletions kotl/kotl-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -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
;;
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
19 changes: 10 additions & 9 deletions man/hyperbole.texi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -171,7 +171,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</P>

<PRE>
Edition 9.0.2pre
Printed March 29, 2026.
Printed May 16, 2026.

Published by the Free Software Foundation, Inc.
Author: Bob Weiner
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down