]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update key-chord
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Wed, 21 May 2025 12:48:37 +0000 (14:48 +0200)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Wed, 21 May 2025 12:48:37 +0000 (14:48 +0200)
bba-programming.org
elpa/key-chord-20240910.1441/key-chord-autoloads.el [deleted file]
elpa/key-chord-20240910.1441/key-chord-pkg.el [deleted file]
elpa/key-chord-20240910.1441/key-chord.el [deleted file]
elpa/key-chord-20250330.2011/key-chord-autoloads.el [new file with mode: 0644]
elpa/key-chord-20250330.2011/key-chord-pkg.el [new file with mode: 0644]
elpa/key-chord-20250330.2011/key-chord.el [new file with mode: 0644]

index 3503d4c8b1d899562dd8642ebe0348bd4b36dc19..608c55d1ce74452bf85c0dcd2aafadc849a770c4 100644 (file)
@@ -136,7 +136,7 @@ for C-c T you can use a file like this one:
 combine key strokes to access commands even faster.
 
 #+BEGIN_SRC emacs-lisp
-  (add-to-list 'load-path "~/.emacs.d/elpa/key-chord-20230522.223")
+  (add-to-list 'load-path "~/.emacs.d/elpa/key-chord-20250330.2011")
 
   (require 'key-chord)
   (key-chord-mode 1)
diff --git a/elpa/key-chord-20240910.1441/key-chord-autoloads.el b/elpa/key-chord-20240910.1441/key-chord-autoloads.el
deleted file mode 100644 (file)
index da24cb8..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-;;; key-chord-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
-;; Generated by the `loaddefs-generate' function.
-
-;; This file is part of GNU Emacs.
-
-;;; Code:
-
-(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
-
-
-\f
-;;; Generated autoloads from key-chord.el
-
-(defvar key-chord-mode nil "\
-Non-nil if Key-Chord mode is enabled.
-See the `key-chord-mode' command
-for a description of this minor mode.
-Setting this variable directly does not take effect;
-either customize it (see the info node `Easy Customization')
-or call the function `key-chord-mode'.")
-(custom-autoload 'key-chord-mode "key-chord" nil)
-(autoload 'key-chord-mode "key-chord" "\
-Map pairs of simultaneously pressed keys to commands.
-
-See functions `key-chord-define-global', `key-chord-define-local',
-and `key-chord-define' and variables `key-chord-two-keys-delay'
-and `key-chord-one-key-delay'.
-
-This is a global minor mode.  If called interactively, toggle the
-`Key-Chord mode' mode.  If the prefix argument is positive, enable the
-mode, and if it is zero or negative, disable the mode.
-
-If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
-mode if ARG is nil, omitted, or is a positive number.  Disable the mode
-if ARG is a negative number.
-
-To check whether the minor mode is enabled in the current buffer,
-evaluate `(default-value \\='key-chord-mode)'.
-
-The mode's hook is called both when the mode is enabled and when it is
-disabled.
-
-(fn &optional ARG)" t)
-(autoload 'key-chord-define-global "key-chord" "\
-Define a key-chord of the two keys in KEYS starting a COMMAND.
-
-KEYS can be a string or a vector of two elements. Currently only
-elements that corresponds to ascii codes in the range 32 to 126
-can be used.
-
-COMMAND can be an interactive function, a string, or nil.
-If COMMAND is nil, the key-chord is removed.
-
-Note that KEYS defined locally in the current buffer will have
-precedence.
-
-(fn KEYS COMMAND)" t)
-(autoload 'key-chord-define-local "key-chord" "\
-Locally define a key-chord of the two keys in KEYS starting a COMMAND.
-
-KEYS can be a string or a vector of two elements. Currently only
-elements that corresponds to ascii codes in the range 32 to 126
-can be used.
-
-COMMAND can be an interactive function, a string, or nil.
-If COMMAND is nil, the key-chord is removed.
-
-The binding goes in the current buffer's local map, which in most
-cases is shared with all other buffers in the same major mode.
-
-(fn KEYS COMMAND)" t)
-(autoload 'key-chord-define "key-chord" "\
-Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
-
-KEYS can be a string or a vector of two elements. Currently only
-elements that corresponds to ascii codes in the range 32 to 126
-can be used.
-
-COMMAND can be an interactive function, a string, or nil.
-If COMMAND is nil, the key-chord is removed.
-
-(fn KEYMAP KEYS COMMAND)")
-(register-definition-prefixes "key-chord" '("key-chord-"))
-\f
-;;; End of scraped data
-
-(provide 'key-chord-autoloads)
-
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; no-native-compile: t
-;; coding: utf-8-emacs-unix
-;; End:
-
-;;; key-chord-autoloads.el ends here
diff --git a/elpa/key-chord-20240910.1441/key-chord-pkg.el b/elpa/key-chord-20240910.1441/key-chord-pkg.el
deleted file mode 100644 (file)
index 754b088..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-;; -*- no-byte-compile: t; lexical-binding: nil -*-
-(define-package "key-chord" "20240910.1441"
-  "Map pairs of simultaneously pressed keys to commands."
-  '((emacs "24"))
-  :url "https://github.com/emacsorphanage/key-chord"
-  :commit "fc75b1451759121601110da8ddfadcf5156318af"
-  :revdesc "fc75b1451759"
-  :keywords '("keyboard" "chord" "input")
-  :authors '(("David Andersson" . "l.david.anderssonsverige.nu"))
-  :maintainers '(("David Andersson" . "l.david.anderssonsverige.nu")))
diff --git a/elpa/key-chord-20240910.1441/key-chord.el b/elpa/key-chord-20240910.1441/key-chord.el
deleted file mode 100644 (file)
index f849da4..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-;;; key-chord.el --- map pairs of simultaneously pressed keys to commands  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2003, 2005, 2008, 2012 David Andersson
-
-;; Author: David Andersson <l.david.andersson(at)sverige.nu>
-;; Package-Version: 20240910.1441
-;; Package-Revision: fc75b1451759
-;; Package-Requires: ((emacs "24"))
-;; Keywords: keyboard chord input
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2 of
-;; the License, or (at your option) any later version.
-
-;; This program is distributed in the hope that it will be
-;; useful, but WITHOUT ANY WARRANTY; without even the implied
-;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-;; PURPOSE.  See the GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public
-;; License along with this program; if not, write to the Free
-;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-;; MA 02111-1307 USA
-
-;;; Commentary:
-
-;; This package implements support for mapping a pair of simultaneously
-;; pressed keys to a command and for mapping the same key being pressed
-;; twice in quick succession to a command. Such bindings are called
-;; "key chords".
-
-;;; Code:
-
-(defgroup key-chord nil
-  "Map pairs of simultaneously pressed keys to commands."
-  :group 'bindings)
-
-(defcustom key-chord-two-keys-delay 0.1
-  "Max time delay between two key press to be considered a key chord."
-  :type 'float)
-
-(defcustom key-chord-one-key-delay 0.2
-  "Max time delay between two press of the same key to be considered a key chord.
-This should normally be a little longer than `key-chord-two-keys-delay'."
-  :type 'float)
-
-(defcustom key-chord-in-macros t
-  "If nil, don't expand key chords when executing keyboard macros.
-
-If non-nil, expand chord sequenses in macros, but only if a
-similar chord was entered during the last interactive macro
-recording. (This carries a bit of guesswork. We can't know for
-sure when executing whether two keys were typed quickly or slowly
-when recorded.)"
-  :type 'boolean)
-
-;; Internal vars
-(defvar key-chord-mode nil)
-
-;; Shortcut for key-chord-input-method: no need to test a key again if it
-;; didn't matched a chord the last time. Improves feedback during autorepeat.
-(defvar key-chord-last-unmatched nil)
-
-;; Macro heuristics: Keep track of which chords was used when the last macro
-;; was defined. Or rather, only the first-char of the chords. Only expand
-;; matching chords during macro execution.
-(defvar key-chord-in-last-kbd-macro nil)
-(defvar key-chord-defining-kbd-macro nil)
-
-;;;###autoload
-(define-minor-mode key-chord-mode
-  "Map pairs of simultaneously pressed keys to commands.
-
-See functions `key-chord-define-global', `key-chord-define-local',
-and `key-chord-define' and variables `key-chord-two-keys-delay'
-and `key-chord-one-key-delay'."
-  :global t
-  (setq input-method-function
-        (and key-chord-mode
-             'key-chord-input-method)))
-
-;;;###autoload
-(defun key-chord-define-global (keys command)
-  "Define a key-chord of the two keys in KEYS starting a COMMAND.
-
-KEYS can be a string or a vector of two elements. Currently only
-elements that corresponds to ascii codes in the range 32 to 126
-can be used.
-
-COMMAND can be an interactive function, a string, or nil.
-If COMMAND is nil, the key-chord is removed.
-
-Note that KEYS defined locally in the current buffer will have
-precedence."
-  (interactive "sSet key chord globally (2 keys): \nCSet chord \"%s\" to command: ")
-  (key-chord-define (current-global-map) keys command))
-
-;;;###autoload
-(defun key-chord-define-local (keys command)
-  "Locally define a key-chord of the two keys in KEYS starting a COMMAND.
-
-KEYS can be a string or a vector of two elements. Currently only
-elements that corresponds to ascii codes in the range 32 to 126
-can be used.
-
-COMMAND can be an interactive function, a string, or nil.
-If COMMAND is nil, the key-chord is removed.
-
-The binding goes in the current buffer's local map, which in most
-cases is shared with all other buffers in the same major mode."
-  (interactive "sSet key chord locally (2 keys): \nCSet chord \"%s\" to command: ")
-  (key-chord-define (current-local-map) keys command))
-
-(defun key-chord-unset-global (keys)
-  "Remove global key-chord of the two keys in KEYS."
-  (interactive "sUnset key chord globally (2 keys): ")
-  (key-chord-define (current-global-map) keys nil))
-
-(defun key-chord-unset-local (keys)
-  "Remove local key-chord of the two keys in KEYS."
-  (interactive "sUnset key chord locally (2 keys): ")
-  (key-chord-define (current-local-map) keys nil))
-
-;;;###autoload
-(defun key-chord-define (keymap keys command)
-  "Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
-
-KEYS can be a string or a vector of two elements. Currently only
-elements that corresponds to ascii codes in the range 32 to 126
-can be used.
-
-COMMAND can be an interactive function, a string, or nil.
-If COMMAND is nil, the key-chord is removed."
-  (if (/= 2 (length keys))
-      (error "Key-chord keys must have two elements"))
-  ;; Exotic chars in a string are >255 but define-key wants 128..255
-  ;; for those.
-  (let ((key1 (logand 255 (aref keys 0)))
-        (key2 (logand 255 (aref keys 1))))
-    (if (eq key1 key2)
-        (define-key keymap (vector 'key-chord key1 key2) command)
-      (define-key keymap (vector 'key-chord key1 key2) command)
-      (define-key keymap (vector 'key-chord key2 key1) command))))
-
-(defun key-chord-lookup-key1 (keymap key)
-  "Like lookup-key but no third arg and no numeric return value."
-  (let ((res (lookup-key keymap key)))
-    (and (not (numberp res))
-         res)))
-
-(defun key-chord-lookup-key (key)
-  "Lookup KEY in all current key maps."
-  (let ((maps (current-minor-mode-maps))
-        res)
-    (while (and maps (not res))
-      (setq res (key-chord-lookup-key1 (car maps) key))
-      (setq maps (cdr maps)))
-    (or res
-        (and (current-local-map)
-             (key-chord-lookup-key1 (current-local-map) key))
-        (key-chord-lookup-key1 (current-global-map) key))))
-
-(defun key-chord-describe ()
-  "List key chord bindings in a help buffer.
-
-Two key chords will be listed twice and there will be Prefix
-Commands. Please ignore that."
-  (interactive)
-  (describe-bindings [key-chord]))
-
-(defun key-chord-input-method (first-char)
-  "Input method controlled by key bindings with the prefix `key-chord'."
-  (cond
-   ((and (not (eq first-char key-chord-last-unmatched))
-         (key-chord-lookup-key (vector 'key-chord first-char)))
-    (let ((delay (if (key-chord-lookup-key
-                      (vector 'key-chord first-char first-char))
-                     key-chord-one-key-delay
-                   key-chord-two-keys-delay)))
-      (cond ((if executing-kbd-macro
-                 (not (memq first-char key-chord-in-last-kbd-macro))
-               (when (bound-and-true-p eldoc-mode)
-                 (eldoc-pre-command-refresh-echo-area))
-               (sit-for delay 'no-redisplay))
-             (setq key-chord-last-unmatched nil)
-             (list first-char))
-            (t ; input-pending-p
-             (let* ((input-method-function nil)
-                    (next-char (read-event))
-                    (res (vector 'key-chord first-char next-char)))
-               (cond ((key-chord-lookup-key res)
-                      (setq key-chord-defining-kbd-macro
-                            (cons first-char key-chord-defining-kbd-macro))
-                      (list 'key-chord first-char next-char))
-                     (t ;put back next-char and return first-char
-                      (setq unread-command-events
-                            (cons next-char unread-command-events))
-                      (when (eq first-char next-char)
-                        (setq key-chord-last-unmatched first-char))
-                      (list first-char))))))))
-   (t ; no key-chord keymap
-    (setq key-chord-last-unmatched first-char)
-    (list first-char))))
-
-(defun key-chord--start-kbd-macro (_append &optional _no-exec)
-  (setq key-chord-defining-kbd-macro nil))
-(advice-add 'start-kbd-macro :after #'key-chord--start-kbd-macro)
-
-(defun key-chord--end-kbd-macro (&optional _repeat _loopfunc)
-  (setq key-chord-in-last-kbd-macro key-chord-defining-kbd-macro))
-(advice-add 'end-kbd-macro :after #'key-chord--end-kbd-macro)
-
-(provide 'key-chord)
-;; Local Variables:
-;; indent-tabs-mode: nil
-;; End:
-;;; key-chord.el ends here
diff --git a/elpa/key-chord-20250330.2011/key-chord-autoloads.el b/elpa/key-chord-20250330.2011/key-chord-autoloads.el
new file mode 100644 (file)
index 0000000..43c08e1
--- /dev/null
@@ -0,0 +1,109 @@
+;;; key-chord-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+\f
+;;; Generated autoloads from key-chord.el
+
+(defvar key-chord-mode nil "\
+Non-nil if Key-Chord mode is enabled.
+See the `key-chord-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `key-chord-mode'.")
+(custom-autoload 'key-chord-mode "key-chord" nil)
+(autoload 'key-chord-mode "key-chord" "\
+Map pairs of simultaneously pressed keys to commands.
+
+See functions `key-chord-define-global', `key-chord-define-local',
+and `key-chord-define' and variables `key-chord-two-keys-delay'
+and `key-chord-one-key-delay'.
+
+This is a global minor mode.  If called interactively, toggle the
+`Key-Chord mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
+mode if ARG is nil, omitted, or is a positive number.  Disable the mode
+if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='key-chord-mode)'.
+
+The mode's hook is called both when the mode is enabled and when it is
+disabled.
+
+(fn &optional ARG)" t)
+(autoload 'key-chord-define-global "key-chord" "\
+Define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+Note that KEYS defined locally in the current buffer will have
+precedence.
+
+(fn KEYS COMMAND)" t)
+(autoload 'key-chord-define-local "key-chord" "\
+Locally define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+The binding goes in the current buffer's local map, which in most
+cases is shared with all other buffers in the same major mode.
+
+(fn KEYS COMMAND)" t)
+(autoload 'key-chord-register-keys "key-chord" "\
+Register KEY1 and KEY2 as being used in a key chord.
+This function should be called by packages that define key chords
+outside of the standard key-chord-define functions.
+
+(fn KEY1 KEY2)")
+(autoload 'key-chord-unregister-keys "key-chord" "\
+Unregister KEY1 and KEY2 as being used in a key chord.
+This should only be called if you're certain these keys are not
+used in any other chords.
+
+(fn KEY1 KEY2)")
+(autoload 'key-chord-define "key-chord" "\
+Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+(fn KEYMAP KEYS COMMAND)")
+(register-definition-prefixes "key-chord" '("key-chord-"))
+\f
+;;; End of scraped data
+
+(provide 'key-chord-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; key-chord-autoloads.el ends here
diff --git a/elpa/key-chord-20250330.2011/key-chord-pkg.el b/elpa/key-chord-20250330.2011/key-chord-pkg.el
new file mode 100644 (file)
index 0000000..cc98a12
--- /dev/null
@@ -0,0 +1,10 @@
+;; -*- no-byte-compile: t; lexical-binding: nil -*-
+(define-package "key-chord" "20250330.2011"
+  "Map pairs of simultaneously pressed keys to commands."
+  '((emacs "24"))
+  :url "https://github.com/LemonBreezes/key-chord"
+  :commit "cb646e815c61f253ad9fdfbe058049dda4e2b32b"
+  :revdesc "cb646e815c61"
+  :keywords '("keyboard" "chord" "input")
+  :authors '(("David Andersson" . "l.david.anderssonsverige.nu"))
+  :maintainers '(("LemonBreezes" . "lookNOSPAMstrawberrytea.xyz")))
diff --git a/elpa/key-chord-20250330.2011/key-chord.el b/elpa/key-chord-20250330.2011/key-chord.el
new file mode 100644 (file)
index 0000000..e05ae28
--- /dev/null
@@ -0,0 +1,460 @@
+;;; key-chord.el --- map pairs of simultaneously pressed keys to commands
+;;  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2003, 2005, 2008, 2012 David Andersson
+
+;; Author: David Andersson <l.david.andersson(at)sverige.nu>
+;; Maintainer: LemonBreezes <lookNOSPAMstrawberrytea.xyz>
+;; Package-Version: 20250330.2011
+;; Package-Revision: cb646e815c61
+;; Package-Requires: ((emacs "24"))
+;; Keywords: keyboard chord input
+;; URL: https://github.com/LemonBreezes/key-chord
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be
+;; useful, but WITHOUT ANY WARRANTY; without even the implied
+;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+;; PURPOSE.  See the GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public
+;; License along with this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+
+;;; Commentary:
+
+;; This package implements support for mapping a pair of simultaneously
+;; pressed keys to a command and for mapping the same key being pressed
+;; twice in quick succession to a command. Such bindings are called
+;; "key chords".
+
+;;; Code:
+
+(defgroup key-chord nil
+  "Map pairs of simultaneously pressed keys to commands."
+  :group 'bindings)
+
+(defun key-chord-in-read-char-context-p ()
+  "Return non-nil if we're in a read-char or similar context.
+This is determined by checking if `overriding-local-map` is set to
+one of the special read keymaps."
+  (and overriding-local-map
+       (memq overriding-local-map
+             (list read-key-empty-map read-key-full-map))))
+
+(defcustom key-chord-two-keys-delay 0.1
+  "Max time delay between two key press to be considered a key chord."
+  :type 'float)
+
+(defcustom key-chord-one-key-delay 0.2
+  "Max time delay between two press of the same key for a chord.
+This should normally be a little longer than
+`key-chord-two-keys-delay'."
+  :type 'float)
+
+(defcustom key-chord-in-macros nil
+  "If nil, don't expand key chords when executing keyboard macros.
+
+If non-nil, expand chord sequenses in macros, but only if a similar
+chord was entered during the last interactive macro recording. (This
+carries a bit of guesswork. We can't know for sure when executing
+whether two keys were typed quickly or slowly when recorded. Be careful
+enabling this as it could cause key chords to be expanded in places
+where they shouldn't be)."
+  :type 'boolean)
+
+(defcustom key-chord-one-key-min-delay 0.0
+  "Minimum delay (in seconds) between two presses for a double-tap key chord.
+The delay applies for chords using the same key. If the delay between two
+identical key presses is less than this value (as when holding a key), the
+chord will not trigger."
+  :type 'float)
+
+(defcustom key-chord-typing-detection nil
+  "If non-nil, detect typing and temporarily disable chord detection.
+This helps avoid accidental chord triggering during fast typing. This
+also dramatically improves the performance of key-chord when typing text
+by acting like a debounce."
+  :type 'boolean)
+
+(defcustom key-chord-typing-speed-threshold 0.1
+  "Maximum delay between keystrokes to be considered part of typing flow.
+Measured in seconds. If keys are pressed faster than this threshold,
+key-chord detection will be temporarily disabled."
+  :type 'float)
+
+(defcustom key-chord-typing-reset-delay 0.5
+  "Time after which to reset typing detection if no keys are pressed.
+Measured in seconds. After this much idle time, key-chord detection
+will be re-enabled."
+  :type 'float)
+
+(defcustom key-chord-use-key-tracking t
+  "If non-nil, track which keys are used in chords to optimize lookups.
+This improves performance by avoiding unnecessary `key-chord-lookup-key'
+calls. However, it could potentially cause issues if key chords are
+defined outside of the normal key-chord-define* functions."
+  :type 'boolean)
+
+;; Internal vars
+(defvar key-chord-mode nil)
+
+;; Shortcut for key-chord-input-method: no need to test a key again if it
+;; didn't matched a chord the last time. Improves feedback during autorepeat.
+(defvar key-chord-last-unmatched nil)
+
+;; Macro heuristics: Keep track of which chords was used when the last macro
+;; was defined. Or rather, only the first-char of the chords. Only expand
+;; matching chords during macro execution.
+(defvar key-chord-in-last-kbd-macro nil)
+(defvar key-chord-defining-kbd-macro nil)
+
+
+;; Typing detection variables
+(defvar key-chord-in-typing-flow nil
+  "Non-nil when user appears to be typing text rather than executing commands.")
+(defvar key-chord-last-key-time nil
+  "Time when the last key was pressed.")
+(defvar key-chord-typing-reset-time nil
+  "Time after which typing flow should be reset.")
+
+
+;; Key tracking for optimization
+(defvar key-chord-keys-in-use (make-vector 256 nil)
+  "Vector indicating which keys are used in any chord.")
+
+;;;###autoload
+(define-minor-mode key-chord-mode
+  "Map pairs of simultaneously pressed keys to commands.
+
+See functions `key-chord-define-global', `key-chord-define-local',
+and `key-chord-define' and variables `key-chord-two-keys-delay'
+and `key-chord-one-key-delay'."
+  :global t
+  (setq input-method-function
+        (and key-chord-mode
+             'key-chord-input-method))
+  (key-chord-reset-typing-detection))
+
+;;;###autoload
+(defun key-chord-define-global (keys command)
+  "Define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+Note that KEYS defined locally in the current buffer will have
+precedence."
+  (interactive "sSet key chord globally (2 keys): \nCSet chord \"%s\" to command: ")
+  (key-chord-define (current-global-map) keys command))
+
+;;;###autoload
+(defun key-chord-define-local (keys command)
+  "Locally define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+The binding goes in the current buffer's local map, which in most
+cases is shared with all other buffers in the same major mode."
+  (interactive "sSet key chord locally (2 keys): \nCSet chord \"%s\" to command: ")
+  (key-chord-define (current-local-map) keys command))
+
+(defun key-chord-unset-global (keys)
+  "Remove global key-chord of the two keys in KEYS."
+  (interactive "sUnset key chord globally (2 keys): ")
+  (key-chord-define (current-global-map) keys nil))
+
+(defun key-chord-unset-local (keys)
+  "Remove local key-chord of the two keys in KEYS."
+  (interactive "sUnset key chord locally (2 keys): ")
+  (key-chord-define (current-local-map) keys nil))
+
+;;;###autoload
+(defun key-chord-register-keys (key1 key2)
+  "Register KEY1 and KEY2 as being used in a key chord.
+This function should be called by packages that define key chords
+outside of the standard key-chord-define functions."
+  ;; Always register keys regardless of key-tracking setting
+  (when (and (integerp key1) (< key1 256))
+    (aset key-chord-keys-in-use key1 t))
+  (when (and (integerp key2) (< key2 256))
+    (aset key-chord-keys-in-use key2 t)))
+
+;;;###autoload
+(defun key-chord-unregister-keys (key1 key2)
+  "Unregister KEY1 and KEY2 as being used in a key chord.
+This should only be called if you're certain these keys are not
+used in any other chords."
+  ;; Always attempt to unregister keys regardless of key-tracking setting
+  ;; Only unregister if we're sure the keys aren't used elsewhere
+  (let ((remove-key1 t)
+        (remove-key2 t))
+    ;; Check if keys are used in any other chords
+    (let ((maps (list (current-global-map) (current-local-map))))
+      (dolist (map (append maps (current-minor-mode-maps)))
+        (when map
+          ;; Check if key1 is used in any other chord
+          (dotimes (k 256)
+            (when (and (not (and (= k key2) (= key1 key2)))
+                       (or (key-chord-lookup-key1 map (vector 'key-chord key1 k))
+                           (key-chord-lookup-key1 map (vector 'key-chord k key1))))
+              (setq remove-key1 nil)))
+
+          ;; Check if key2 is used in any other chord
+          (dotimes (k 256)
+            (when (and (not (and (= k key1) (= key1 key2)))
+                       (or (key-chord-lookup-key1 map (vector 'key-chord key2 k))
+                           (key-chord-lookup-key1 map (vector 'key-chord k key2))))
+              (setq remove-key2 nil))))))
+
+    ;; Remove keys from tracking vector if not used elsewhere
+    (when remove-key1 (aset key-chord-keys-in-use key1 nil))
+    (when remove-key2 (aset key-chord-keys-in-use key2 nil))))
+
+;;;###autoload
+(defun key-chord-define (keymap keys command)
+  "Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only
+elements that corresponds to ascii codes in the range 32 to 126
+can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed."
+  (when (/= 2 (length keys))
+    (error "Key-chord keys must have two elements"))
+  (let ((key1 (aref keys 0))
+        (key2 (aref keys 1)))
+    ;; Check that both keys are bytes
+    (unless (and (integerp key1) (< key1 256)
+                 (integerp key2) (< key2 256))
+      (error "Key-chord keys must both be bytes (characters with codes < 256)"))
+
+    (if (eq key1 key2)
+        (define-key keymap (vector 'key-chord key1 key2) command)
+      (define-key keymap (vector 'key-chord key1 key2) command)
+      (define-key keymap (vector 'key-chord key2 key1) command))
+
+    ;; Update key tracking directly
+    (if command
+        (key-chord-register-keys key1 key2)
+      (key-chord-unregister-keys key1 key2))))
+
+(defun key-chord-lookup-key1 (keymap key)
+  "Like `lookup-key' but no third arg and no numeric return value.
+KEYMAP is the keymap to look up the KEY in."
+  (let ((res (lookup-key keymap key)))
+    (and (not (numberp res))
+         res)))
+
+(defun key-chord-lookup-key (key)
+  "Lookup KEY in all current key maps."
+  (let ((maps (current-minor-mode-maps))
+        res)
+    (while (and maps (not res))
+      (setq res (key-chord-lookup-key1 (car maps) key))
+      (setq maps (cdr maps)))
+    (or res
+        (and (current-local-map)
+             (key-chord-lookup-key1 (current-local-map) key))
+        (key-chord-lookup-key1 (current-global-map) key))))
+
+(defun key-chord-describe ()
+  "List key chord bindings in a help buffer.
+
+Two key chords will be listed twice and there will be Prefix
+Commands. Please ignore that."
+  (interactive)
+  (describe-bindings [key-chord]))
+
+(defun key-chord-reset-all-state ()
+  "Reset all key-chord state variables."
+  (setq key-chord-last-unmatched nil)
+  (setq key-chord-in-typing-flow nil)
+  (setq key-chord-last-key-time nil)
+  (setq key-chord-typing-reset-time nil))
+
+(defun key-chord-reset-typing-detection ()
+  "Reset typing detection state when `key-chord-mode' is toggled."
+  (key-chord-reset-all-state))
+
+(defun key-chord-reset-typing-mode ()
+  "Reset the typing detection mode."
+  (setq key-chord-in-typing-flow nil)
+  (setq key-chord-last-unmatched nil))
+
+(defun key-chord-pause-typing-flow ()
+  "Temporarily pause typing flow detection to allow chord detection."
+  (when key-chord-typing-detection
+    (setq key-chord-in-typing-flow nil)))
+
+(defun key-chord-valid-chord-char-p (char)
+  "Return non-nil if CHAR is valid for chord detection.
+A valid character is an integer in the range 0-255."
+  (and (integerp char) (< char 256)))
+
+(defun key-chord-execute-chord (first-char next-char)
+  "Execute the chord composed of FIRST-CHAR and NEXT-CHAR.
+Returns the key-chord event to be processed."
+  ;; Record the chord for macro tracking
+  (setq key-chord-defining-kbd-macro
+        (cons first-char key-chord-defining-kbd-macro))
+  ;; Reset state after successful chord execution
+  (setq key-chord-last-unmatched nil)
+  ;; Return the chord event
+  (list 'key-chord first-char next-char))
+
+(defun key-chord-no-chord (first-char &optional next-char)
+  "Handle the case when no chord is matched.
+FIRST-CHAR is the first character pressed.
+If NEXT-CHAR is provided, it will be added to `unread-command-events`."
+  (when next-char
+    (setq unread-command-events (cons next-char unread-command-events)))
+  (setq key-chord-last-unmatched first-char)
+  (list first-char))
+
+(defun key-chord-check-typing-flow (current-time)
+  "Check if user is in typing mode based on timing between keystrokes.
+CURRENT-TIME is the time at which the function was called."
+  (when key-chord-typing-detection
+    ;; Check if we need to reset typing flow based on elapsed time
+    (when (and key-chord-typing-reset-time
+               (> (float-time current-time) key-chord-typing-reset-time))
+      (setq key-chord-in-typing-flow nil)
+      (setq key-chord-last-unmatched nil)) ;; Reset last-unmatched when exiting typing flow
+
+    ;; Set new reset time
+    (setq key-chord-typing-reset-time
+          (+ (float-time current-time) key-chord-typing-reset-delay))
+
+    ;; Check if we're in typing flow based on timing
+    (unless key-chord-in-typing-flow
+      (when key-chord-last-key-time
+        (let ((elapsed (float-time (time-subtract current-time key-chord-last-key-time))))
+          (when (< elapsed key-chord-typing-speed-threshold)
+            (setq key-chord-in-typing-flow t)))))
+
+    ;; Update last key time
+    (setq key-chord-last-key-time current-time)))
+
+(defun key-chord-input-method (first-char)
+  "Input method controlled by key bindings with the prefix `key-chord'.
+FIRST-CHAR is the first character input by the user."
+  ;; Check if we're in a read-char context and bypass key-chord if so
+  (if (key-chord-in-read-char-context-p)
+      (progn
+        (key-chord-reset-all-state)
+        (list first-char))
+    
+    ;; Not in read-char context, proceed with normal key-chord processing
+    (progn
+      ;; Check typing mode (but not during macro execution)
+      (unless executing-kbd-macro
+        (key-chord-check-typing-flow (current-time)))
+
+      (cond
+       ;; For any non-valid chord character, bypass chord detection
+       ((not (key-chord-valid-chord-char-p first-char))
+        (setq key-chord-last-unmatched nil) ;; Reset for safety
+        (list first-char))
+
+       ;; Skip chord detection if in typing mode (but not during macro execution)
+       ((and key-chord-typing-detection
+             key-chord-in-typing-flow
+             (not executing-kbd-macro))
+        ;; Don't update key-chord-last-unmatched in typing flow mode
+        (list first-char))
+
+       ;; Skip chord detection during macro execution if key-chord-in-macros is nil
+       ;; or if the key is not in a recorded chord
+       ((and executing-kbd-macro
+             (or (not key-chord-in-macros)
+                 (not (memq first-char key-chord-in-last-kbd-macro))))
+        (key-chord-no-chord first-char))
+
+       ;; Optimization: Skip chord detection completely if key tracking is enabled
+       ;; and first-char is not used in any chord
+       ((and key-chord-use-key-tracking
+             (not (aref key-chord-keys-in-use first-char)))
+        (key-chord-no-chord first-char))
+
+       ;; Continue with chord detection for keys that might be part of a chord
+       ((not (eq first-char key-chord-last-unmatched))
+        (key-chord-pause-typing-flow) ;; Temporarily exit typing flow for chord detection
+        (let ((res (key-chord-lookup-key (vector 'key-chord first-char))))
+          (if (not res)
+              (key-chord-no-chord first-char)
+            (let ((start-time (current-time))
+                  (delay (if (key-chord-lookup-key
+                              (vector 'key-chord first-char first-char))
+                             key-chord-one-key-delay
+                           key-chord-two-keys-delay)))
+
+              ;; Read second character
+              (let ((next-char (read-event nil nil delay)))
+                (cond
+                 ;; No second character received within timeout
+                 ((null next-char)
+                  (key-chord-no-chord first-char))
+
+                 ;; Handle invalid next character
+                 ((not (key-chord-valid-chord-char-p next-char))
+                  (key-chord-no-chord first-char next-char))
+
+                 ;; Handle double-press of the same key (with timing checks)
+                 ((eq first-char next-char)
+                  (let ((elapsed (float-time (time-subtract (current-time) start-time))))
+                    (if (< elapsed key-chord-one-key-min-delay)
+                        ;; Too fast (key held down) - not a chord
+                        (key-chord-no-chord first-char next-char)
+                      ;; Check if this is a valid same-key chord
+                      (if (key-chord-lookup-key (vector 'key-chord first-char next-char))
+                          (key-chord-execute-chord first-char next-char)
+                        ;; Not a valid chord
+                        (key-chord-no-chord first-char next-char)))))
+
+                 ;; Handle two different keys
+                 (t
+                  ;; Check if this is a valid two-key chord
+                  (if (key-chord-lookup-key (vector 'key-chord first-char next-char))
+                      (key-chord-execute-chord first-char next-char)
+                    ;; Not a valid chord
+                    (key-chord-no-chord first-char next-char)))))))))
+       ;; Key was last unmatched
+       (t (key-chord-no-chord first-char))))))
+
+(defun key-chord--start-kbd-macro (_append &optional _no-exec)
+  "Reset key chord tracking when a keyboard macro is started.
+_APPEND and _NO-EXEC are ignored arguments from `start-kbd-macro'."
+  (setq key-chord-defining-kbd-macro nil))
+
+(advice-add 'start-kbd-macro :after #'key-chord--start-kbd-macro)
+
+
+(defun key-chord--end-kbd-macro (&optional _repeat _loopfunc)
+  "Save key chord information when a keyboard macro ends.
+_REPEAT and _LOOPFUNC are ignored arguments from `end-kbd-macro'."
+  (setq key-chord-in-last-kbd-macro key-chord-defining-kbd-macro))
+
+(advice-add 'end-kbd-macro :after #'key-chord--end-kbd-macro)
+
+
+(provide 'key-chord)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; key-chord.el ends here