From: Stephen Berman via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: 70594@debbugs.gnu.org
Subject: bug#70594: 30.0.50; Error when tabbing with only one active widget
Date: Fri, 26 Apr 2024 14:43:42 +0200 [thread overview]
Message-ID: <87r0esl2f5.fsf@gmx.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 2185 bytes --]
Commit 91333dacfa1, which adds the feature of optionally skipping over
inactive widgets when tabbing (bug#70413), fails to handle buffers that
contain only one active widget; in that case, pressing TAB or S-TAB
raises the error "No buttons or fields found". To reproduce:
0. emacs -Q
1. Load the attached file widget-test.el and then type `M-x
my-widget-test'.
2. In the buffer "*My Widget Test*" repeatedly press TAB and S-TAB and
observe that point moves successively between the active radio
buttons labelled "One" and "Two" and the active push button "Submit",
but skips the inactive push button "Reset", since the user option
widget-skip-inactive is enabled.
3. Now press (via RET or mouse-click) the "Submit" button, which makes
the radio buttons and the "Submit" button inactive and the "Reset"
button active.
4. Pressing TAB once moves point to the "Reset" button, then pressing
TAB again moves point to BOB and raises the error "No buttons or
fields found". Likewise, pressing S-TAB once moves point to "Reset",
then pressing S-TAB again moves to EOB and raises the same error.
The attached patched fixes this bug. In addition, when only one widget
is active and point is on it, since pressing TAB or S-TAB does not move
point, the informational message "Only one tabable widget" is displayed.
The original code in widget-move contained separate loops to handle
forward and backward movement and this involved some code duplication.
The changes to this code to fix the bug would have required further
duplication, so I took the opportunity to parameterize the
directionality, allowing handling both directions in a single loop.
This shortens the code and IMO makes the similarities and differences in
the handling easier to see.
Configured using:
'configure 'CFLAGS=-Og -g3' PKG_CONFIG_PATH=/opt/qt5/lib/pkgconfig'
Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG
RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER
WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB
[-- Attachment #2: widget-test.el --]
[-- Type: application/emacs-lisp, Size: 1044 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: widget-move patch --]
[-- Type: text/x-patch, Size: 2675 bytes --]
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index dc481d4d0a5..407309c3429 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -1263,42 +1263,40 @@ widget-move
ARG may be negative to move backward.
When the second optional argument is non-nil,
nothing is shown in the echo area."
- (let ((wrapped 0)
- (number arg)
- (old (widget-tabable-at)))
- ;; Forward.
- (while (> arg 0)
- (cond ((eobp)
- (goto-char (point-min))
- (setq wrapped (1+ wrapped)))
- (widget-use-overlay-change
- (goto-char (next-overlay-change (point))))
- (t
- (forward-char 1)))
- (and (= wrapped 2)
- (eq arg number)
- (error "No buttons or fields found"))
- (let ((new (widget-tabable-at)))
- (when new
- (unless (eq new old)
- (setq arg (1- arg))
- (setq old new)))))
- ;; Backward.
- (while (< arg 0)
- (cond ((bobp)
- (goto-char (point-max))
- (setq wrapped (1+ wrapped)))
- (widget-use-overlay-change
- (goto-char (previous-overlay-change (point))))
- (t
- (backward-char 1)))
- (and (= wrapped 2)
- (eq arg number)
- (error "No buttons or fields found"))
- (let ((new (widget-tabable-at)))
- (when new
- (unless (eq new old)
- (setq arg (1+ arg))))))
+ (let* ((wrapped 0)
+ (number arg)
+ (fwd (> arg 0)) ; widget-forward is caller.
+ (bwd (< arg 0)) ; widget-backward is caller.
+ (old (widget-tabable-at))
+ (tabable (if old 1 0))
+ pos)
+ (catch 'one
+ (while (> (abs arg) 0)
+ (cond ((or (and fwd (eobp)) (and bwd (bobp)))
+ (goto-char (cond (fwd (point-min))
+ (bwd (point-max))))
+ (setq wrapped (1+ wrapped)))
+ (widget-use-overlay-change
+ (goto-char (cond (fwd (next-overlay-change (point)))
+ (bwd (previous-overlay-change (point))))))
+ (t
+ (cond (fwd (forward-char 1))
+ (bwd (backward-char 1)))))
+ (and (= wrapped 2)
+ (eq arg number)
+ (if (= tabable 1)
+ (progn
+ (goto-char pos)
+ (throw 'one (message "Only one tabable widget")))
+ (error "No buttons or fields found")))
+ (let ((new (widget-tabable-at)))
+ (when new
+ (if (eq new old)
+ (setq pos (point))
+ (cl-incf tabable)
+ (setq arg (cond (fwd (1- arg))
+ (bwd (1+ arg))))
+ (setq old new))))))
(let ((new (widget-tabable-at)))
(while (and (eq (widget-tabable-at) new) (not (bobp)))
(backward-char)))
next reply other threads:[~2024-04-26 12:43 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-26 12:43 Stephen Berman via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-04-26 15:02 ` bug#70594: 30.0.50; Error when tabbing with only one active widget Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87r0esl2f5.fsf@gmx.net \
--to=bug-gnu-emacs@gnu.org \
--cc=70594@debbugs.gnu.org \
--cc=stephen.berman@gmx.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).