diff options
| author | Gregory Heytings | 2021-05-15 20:15:59 +0000 |
|---|---|---|
| committer | Eli Zaretskii | 2021-05-29 11:05:33 +0300 |
| commit | bd5c7404195e45f11946b4e0933a1f8b697d8b87 (patch) | |
| tree | 71852ee487e69b320e333a3bfd18047ca9de8c20 | |
| parent | 7bbd6b720e60cb5e726214268c5b80a3e23f799e (diff) | |
| download | emacs-bd5c7404195e45f11946b4e0933a1f8b697d8b87.tar.gz emacs-bd5c7404195e45f11946b4e0933a1f8b697d8b87.zip | |
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'.
| -rw-r--r-- | lisp/international/quail.el | 72 | ||||
| -rw-r--r-- | lisp/subr.el | 6 | ||||
| -rw-r--r-- | lisp/term/xterm.el | 20 | ||||
| -rw-r--r-- | src/keyboard.c | 13 |
4 files changed, 55 insertions, 56 deletions
diff --git a/lisp/international/quail.el b/lisp/international/quail.el index fff06deee88..33851f09a13 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el | |||
| @@ -1368,6 +1368,27 @@ If STR has `advice' text property, append the following special event: | |||
| 1368 | (delete-region (overlay-start quail-overlay) | 1368 | (delete-region (overlay-start quail-overlay) |
| 1369 | (overlay-end quail-overlay)))) | 1369 | (overlay-end quail-overlay)))) |
| 1370 | 1370 | ||
| 1371 | (defun quail-add-unread-command-events (key &optional reset) | ||
| 1372 | "Add KEY to `unread-command-events', ensuring that it is not recorded. | ||
| 1373 | If KEY is a character, it is prepended to `unread-command-events' as | ||
| 1374 | a cons cell of the form (no-record . KEY). | ||
| 1375 | If KEY is a vector of events, the events in the vector are prepended | ||
| 1376 | to `unread-command-events', after converting each event to a cons cell | ||
| 1377 | of the form (no-record . EVENT). | ||
| 1378 | Quail puts keys back in `unread-command-events' to be handled again, | ||
| 1379 | and when it does this these keys have already been recorded in the | ||
| 1380 | recent keys and in the keyboard macro being defined, which means that | ||
| 1381 | recording them again creates duplicates. | ||
| 1382 | When RESET is non-nil, the events in `unread-command-events' are first | ||
| 1383 | discarded." | ||
| 1384 | (if reset (setq unread-command-events nil)) | ||
| 1385 | (setq unread-command-events | ||
| 1386 | (if (characterp key) | ||
| 1387 | (cons (cons 'no-record key) unread-command-events) | ||
| 1388 | (append (mapcan (lambda (e) (list (cons 'no-record e))) | ||
| 1389 | (append key nil)) | ||
| 1390 | unread-command-events)))) | ||
| 1391 | |||
| 1371 | (defun quail-start-translation (key) | 1392 | (defun quail-start-translation (key) |
| 1372 | "Start translation of the typed character KEY by the current Quail package. | 1393 | "Start translation of the typed character KEY by the current Quail package. |
| 1373 | Return the input string." | 1394 | Return the input string." |
| @@ -1385,13 +1406,11 @@ Return the input string." | |||
| 1385 | ;; (generated-events nil) ;FIXME: What is this? | 1406 | ;; (generated-events nil) ;FIXME: What is this? |
| 1386 | (input-method-function nil) | 1407 | (input-method-function nil) |
| 1387 | (modified-p (buffer-modified-p)) | 1408 | (modified-p (buffer-modified-p)) |
| 1388 | last-command-event last-command this-command inhibit-record) | 1409 | last-command-event last-command this-command) |
| 1389 | (setq quail-current-key "" | 1410 | (setq quail-current-key "" |
| 1390 | quail-current-str "" | 1411 | quail-current-str "" |
| 1391 | quail-translating t) | 1412 | quail-translating t) |
| 1392 | (if key | 1413 | (if key (quail-add-unread-command-events key)) |
| 1393 | (setq unread-command-events (cons key unread-command-events) | ||
| 1394 | inhibit-record t)) | ||
| 1395 | (while quail-translating | 1414 | (while quail-translating |
| 1396 | (set-buffer-modified-p modified-p) | 1415 | (set-buffer-modified-p modified-p) |
| 1397 | (quail-show-guidance) | 1416 | (quail-show-guidance) |
| @@ -1400,13 +1419,8 @@ Return the input string." | |||
| 1400 | (or input-method-previous-message "") | 1419 | (or input-method-previous-message "") |
| 1401 | quail-current-str | 1420 | quail-current-str |
| 1402 | quail-guidance-str))) | 1421 | quail-guidance-str))) |
| 1403 | ;; We inhibit record_char only for the first key, | ||
| 1404 | ;; because it was already recorded before read_char | ||
| 1405 | ;; called quail-input-method. | ||
| 1406 | (inhibit--record-char inhibit-record) | ||
| 1407 | (keyseq (read-key-sequence prompt nil nil t)) | 1422 | (keyseq (read-key-sequence prompt nil nil t)) |
| 1408 | (cmd (lookup-key (quail-translation-keymap) keyseq))) | 1423 | (cmd (lookup-key (quail-translation-keymap) keyseq))) |
| 1409 | (setq inhibit-record nil) | ||
| 1410 | (if (if key | 1424 | (if (if key |
| 1411 | (and (commandp cmd) (not (eq cmd 'quail-other-command))) | 1425 | (and (commandp cmd) (not (eq cmd 'quail-other-command))) |
| 1412 | (eq cmd 'quail-self-insert-command)) | 1426 | (eq cmd 'quail-self-insert-command)) |
| @@ -1420,9 +1434,7 @@ Return the input string." | |||
| 1420 | (quail-error (message "%s" (cdr err)) (beep)))) | 1434 | (quail-error (message "%s" (cdr err)) (beep)))) |
| 1421 | ;; KEYSEQ is not defined in the translation keymap. | 1435 | ;; KEYSEQ is not defined in the translation keymap. |
| 1422 | ;; Let's return the event(s) to the caller. | 1436 | ;; Let's return the event(s) to the caller. |
| 1423 | (setq unread-command-events | 1437 | (quail-add-unread-command-events (this-single-command-raw-keys)) |
| 1424 | (append (this-single-command-raw-keys) | ||
| 1425 | unread-command-events)) | ||
| 1426 | (setq quail-translating nil)))) | 1438 | (setq quail-translating nil)))) |
| 1427 | (quail-delete-region) | 1439 | (quail-delete-region) |
| 1428 | quail-current-str) | 1440 | quail-current-str) |
| @@ -1450,15 +1462,13 @@ Return the input string." | |||
| 1450 | ;; (generated-events nil) ;FIXME: What is this? | 1462 | ;; (generated-events nil) ;FIXME: What is this? |
| 1451 | (input-method-function nil) | 1463 | (input-method-function nil) |
| 1452 | (modified-p (buffer-modified-p)) | 1464 | (modified-p (buffer-modified-p)) |
| 1453 | last-command-event last-command this-command inhibit-record) | 1465 | last-command-event last-command this-command) |
| 1454 | (setq quail-current-key "" | 1466 | (setq quail-current-key "" |
| 1455 | quail-current-str "" | 1467 | quail-current-str "" |
| 1456 | quail-translating t | 1468 | quail-translating t |
| 1457 | quail-converting t | 1469 | quail-converting t |
| 1458 | quail-conversion-str "") | 1470 | quail-conversion-str "") |
| 1459 | (if key | 1471 | (if key (quail-add-unread-command-events key)) |
| 1460 | (setq unread-command-events (cons key unread-command-events) | ||
| 1461 | inhibit-record t)) | ||
| 1462 | (while quail-converting | 1472 | (while quail-converting |
| 1463 | (set-buffer-modified-p modified-p) | 1473 | (set-buffer-modified-p modified-p) |
| 1464 | (or quail-translating | 1474 | (or quail-translating |
| @@ -1474,13 +1484,8 @@ Return the input string." | |||
| 1474 | quail-conversion-str | 1484 | quail-conversion-str |
| 1475 | quail-current-str | 1485 | quail-current-str |
| 1476 | quail-guidance-str))) | 1486 | quail-guidance-str))) |
| 1477 | ;; We inhibit record_char only for the first key, | ||
| 1478 | ;; because it was already recorded before read_char | ||
| 1479 | ;; called quail-input-method. | ||
| 1480 | (inhibit--record-char inhibit-record) | ||
| 1481 | (keyseq (read-key-sequence prompt nil nil t)) | 1487 | (keyseq (read-key-sequence prompt nil nil t)) |
| 1482 | (cmd (lookup-key (quail-conversion-keymap) keyseq))) | 1488 | (cmd (lookup-key (quail-conversion-keymap) keyseq))) |
| 1483 | (setq inhibit-record nil) | ||
| 1484 | (if (if key (commandp cmd) (eq cmd 'quail-self-insert-command)) | 1489 | (if (if key (commandp cmd) (eq cmd 'quail-self-insert-command)) |
| 1485 | (progn | 1490 | (progn |
| 1486 | (setq last-command-event (aref keyseq (1- (length keyseq))) | 1491 | (setq last-command-event (aref keyseq (1- (length keyseq))) |
| @@ -1503,9 +1508,7 @@ Return the input string." | |||
| 1503 | (setq quail-converting nil))))) | 1508 | (setq quail-converting nil))))) |
| 1504 | ;; KEYSEQ is not defined in the conversion keymap. | 1509 | ;; KEYSEQ is not defined in the conversion keymap. |
| 1505 | ;; Let's return the event(s) to the caller. | 1510 | ;; Let's return the event(s) to the caller. |
| 1506 | (setq unread-command-events | 1511 | (quail-add-unread-command-events (this-single-command-raw-keys)) |
| 1507 | (append (this-single-command-raw-keys) | ||
| 1508 | unread-command-events)) | ||
| 1509 | (setq quail-converting nil)))) | 1512 | (setq quail-converting nil)))) |
| 1510 | (setq quail-translating nil) | 1513 | (setq quail-translating nil) |
| 1511 | (if (overlay-start quail-conv-overlay) | 1514 | (if (overlay-start quail-conv-overlay) |
| @@ -1551,9 +1554,8 @@ with more keys." | |||
| 1551 | (or input-method-exit-on-first-char | 1554 | (or input-method-exit-on-first-char |
| 1552 | (while (> len control-flag) | 1555 | (while (> len control-flag) |
| 1553 | (setq len (1- len)) | 1556 | (setq len (1- len)) |
| 1554 | (setq unread-command-events | 1557 | (quail-add-unread-command-events |
| 1555 | (cons (aref quail-current-key len) | 1558 | (aref quail-current-key len)))))) |
| 1556 | unread-command-events)))))) | ||
| 1557 | ((null control-flag) | 1559 | ((null control-flag) |
| 1558 | (unless quail-current-str | 1560 | (unless quail-current-str |
| 1559 | (setq quail-current-str | 1561 | (setq quail-current-str |
| @@ -1799,8 +1801,7 @@ sequence counting from the head." | |||
| 1799 | (setcar indices (1+ (car indices))) | 1801 | (setcar indices (1+ (car indices))) |
| 1800 | (quail-update-current-translations) | 1802 | (quail-update-current-translations) |
| 1801 | (quail-update-translation nil))) | 1803 | (quail-update-translation nil))) |
| 1802 | (setq unread-command-events | 1804 | (quail-add-unread-command-events last-command-event) |
| 1803 | (cons last-command-event unread-command-events)) | ||
| 1804 | (quail-terminate-translation))) | 1805 | (quail-terminate-translation))) |
| 1805 | 1806 | ||
| 1806 | (defun quail-prev-translation () | 1807 | (defun quail-prev-translation () |
| @@ -1814,8 +1815,7 @@ sequence counting from the head." | |||
| 1814 | (setcar indices (1- (car indices))) | 1815 | (setcar indices (1- (car indices))) |
| 1815 | (quail-update-current-translations) | 1816 | (quail-update-current-translations) |
| 1816 | (quail-update-translation nil))) | 1817 | (quail-update-translation nil))) |
| 1817 | (setq unread-command-events | 1818 | (quail-add-unread-command-events last-command-event) |
| 1818 | (cons last-command-event unread-command-events)) | ||
| 1819 | (quail-terminate-translation))) | 1819 | (quail-terminate-translation))) |
| 1820 | 1820 | ||
| 1821 | (defun quail-next-translation-block () | 1821 | (defun quail-next-translation-block () |
| @@ -1830,8 +1830,7 @@ sequence counting from the head." | |||
| 1830 | (setcar indices (+ (nth 2 indices) offset)) | 1830 | (setcar indices (+ (nth 2 indices) offset)) |
| 1831 | (quail-update-current-translations) | 1831 | (quail-update-current-translations) |
| 1832 | (quail-update-translation nil))) | 1832 | (quail-update-translation nil))) |
| 1833 | (setq unread-command-events | 1833 | (quail-add-unread-command-events last-command-event) |
| 1834 | (cons last-command-event unread-command-events)) | ||
| 1835 | (quail-terminate-translation))) | 1834 | (quail-terminate-translation))) |
| 1836 | 1835 | ||
| 1837 | (defun quail-prev-translation-block () | 1836 | (defun quail-prev-translation-block () |
| @@ -1850,8 +1849,7 @@ sequence counting from the head." | |||
| 1850 | (setcar indices (+ (nth 1 indices) offset)) | 1849 | (setcar indices (+ (nth 1 indices) offset)) |
| 1851 | (quail-update-current-translations))) | 1850 | (quail-update-current-translations))) |
| 1852 | (quail-update-translation nil))) | 1851 | (quail-update-translation nil))) |
| 1853 | (setq unread-command-events | 1852 | (quail-add-unread-command-events last-command-event) |
| 1854 | (cons last-command-event unread-command-events)) | ||
| 1855 | (quail-terminate-translation))) | 1853 | (quail-terminate-translation))) |
| 1856 | 1854 | ||
| 1857 | (defun quail-abort-translation () | 1855 | (defun quail-abort-translation () |
| @@ -2006,8 +2004,8 @@ Remaining args are for FUNC." | |||
| 2006 | (sit-for 1000000) | 2004 | (sit-for 1000000) |
| 2007 | (delete-region point-max (point-max)) | 2005 | (delete-region point-max (point-max)) |
| 2008 | (when quit-flag | 2006 | (when quit-flag |
| 2009 | (setq quit-flag nil | 2007 | (setq quit-flag nil) |
| 2010 | unread-command-events '(7))))) | 2008 | (quail-add-unread-command-events 7 t)))) |
| 2011 | 2009 | ||
| 2012 | (defun quail-show-guidance () | 2010 | (defun quail-show-guidance () |
| 2013 | "Display a guidance for Quail input method in some window. | 2011 | "Display a guidance for Quail input method in some window. |
diff --git a/lisp/subr.el b/lisp/subr.el index 82c2d221a68..78507a552c1 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -1757,6 +1757,12 @@ be a list of the form returned by `event-start' and `event-end'." | |||
| 1757 | (make-obsolete-variable 'load-dangerous-libraries | 1757 | (make-obsolete-variable 'load-dangerous-libraries |
| 1758 | "no longer used." "27.1") | 1758 | "no longer used." "27.1") |
| 1759 | 1759 | ||
| 1760 | (defvar inhibit--record-char nil | ||
| 1761 | "Obsolete variable. | ||
| 1762 | This was used internally by quail.el and keyboard.c in Emacs 27. | ||
| 1763 | It does nothing in Emacs 28.") | ||
| 1764 | (make-obsolete-variable 'inhibit--record-char nil "28.1") | ||
| 1765 | |||
| 1760 | ;; We can't actually make `values' obsolete, because that will result | 1766 | ;; We can't actually make `values' obsolete, because that will result |
| 1761 | ;; in warnings when using `values' in let-bindings. | 1767 | ;; in warnings when using `values' in let-bindings. |
| 1762 | ;;(make-obsolete-variable 'values "no longer used" "28.1") | 1768 | ;;(make-obsolete-variable 'values "no longer used" "28.1") |
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index eeaf805930b..8bcae37afe4 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el | |||
| @@ -770,8 +770,7 @@ Can be nil to mean \"no timeout\".") | |||
| 770 | By not redisplaying right away for xterm queries, we can avoid | 770 | By not redisplaying right away for xterm queries, we can avoid |
| 771 | unsightly flashing during initialization. Give up and redisplay | 771 | unsightly flashing during initialization. Give up and redisplay |
| 772 | anyway if we've been waiting a little while." | 772 | anyway if we've been waiting a little while." |
| 773 | (let ((start-time (current-time)) | 773 | (let ((start-time (current-time))) |
| 774 | (inhibit--record-char t)) | ||
| 775 | (or (let ((inhibit-redisplay t)) | 774 | (or (let ((inhibit-redisplay t)) |
| 776 | (read-event nil nil xterm-query-redisplay-timeout)) | 775 | (read-event nil nil xterm-query-redisplay-timeout)) |
| 777 | (read-event nil nil | 776 | (read-event nil nil |
| @@ -839,8 +838,8 @@ We run the first FUNCTION whose STRING matches the input events." | |||
| 839 | basemap | 838 | basemap |
| 840 | (make-composed-keymap map (keymap-parent basemap)))) | 839 | (make-composed-keymap map (keymap-parent basemap)))) |
| 841 | 840 | ||
| 842 | (defun terminal-init-xterm () | 841 | (defun xterm--init () |
| 843 | "Terminal initialization function for xterm." | 842 | "Initialize the terminal for xterm." |
| 844 | ;; rxvt terminals sometimes set the TERM variable to "xterm", but | 843 | ;; rxvt terminals sometimes set the TERM variable to "xterm", but |
| 845 | ;; rxvt's keybindings are incompatible with xterm's. It is | 844 | ;; rxvt's keybindings are incompatible with xterm's. It is |
| 846 | ;; better in that case to use rxvt's initialization function. | 845 | ;; 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." | |||
| 882 | ;; support it just ignore the sequence. | 881 | ;; support it just ignore the sequence. |
| 883 | (xterm--init-bracketed-paste-mode) | 882 | (xterm--init-bracketed-paste-mode) |
| 884 | ;; We likewise unconditionally enable support for focus tracking. | 883 | ;; We likewise unconditionally enable support for focus tracking. |
| 885 | (xterm--init-focus-tracking) | 884 | (xterm--init-focus-tracking)) |
| 886 | 885 | ||
| 887 | (run-hooks 'terminal-init-xterm-hook)) | 886 | (defun terminal-init-xterm () |
| 887 | "Terminal initialization function for xterm." | ||
| 888 | (unwind-protect | ||
| 889 | (progn | ||
| 890 | (xterm--init) | ||
| 891 | ;; If the terminal initialization completed without errors, clear | ||
| 892 | ;; the lossage to discard the responses of the terminal emulator | ||
| 893 | ;; during initialization; otherwise they appear in the recent keys. | ||
| 894 | (clear-this-command-keys)) | ||
| 895 | (run-hooks 'terminal-init-xterm-hook))) | ||
| 888 | 896 | ||
| 889 | (defun xterm--init-modify-other-keys () | 897 | (defun xterm--init-modify-other-keys () |
| 890 | "Terminal initialization for xterm's modifyOtherKeys support." | 898 | "Terminal initialization for xterm's modifyOtherKeys support." |
diff --git a/src/keyboard.c b/src/keyboard.c index 47b5e590245..c855d45afab 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -3233,10 +3233,6 @@ help_char_p (Lisp_Object c) | |||
| 3233 | static void | 3233 | static void |
| 3234 | record_char (Lisp_Object c) | 3234 | record_char (Lisp_Object c) |
| 3235 | { | 3235 | { |
| 3236 | /* quail.el binds this to avoid recording keys twice. */ | ||
| 3237 | if (inhibit_record_char) | ||
| 3238 | return; | ||
| 3239 | |||
| 3240 | int recorded = 0; | 3236 | int recorded = 0; |
| 3241 | 3237 | ||
| 3242 | if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement))) | 3238 | 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. */); | |||
| 12343 | Vwhile_no_input_ignore_events, | 12339 | Vwhile_no_input_ignore_events, |
| 12344 | doc: /* Ignored events from while-no-input. */); | 12340 | doc: /* Ignored events from while-no-input. */); |
| 12345 | 12341 | ||
| 12346 | DEFVAR_BOOL ("inhibit--record-char", | ||
| 12347 | inhibit_record_char, | ||
| 12348 | doc: /* If non-nil, don't record input events. | ||
| 12349 | This inhibits recording input events for the purposes of keyboard | ||
| 12350 | macros, dribble file, and `recent-keys'. | ||
| 12351 | Internal use only. */); | ||
| 12352 | |||
| 12353 | pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); | 12342 | pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); |
| 12354 | } | 12343 | } |
| 12355 | 12344 | ||
| @@ -12383,8 +12372,6 @@ syms_of_keyboard_for_pdumper (void) | |||
| 12383 | /* Create the initial keyboard. Qt means 'unset'. */ | 12372 | /* Create the initial keyboard. Qt means 'unset'. */ |
| 12384 | eassert (initial_kboard == NULL); | 12373 | eassert (initial_kboard == NULL); |
| 12385 | initial_kboard = allocate_kboard (Qt); | 12374 | initial_kboard = allocate_kboard (Qt); |
| 12386 | |||
| 12387 | inhibit_record_char = false; | ||
| 12388 | } | 12375 | } |
| 12389 | 12376 | ||
| 12390 | void | 12377 | void |