Reputation: 177
Suppose I define the following shortcut
(global-set-key (kbd "C-d C-j") "Hello!")
Is it possible to configure emacs so that if I type "C-d C-j C-j C-j"
I will get "Hello! Hello! Hello!" rather than having to type "C-d C-j C-d C-j C-d C-j"
?
Upvotes: 8
Views: 562
Reputation: 17451
No. The sequence "ctrl-d ctrl-j" is what is bound to the string "Hello!" Emacs binds the sequence as a whole to the given string. Here's some good info on the topic:
On the other hand, if you wanted just three instances of "Hello!", you could define that sequence C-d C-j C-d C-j C-d C-j
as "Hello! Hello! Hello!", but it would be shorter to just define a simpler sequence for the string you want.
Upvotes: 1
Reputation: 217
smartrep is all you want
(require 'smartrep)
(defvar ctl-d-map (make-keymap)) ;; create C-d map
(define-key global-map "\C-d" ctl-d-map)
(smartrep-define-key
global-map "C-d"
'(("C-j" . (insert "hello"))))
Upvotes: 0
Reputation: 30708
I use this all the time. You'll need library repeat.el
(part of GNU Emacs) to use it.
(defun make-repeatable (command) "Repeat COMMAND." (let ((repeat-message-function 'ignore)) (setq last-repeatable-command command) (repeat nil))) (defun my-hello () "Single `hello'." (interactive) (insert "HELLO!")) (defun my-hello-repeat () (interactive) (require 'repeat) (make-repeatable 'my-hello))
Now bind my-hello-repeat
:
(global-set-key (kbd "") 'my-hello-repeat)
Now just hold down the home key to repeat HELLO!.
I use this same technique in multiple libraries, including Bookmark+, thing-cmds, and wide-n.
Upvotes: 0
Reputation: 21182
Try something like this:
(global-set-key (kbd "C-c C-j") (lambda()
(interactive)
(insert "Hello!")
(message "Type j to print Hello!")
(while (equal (read-event) ?j)
(insert "Hello!"))
(push last-input-event unread-command-events)))
Idea taken from kmacro-call-macro
Upvotes: 2
Reputation: 19290
I don’t think you can configure Emacs so that it does that for all commands. However, you can implement this functionality in the commands themselves. This is what is done for C-x e. Here is a macro I just wrote (guided by the standard definition of kmacro-call-macro
in GNU Emacs 23.1.1) that makes it easy to add this functionality to your own commands:
(defmacro with-easy-repeat (&rest body)
"Execute BODY and repeat while the user presses the last key."
(declare (indent 0))
`(let* ((repeat-key (and (> (length (this-single-command-keys)) 1)
last-input-event))
(repeat-key-str (format-kbd-macro (vector repeat-key) nil)))
,@body
(while repeat-key
(message "(Type %s to repeat)" repeat-key-str)
(let ((event (read-event)))
(clear-this-command-keys t)
(if (equal event repeat-key)
(progn ,@body
(setq last-input-event nil))
(setq repeat-key nil)
(push last-input-event unread-command-events))))))
Here’s how you use it:
(defun hello-world ()
(interactive)
(with-easy-repeat
(insert "Hello, World!\n")))
(global-set-key (kbd "C-c x y z") 'hello-world)
Now you can type C-c x y z z z to insert Hello, World!
three times.
Upvotes: 11
Reputation: 3035
If you are looking for something generic that works on all commands I cant see how that would work - how would emacs know if you are starting a new command or want to repeat the previous. A better example would be "C-c h", if you type "h" after that, should emacs repeat the command or insert a h?
That said, emacs already has a mechanism for this - the universal argument.
Try this key sequence:
C-u 3 C-d C-j
It is even fewer keypresses than C-d C-j C-j C-j C-j
Upvotes: 4