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)))