From 14189be77c18bb079f2f37da4147fba192f3efe1 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 12 Sep 2024 15:11:08 -0400 Subject: [PATCH] fix: out-of-bounds error if this-single-command-raw-keys is empty It seems there's an edge case in EXWM where input events may occur without keys to cause them (#8064), so these two keybind fixes need to be ready to receive an empty vector from `this-single-command-raw-keys`. Fix: #8064 --- lisp/doom-keybinds.el | 51 +++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/lisp/doom-keybinds.el b/lisp/doom-keybinds.el index 2ff1bcfe0..73bee7835 100644 --- a/lisp/doom-keybinds.el +++ b/lisp/doom-keybinds.el @@ -50,34 +50,29 @@ and Emacs states, and for non-evil users.") (setq w32-lwindow-modifier 'super w32-rwindow-modifier 'super))) -;; HACK: Emacs can't distinguish C-i from TAB in either GUI or TTY frames. This -;; is a byproduct of its history with the terminal, which can't distinguish -;; them either, however, Emacs has separate input events for many contentious -;; keys like TAB and RET (like [tab] and [return], aka "" and -;; ""), which are only triggered in GUI frames, so here, I create one -;; for C-i. Won't work in TTY frames, though. Doom's :os tty module has a -;; workaround for that though. -(define-key input-decode-map - [?\C-i] (cmd! (if (when-let ((keys (this-single-command-raw-keys))) - (and (display-graphic-p) - (not (cl-position 'tab keys)) - (not (cl-position 'kp-tab keys)) - ;; Fall back if no keybind can be found, - ;; otherwise we've broken all pre-existing C-i - ;; keybinds. - (key-binding (vconcat (cl-subseq keys 0 -1) [C-i]) nil t))) - [C-i] [?\C-i]))) - -;; HACK: Same as C-i, but C-m is a little harder. There is no workaround for -;; this for the terminal. -(define-key input-decode-map - [?\C-m] (cmd! (if (when-let ((keys (this-single-command-raw-keys))) - (and (display-graphic-p) - (not (cl-position 'return keys)) - (not (cl-position 'kp-return keys)) - ;; Fall back if no keybind can be found. - (key-binding (vconcat (cl-subseq keys 0 -1) [C-m]) nil t))) - [C-m] [?\C-m]))) +;; HACK: Emacs can't distinguish C-i from TAB, or C-m from RET, in either GUI or +;; TTY frames. This is a byproduct of its history with the terminal, which +;; can't distinguish them either, however, Emacs has separate input events for +;; many contentious keys like TAB and RET (like [tab] and [return], aka +;; "" and ""), which are only triggered in GUI frames, so here, I +;; create one for C-i. Won't work in TTY frames, though. Doom's :os tty module +;; has a workaround for that though. +(pcase-dolist (`(,key ,fallback . ,events) + '(([C-i] [?\C-i] tab kp-tab) + ([C-m] [?\C-m] return kp-return))) + (define-key + input-decode-map fallback + (cmd! (if (when-let ((keys (this-single-command-raw-keys))) + (and (display-graphic-p) + (not (cl-loop for event in events + if (cl-position event keys) + return t)) + ;; Use FALLBACK if nothing is bound to KEY, otherwise we've + ;; broken all pre-existing FALLBACK keybinds. + (key-binding + (vconcat (if (= 0 (length keys)) [] (cl-subseq keys 0 -1)) + key) nil t))) + key fallback)))) ;;