Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a dynamic touch to emacs macros and or query replaces?

Tags:

emacs

lisp

elisp

I often find myself needing to do several query and replace operations in a row because, for example I want to change all occurences of 23 to 24 in a line, then 24 to 25 in the next line, and so on (usually because i write an expression in a line which I yank multiple times in subsequent lines and need to slightly modify)...

A macro with C-x q or a regular doing multiple query replace doesn't seem powerful enough in situations like these..is there something more general/flexible to handle variable replaces or variable macro variations like this that I can look into? I belive I had once come across an example on the web where lisp expressions were introduced into certain commands to be more powerful but I can't remember this or where I read about it..

like image 432
Palace Chan Avatar asked Apr 30 '12 17:04

Palace Chan


2 Answers

I'm not sure this completely answers your question, but I've found registers to be a useful tool for building powerful macros. The most important functions are:

  • C-x r n number-to-register copy the number at the point into a register
  • C-x r + increment-register increments the value stored in a register
  • C-x r i insert-register inserts the value of the register into the buffer

Using these functions, you could solve the problem of replacing incrementing numbers on each line with:

  • seed the first number into a register with number-to-register
  • start macro definition
  • select a line
  • replace-string, insert-register, increment-register, insert-register
  • move to the beginning of the next line
  • end macro definition

There is more information on registers in the emacs manual: https://www.gnu.org/software/emacs/manual/html_node/emacs/Registers.html

like image 105
ataylor Avatar answered Oct 24 '22 11:10

ataylor


As well as neat uses of existing commands, such as the one shown by ataylor, keyboard macros can be used to perform almost arbitrarily-complex and dynamic behaviours.

Of particular note, C-uM-: will insert into the current buffer the result of any elisp form you enter -- a form which can, of course, be constructed as part of the macro -- so even when no command exists for a particular operation, you are unlikely to be prevented from using macros to achieve your goals.

(And of course if elisp isn't the answer, C-uM-! and C-uM-| give you easy access to incorporating shell command output as well.)

Naturally there are cases where a more targeted solution is available and a macro is more trouble than it is worth (the "search and replace with elisp evaluation" technique linked to in the comments is also incredibly powerful, and often the ideal solution); however keyboard macros also offer an amazing amount of power for incredibly little effort, and can do some things with ease that you might struggle to implement otherwise.

One of my favourite examples is using "old -> new" mapping data in one buffer (in virtually any format imaginable) and using that to perform a search-and-replace on those values in another buffer. The speed with which you can do this kind of thing on an ad-hoc basis with nothing more than simple movement and editing keystrokes is amazing.

The macro editor also makes it easy to tweak your macro if it is not correct the first time, without the need to re-record all the steps.

I read some useful advice one time, which was simply to try to always think about whether you could achieve a task with keyboard macros whenever you encountered something non-trivial. The more you use them, the more you realise different ways in which you can use them, and soon you have a new indispensable tool in your toolbox.

like image 31
phils Avatar answered Oct 24 '22 11:10

phils