Analysis of the problem
Looking at wid-edit.el
, the only call to widget-field-activate
happens inside widget-field-keymap
:
(defvar widget-field-keymap
(let ((map (copy-keymap widget-keymap)))
...
(define-key map "\C-m" 'widget-field-activate)
...
I cannot find the function used elsewhere, therefore the widget-field-activate
action can only be triggered when widget-field-keymap
is active and when Enter is pressed. Since this keymap is associated to editable fields, it means one should be inside a field and hit Enter.
There is however a "dead" spot on the right field boundary where an anomalous behaviour happens:
- Pressing Enter triggers
widget-field-activate
, which would imply you are inside the field.
However, using a Edebug, shows that this point is outside a field. In fact,
(get-char-property (point) 'field)
returns nil
, rather than the field properties.
The function widget-field-keymap
controls for this and: if Enter is pressed inside the field, activates the field; if Enter is pressed outside, executes the standard widget-global-map
binding for RET, which is (newline)
:
(defun widget-field-activate (pos &optional event)
"Invoke the editable field at point."
(interactive "@d")
(let ((field (widget-field-at pos))) ; <- the func checks if we are in a field
(if field
(widget-apply-action field event)
(call-interactively ; <- if not, lookup-key returns newline
(lookup-key widget-global-map (this-command-keys))))))
Calling the newline causes the bizarre result of visually breaking the field, spanning it over two lines.
Instead, the function should do nothing if the activation cannot proceed or perhaps return the usual read-only warning. Hence, the following
General workaround
(defun widget-field-activate (pos &optional event)
(interactive "@d")
(let ((field (widget-field-at pos)))
(if field
(widget-apply-action field event)
(message "Text is read-only: \"Attempt to change text outside editable field\""))))
I don't know if this version fixes a bug, but I haven't found any side effect and that produces a more desirable behaviour.
point
is the insertion positions between character positions. The rectangular cursor is a bit misleading in that regard. The relevant part of the cursor is its left edge which is actually better represented by the vertical bar you get when you customizecursor-type
tobar
. Difficult to spot -- not the default. Your problem does not occur immediately beforetext2
but immediately behind the widget field.RET
but byC-q C-j
(which corresponds more or less to a literalRET
).RET
does not insert a linebreak in the widget field since it is bound towidget-field-activate
in thewidget-field-keymap
which is active in the widget field.widget-before-change
,widget-after-change
, and the comment about not subtracting 1 iflocal-map
is working at the end of the overlay inwidget-field-end
.M-x report-emacs-bug
.