TheEzEzz
TheEzEzz

Reputation: 177

Two key shortcut in emacs without repressing the first key?

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

Answers (6)

Jonathan M
Jonathan M

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:

Link

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

driftcrow
driftcrow

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

Drew
Drew

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

Oleg Pavliv
Oleg Pavliv

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

Daniel Brockman
Daniel Brockman

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

Anders Waldenborg
Anders Waldenborg

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

Related Questions