reddit / emacs
Emulate keyboard input from elisp
Horrih · 2022-10-30 08:59
Hello all,
I have been playing with keymaps and wrapper commands a lot. And something I have come to realise is that a lot of stuff could be implemented really fast by sending arbitrary key sequences.
Keyboard macros seem limited to me : they look more like a succession of commands than a succession of keys.
Two examples I could not achieve with macros (maybe I'm doing it wrong)
\- Prepare a command : for example I want to prepare a call to isearch, with foo pre-typed into the minibuffer. When I do it the macro way, the macro will *execute* the command *isearch foo*
\- Define an alias for partial key-bindings : let's say I want to alias *C-x r* to *C-r*, so that i can type *C-r t* instead of C-x r t (which is bound to #'string-rectangle). I could not make a keyboard macro work since C-x r is not bound to anything
Is there anyway to send arbitrary key sequences to the emacs interpreter from elisp ?
​
Thanks !
ayy_ess · 2022-10-30 10:15
Would general-simulate-key from general.el work for these use-cases?
L-Szos · 2022-10-30 10:18
Id imagine `C-x r` is bound to a keymap, not to nothing. So you bind `C-r` to that keymap. `C-h k C-x r t` should tell you what keymap it is bound in (if i remember correctly, im away from my computer at the moment).
pwnedary · 2022-10-30 11:04
Someone correct me if I am wrong, but does not this come pretty close:
(let ((events (listify-key-sequence "the keys to type")))
(setq unread-input-method-events (nconc events unread-input-method-events)))
7890yuiop · 2022-10-30 11:09
> Is there anyway to send arbitrary key sequences to the emacs interpreter from elisp ?
Yes, you can push events onto `unread-command-events`.
github-alphapapa · 2022-10-30 14:13
See the package `with-simulated-input`.
JDRiverRun · 2022-10-30 14:47
I've seen it done like (with tabs and return/newline):
(setq unread-command-events (mapcar 'identity
"///ssh:datpi:/home/pi/no\\tex\\t/do\\tma\\tce\\t\\n"))
MunsterPlop · 2022-10-30 15:04
Actually, it's a key combination "rt" that is part of c-x-map like the rest of "r"* binds.
A keymap would definitely be better...
Horrih · 2022-10-30 21:43
>(setq unread-input-method-events (nconc events unread-input-method-events)))
Can confirm it works flawlessly in both cases, thanks a lot !
Horrih · 2022-10-30 21:46
This works perfectly out of the box thanks !
After checking out its source code it does use unread-command-events and listify-key-sequence functions described in other comments
Horrih · 2022-10-30 21:53
Interesting package, thanks ! The possibility to add wait timer can be useful
Horrih · 2022-10-30 21:54
Thanks, the unread-command-events did work in my case
Horrih · 2022-10-30 21:56
Thanks, it worked !
Horrih · 2022-10-30 22:03
Thank you all for your helpful answers
Both unread-command-events and unread-input-method-events worked in my tests
(defun gen-input(KEYS)
(setq unread-command-events (nconc (listify-key-sequence (kbd KEYS)) unread-command-events)))
Using general-simulate-keys seems to be the most fool-proof approach : it returns a new command (named after the key-sequence you used). This means that you can directly rebind it
(global-set-key my-binding (general-simulate-keys "C-s foo"))