1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-23 07:19:15 +00:00

Fix key recording bug when an input method is activated

* lisp/international/quail.el (quail-add-unread-command-events):
New function.
(quail-start-translation, quail-start-conversion)
(quail-update-translation, quail-next-translation)
(quail-prev-translation, quail-next-translation-block)
(quail-prev-translation-block, quail-minibuffer-message): Use
'quail-add-unread-command-events' (and partly revert commit
03e3440dbb).  (Bug#48042)

* lisp/subr.el (inhibit--record-char): Now obsolete.

* lisp/term/xterm.el (xterm--init): New function, with most of the
code of former 'terminal-init-xterm'.
(terminal-init-xterm): Clear the lossage after terminal
initialization (see Bug#44908).
(xterm--read-event-for-query): Do not use 'inhibit--record-char'
anymore (revert commit 3e6525d69f).

* src/keyboard.c (syms_of_keyboard): Remove 'inhibit--record-char'
(partly revert 03e3440dbb).
(record_char, syms_of_keyboard_for_pdumper): Do not use
'inhibit_record_char anymore'.
This commit is contained in:
Gregory Heytings 2021-05-15 20:15:59 +00:00 committed by Eli Zaretskii
parent 7bbd6b720e
commit bd5c740419
4 changed files with 55 additions and 56 deletions

View File

@ -1368,6 +1368,27 @@ If STR has `advice' text property, append the following special event:
(delete-region (overlay-start quail-overlay)
(overlay-end quail-overlay))))
(defun quail-add-unread-command-events (key &optional reset)
"Add KEY to `unread-command-events', ensuring that it is not recorded.
If KEY is a character, it is prepended to `unread-command-events' as
a cons cell of the form (no-record . KEY).
If KEY is a vector of events, the events in the vector are prepended
to `unread-command-events', after converting each event to a cons cell
of the form (no-record . EVENT).
Quail puts keys back in `unread-command-events' to be handled again,
and when it does this these keys have already been recorded in the
recent keys and in the keyboard macro being defined, which means that
recording them again creates duplicates.
When RESET is non-nil, the events in `unread-command-events' are first
discarded."
(if reset (setq unread-command-events nil))
(setq unread-command-events
(if (characterp key)
(cons (cons 'no-record key) unread-command-events)
(append (mapcan (lambda (e) (list (cons 'no-record e)))
(append key nil))
unread-command-events))))
(defun quail-start-translation (key)
"Start translation of the typed character KEY by the current Quail package.
Return the input string."
@ -1385,13 +1406,11 @@ Return the input string."
;; (generated-events nil) ;FIXME: What is this?
(input-method-function nil)
(modified-p (buffer-modified-p))
last-command-event last-command this-command inhibit-record)
last-command-event last-command this-command)
(setq quail-current-key ""
quail-current-str ""
quail-translating t)
(if key
(setq unread-command-events (cons key unread-command-events)
inhibit-record t))
(if key (quail-add-unread-command-events key))
(while quail-translating
(set-buffer-modified-p modified-p)
(quail-show-guidance)
@ -1400,13 +1419,8 @@ Return the input string."
(or input-method-previous-message "")
quail-current-str
quail-guidance-str)))
;; We inhibit record_char only for the first key,
;; because it was already recorded before read_char
;; called quail-input-method.
(inhibit--record-char inhibit-record)
(keyseq (read-key-sequence prompt nil nil t))
(cmd (lookup-key (quail-translation-keymap) keyseq)))
(setq inhibit-record nil)
(if (if key
(and (commandp cmd) (not (eq cmd 'quail-other-command)))
(eq cmd 'quail-self-insert-command))
@ -1420,9 +1434,7 @@ Return the input string."
(quail-error (message "%s" (cdr err)) (beep))))
;; KEYSEQ is not defined in the translation keymap.
;; Let's return the event(s) to the caller.
(setq unread-command-events
(append (this-single-command-raw-keys)
unread-command-events))
(quail-add-unread-command-events (this-single-command-raw-keys))
(setq quail-translating nil))))
(quail-delete-region)
quail-current-str)
@ -1450,15 +1462,13 @@ Return the input string."
;; (generated-events nil) ;FIXME: What is this?
(input-method-function nil)
(modified-p (buffer-modified-p))
last-command-event last-command this-command inhibit-record)
last-command-event last-command this-command)
(setq quail-current-key ""
quail-current-str ""
quail-translating t
quail-converting t
quail-conversion-str "")
(if key
(setq unread-command-events (cons key unread-command-events)
inhibit-record t))
(if key (quail-add-unread-command-events key))
(while quail-converting
(set-buffer-modified-p modified-p)
(or quail-translating
@ -1474,13 +1484,8 @@ Return the input string."
quail-conversion-str
quail-current-str
quail-guidance-str)))
;; We inhibit record_char only for the first key,
;; because it was already recorded before read_char
;; called quail-input-method.
(inhibit--record-char inhibit-record)
(keyseq (read-key-sequence prompt nil nil t))
(cmd (lookup-key (quail-conversion-keymap) keyseq)))
(setq inhibit-record nil)
(if (if key (commandp cmd) (eq cmd 'quail-self-insert-command))
(progn
(setq last-command-event (aref keyseq (1- (length keyseq)))
@ -1503,9 +1508,7 @@ Return the input string."
(setq quail-converting nil)))))
;; KEYSEQ is not defined in the conversion keymap.
;; Let's return the event(s) to the caller.
(setq unread-command-events
(append (this-single-command-raw-keys)
unread-command-events))
(quail-add-unread-command-events (this-single-command-raw-keys))
(setq quail-converting nil))))
(setq quail-translating nil)
(if (overlay-start quail-conv-overlay)
@ -1551,9 +1554,8 @@ with more keys."
(or input-method-exit-on-first-char
(while (> len control-flag)
(setq len (1- len))
(setq unread-command-events
(cons (aref quail-current-key len)
unread-command-events))))))
(quail-add-unread-command-events
(aref quail-current-key len))))))
((null control-flag)
(unless quail-current-str
(setq quail-current-str
@ -1799,8 +1801,7 @@ sequence counting from the head."
(setcar indices (1+ (car indices)))
(quail-update-current-translations)
(quail-update-translation nil)))
(setq unread-command-events
(cons last-command-event unread-command-events))
(quail-add-unread-command-events last-command-event)
(quail-terminate-translation)))
(defun quail-prev-translation ()
@ -1814,8 +1815,7 @@ sequence counting from the head."
(setcar indices (1- (car indices)))
(quail-update-current-translations)
(quail-update-translation nil)))
(setq unread-command-events
(cons last-command-event unread-command-events))
(quail-add-unread-command-events last-command-event)
(quail-terminate-translation)))
(defun quail-next-translation-block ()
@ -1830,8 +1830,7 @@ sequence counting from the head."
(setcar indices (+ (nth 2 indices) offset))
(quail-update-current-translations)
(quail-update-translation nil)))
(setq unread-command-events
(cons last-command-event unread-command-events))
(quail-add-unread-command-events last-command-event)
(quail-terminate-translation)))
(defun quail-prev-translation-block ()
@ -1850,8 +1849,7 @@ sequence counting from the head."
(setcar indices (+ (nth 1 indices) offset))
(quail-update-current-translations)))
(quail-update-translation nil)))
(setq unread-command-events
(cons last-command-event unread-command-events))
(quail-add-unread-command-events last-command-event)
(quail-terminate-translation)))
(defun quail-abort-translation ()
@ -2006,8 +2004,8 @@ Remaining args are for FUNC."
(sit-for 1000000)
(delete-region point-max (point-max))
(when quit-flag
(setq quit-flag nil
unread-command-events '(7)))))
(setq quit-flag nil)
(quail-add-unread-command-events 7 t))))
(defun quail-show-guidance ()
"Display a guidance for Quail input method in some window.

View File

@ -1757,6 +1757,12 @@ be a list of the form returned by `event-start' and `event-end'."
(make-obsolete-variable 'load-dangerous-libraries
"no longer used." "27.1")
(defvar inhibit--record-char nil
"Obsolete variable.
This was used internally by quail.el and keyboard.c in Emacs 27.
It does nothing in Emacs 28.")
(make-obsolete-variable 'inhibit--record-char nil "28.1")
;; We can't actually make `values' obsolete, because that will result
;; in warnings when using `values' in let-bindings.
;;(make-obsolete-variable 'values "no longer used" "28.1")

View File

@ -770,8 +770,7 @@ Can be nil to mean \"no timeout\".")
By not redisplaying right away for xterm queries, we can avoid
unsightly flashing during initialization. Give up and redisplay
anyway if we've been waiting a little while."
(let ((start-time (current-time))
(inhibit--record-char t))
(let ((start-time (current-time)))
(or (let ((inhibit-redisplay t))
(read-event nil nil xterm-query-redisplay-timeout))
(read-event nil nil
@ -839,8 +838,8 @@ We run the first FUNCTION whose STRING matches the input events."
basemap
(make-composed-keymap map (keymap-parent basemap))))
(defun terminal-init-xterm ()
"Terminal initialization function for xterm."
(defun xterm--init ()
"Initialize the terminal for xterm."
;; rxvt terminals sometimes set the TERM variable to "xterm", but
;; rxvt's keybindings are incompatible with xterm's. It is
;; better in that case to use rxvt's initialization function.
@ -882,9 +881,18 @@ We run the first FUNCTION whose STRING matches the input events."
;; support it just ignore the sequence.
(xterm--init-bracketed-paste-mode)
;; We likewise unconditionally enable support for focus tracking.
(xterm--init-focus-tracking)
(xterm--init-focus-tracking))
(run-hooks 'terminal-init-xterm-hook))
(defun terminal-init-xterm ()
"Terminal initialization function for xterm."
(unwind-protect
(progn
(xterm--init)
;; If the terminal initialization completed without errors, clear
;; the lossage to discard the responses of the terminal emulator
;; during initialization; otherwise they appear in the recent keys.
(clear-this-command-keys))
(run-hooks 'terminal-init-xterm-hook)))
(defun xterm--init-modify-other-keys ()
"Terminal initialization for xterm's modifyOtherKeys support."

View File

@ -3233,10 +3233,6 @@ help_char_p (Lisp_Object c)
static void
record_char (Lisp_Object c)
{
/* quail.el binds this to avoid recording keys twice. */
if (inhibit_record_char)
return;
int recorded = 0;
if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
@ -12343,13 +12339,6 @@ If nil, Emacs crashes immediately in response to fatal signals. */);
Vwhile_no_input_ignore_events,
doc: /* Ignored events from while-no-input. */);
DEFVAR_BOOL ("inhibit--record-char",
inhibit_record_char,
doc: /* If non-nil, don't record input events.
This inhibits recording input events for the purposes of keyboard
macros, dribble file, and `recent-keys'.
Internal use only. */);
pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
}
@ -12383,8 +12372,6 @@ syms_of_keyboard_for_pdumper (void)
/* Create the initial keyboard. Qt means 'unset'. */
eassert (initial_kboard == NULL);
initial_kboard = allocate_kboard (Qt);
inhibit_record_char = false;
}
void