For something long-term, I would recommend the approach shown by seh, as this will naturally be more stable in most situations. Of course, this requires a little more work and know-how, but it all costs :)
An approach
angus is similar to an abridged version of the keyboard macro function, which gives Emacs its name (and is a bit easier to use than the macros for this example). However, you definitely need to know macros - they can be extremely useful, and for something more complicated it quickly becomes much easier to record one dynamically than to manually record all the individual keys.
In this summary, I wrote myself the most important bits:
;;;; * Keyboard macros ;; Cx ( or F3 Begin recording. ;; F3 Insert counter (if recording has already commenced). ;; Cu <n> Cx ( or F3 Begin recording with an initial counter value <n>. ;; Cx ) or F4 End recording. ;; Cu <n> Cx ) or F4 End recording, then execute the macro <n>-1 times. ;; Cx e or F4 Execute the last recorded keyboard macro. ;; e or F4 Additional e or F4 presses repeat the macro. ;; Cu <n> Cx e or F4 Execute the last recorded keyboard macro <n> times. ;; Cx Ck r Apply the last macro to each line of the region. ;; Cx Ck e Edit a keyboard macro (RET for most recent). ;; Cx Ck b Set a key-binding. ;; ;; If you find yourself using lots of macros, you can even name them ;; for later use, and save them to your init file. ;; Mx name-last-kbd-macro RET (name) RET ;; Mx insert-kbd-macro RET (name) RET ;; ;; For more documentation: ;; Ch k Cx ( ;; M-: (info "(emacs) Keyboard Macros") RET
If we play with an example from the question, you will see how some of these things come together ...
First you can define a macro with F3 Cu 2 Cx } F4
Then you can temporarily bind it to F1 using Cx Ck b F1 (in fact, this is not the case if F1 is currently the prefix key for the existing keyboard layout, as entering it online will just prompt for the remainder. You can get around this in the code using (global-set-key (kbd "<f1>") ...) , but I suggest sticking with reserved bindings ).
If you then use describe-key ( Ch k ) to check what is associated with this key, Emacs will show you an expression (lambda) that you could copy into your initialization file if you want.
Alternatively, you can name the macro and ask Emacs to paste the code into the current buffer:
Mx name-last-kbd-macro RET (name) RET
Mx insert-kbd-macro RET RET
This code will be different from the lambda expression shown by describe-key , but if you evaluate the inserted macro, you will see equivalence. You can also show that the expression (kbd "...") also evaluates the same value, and so these are just alternative ways to do the same.
(You can use the * scratch * buffer to evaluate the code by moving the point after the end of the expression, and either typing Cx Ce to show the value in the minibuffer, or Cj to paste the value into the buffer).
Note that the βpastedβ code uses fset to assign a character to the macro. You can bind a macro to a key by executing (fset) and then assigning that character to a keyword using (global-set-key) , or you can ignore (fset) and simply assign the macro value directly. This, of course, is directly equivalent to the answer to the Angus.
Edit: I just noticed that the kmacro-name-last-macro function is associated with Cx Ck n , which is almost identical in name-last-kbd-macro form, but which generates a lambda expression form that is visible when using kmacro-bind-to-key ( Cx Ck b ) and describe-key .