Context: I want to make a minor mode where pressing f
twice fast results in whatever the pressing of (
should do at that time. This doesn't always mean just insertion of (
. For example, in buffers where paredit mode or autopair mode is enabled, pressing of (
usually results in insertion of ()
. In a paredit mode buffer, that sometimes results in wrapping the selected text: for example, if I select a b
and press (
, that should result in replacing the selection with (a b)
.
For detection of f
being pressed twice, I just need to take the logic in the short code in http://www.emacswiki.org/emacs/electric-dot-and-dash.el
So the only missing piece is a Lisp code snippet that tells Emacs "Trigger pressing of (
now!"
The first thing that came to my mind was that the snippet should do
(
but that breaks down if the auto pairing package (autopair or paredit or other similar package) binds (
to a command that has a logic that looks up what key was used to call the command, or if the package simply relies on post-self-insert-hook or post-command-hook instead of binding (
.
update
I've looked up Key Chord documentation and it turns out what I am trying to do with answers to this question has a simpler solution:
(require 'key-chord)
(key-chord-mode 1)
(defvar my-easy-open-paren-mode-map
(let ((map (make-sparse-keymap)))
(key-chord-define map ",." (kbd "("))
map))
(define-minor-mode my-easy-open-paren-mode
"In this mode, pressing . and , together is another way of pressing the open paren.")
(defvar my-easy-semicolon-mode-map
(let ((map (make-sparse-keymap)))
(key-chord-define map ";;" (kbd "C-e ;"))
map))
(define-minor-mode my-easy-semicolon-mode
"In this mode, pressing semicolon twice fast is another way of pressing C-e and semicolon.")
(add-hook 'prog-mode-hook 'my-easy-open-paren-mode)
(add-hook 'c-mode-common-hook 'my-easy-semicolon-mode)
Triggering key press may still be useful in other contexts though.
The manual way is to use C-h k KEY to describe what KEY is bound to; the other way is to describe a function, FUNCTION , with C-h f FUNCTION . Because Emacs is a self-documenting editor all functions, variables, keys, etc. known to Emacs are accessible through the describe-xxx commands. Type C-h C-h to see them all.
Emacs Lisp is a dialect of the Lisp programming language used as a scripting language by Emacs (a text editor family most commonly associated with GNU Emacs and XEmacs). It is used for implementing most of the editing functionality built into Emacs, the remainder being written in C, as is the Lisp interpreter.
function (aka #' ) is used to quote functions, whereas quote (aka ' ) is used to quote data.
In a fresh Emacs window, type ESC-x lisp-interaction-mode . That will turn your buffer into a LISP terminal; pressing Ctrl+j will feed the s-expression that your cursor (called "point" in Emacs manuals' jargon) stands right behind to LISP, and will print the result.
You might appreciate the Key Chord library for binding functions to a double key-press. (I wouldn't recommend using f
if you'll be writing in English, mind you; but YMMV.)
post-self-insert-hook
would still run if the binding was self-insert-command
. post-command-hook
will run in any case, but if you're worried about it seeing an incorrect function and/or input event, you can manipulate those...
After looking up the binding, your function can set this-command
to the function you're about to call-interactively
, and last-command-event
to the required key. e.g.:
(defun my-fake-paren ()
(interactive)
(let ((command (key-binding "(")))
(setq last-command-event ?\()
(setq this-command command)
(call-interactively command)))
I use Key Chord for this sort of thing, although the page you link appears to do the same thing. The trick is getting the call to call-interactively
to work correctly. I wrapped it in a let that reset the variable last-command-event
, such that call-interactively
thinks it was a "(". This works for me in paredit and fundamental modes.
(require 'key-chord)
(key-chord-mode 1)
(defun my-paren-call ()
(interactive)
(let ((last-command-event ?\())
(call-interactively (key-binding "("))))
(key-chord-define-global "ff" 'my-paren-call)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With