Fix tabbing between widgets (bug#70594)

* lisp/wid-edit.el (widget-move): Don't error when tabbing in a
buffer with only one active widget and 'widget-skip-inactive'
enabled.  Improve code by handling forward and backward movement
in a single loop.
This commit is contained in:
Stephen Berman 2024-06-25 12:38:03 +02:00
parent 6ad6507532
commit 2f18929319

View file

@ -1276,42 +1276,40 @@ This is much faster.")
ARG may be negative to move backward. ARG may be negative to move backward.
When the second optional argument is non-nil, When the second optional argument is non-nil,
nothing is shown in the echo area." nothing is shown in the echo area."
(let ((wrapped 0) (let* ((wrapped 0)
(number arg) (number arg)
(old (widget-tabable-at))) (fwd (> arg 0)) ; widget-forward is caller.
;; Forward. (bwd (< arg 0)) ; widget-backward is caller.
(while (> arg 0) (old (widget-tabable-at))
(cond ((eobp) (tabable (if old 1 0))
(goto-char (point-min)) pos)
(setq wrapped (1+ wrapped))) (catch 'one
(widget-use-overlay-change (while (> (abs arg) 0)
(goto-char (next-overlay-change (point)))) (cond ((or (and fwd (eobp)) (and bwd (bobp)))
(t (goto-char (cond (fwd (point-min))
(forward-char 1))) (bwd (point-max))))
(and (= wrapped 2) (setq wrapped (1+ wrapped)))
(eq arg number) (widget-use-overlay-change
(error "No buttons or fields found")) (goto-char (cond (fwd (next-overlay-change (point)))
(let ((new (widget-tabable-at))) (bwd (previous-overlay-change (point))))))
(when new (t
(unless (eq new old) (cond (fwd (forward-char 1))
(setq arg (1- arg)) (bwd (backward-char 1)))))
(setq old new))))) (and (= wrapped 2)
;; Backward. (eq arg number)
(while (< arg 0) (if (= tabable 1)
(cond ((bobp) (progn
(goto-char (point-max)) (goto-char pos)
(setq wrapped (1+ wrapped))) (throw 'one (message "Only one tabable widget")))
(widget-use-overlay-change (error "No buttons or fields found")))
(goto-char (previous-overlay-change (point)))) (let ((new (widget-tabable-at)))
(t (when new
(backward-char 1))) (if (eq new old)
(and (= wrapped 2) (setq pos (point))
(eq arg number) (cl-incf tabable)
(error "No buttons or fields found")) (setq arg (cond (fwd (1- arg))
(let ((new (widget-tabable-at))) (bwd (1+ arg))))
(when new (setq old new))))))
(unless (eq new old)
(setq arg (1+ arg))))))
(let ((new (widget-tabable-at))) (let ((new (widget-tabable-at)))
(while (and (eq (widget-tabable-at) new) (not (bobp))) (while (and (eq (widget-tabable-at) new) (not (bobp)))
(backward-char))) (backward-char)))