Automation

Author

Marie-Hélène Burle

A good text editor should make your work easier and more efficient. At the core of efficiency is automation which can be achieved by various techniques such as powerful search and replace, usage of regular expressions, definition of functions, or keyboard macros.

Search and replace

Open a new file (you can call it exercise if you want).

Remember that one option is to launch Emacs (or emacsclient if you have an Emacs server running), then find a new file with C-x C-f. Another option is to launch Emacs (or emacsclient) directly with a new file open (with emacs exercise or emacsclient exercise).

Now, yank (C-y) the following text in it:

This is a list:

- Item one
- Item two
- Item three
- Item four
- Item five
- Item six
- Item seven
- Item eight
- Item nine
- Item ten

We want to turn this list into a different style, with each item in lower case and a coma at the end.

In this particular example, because all items start with the same word, we can use a search and replace method.

  • first, go to the start of the buffer (with M-<),
  • then use the query-replace command. You can access it with M-x query-replace or with the kbd M-%,
  • now, enter what you want to look for (“Item”) and press RET (the <return> key labelled “Enter” on your keyboard),
  • finally type what you want to replace the query by (“item”) and press RET again.

Emacs tells you that you can press ? for help. If you do so, you will see how to navigate the search and replace interface. Here are the most important kbds to remember:

SPC to replace one match
n to skip to next match
RET to exit
! to replace all remaining matches in this buffer

Since we want to replace all instances, we can press !.

Now, for the addition of comas at the end of items:

  • move back to the top of the buffer again,
  • launch another query-replace,
  • for the query, type C-q C-j then `RET,
  • for the replacement, type , C-q C-j and RET.

C-q is a way to quote the next character, in effect entering it in the search query rather than applying its effect. C-j inserts a new line (what we want since we want to add , before new lines), but if pressed unquoted, it has the same effect as pressing RET, which would move the query-replace questions along—not what we want.

Try pressing C-j to see that it will insert a new line in your buffer.

Now, we don’t want to add , at the end of the first or second lines, so press n (for “no”) twice. Then you can either press the space bar until the end of the list or press ! to replace the remaining matches.

Search and replace with regexp

Let’s consider a different list. Copy it, go back to your buffer, press C-x h to select all its content, press DEL (backspace key) to erase the highlighted region, then yank what you had copied below with C-y.

This is a list:

- First item
- Second item
- Third item
- Fourth item
- Fifth item
- Sixth item
- Seventh item
- Eighth item
- Ninth item
- Tenth item

In this case, we can’t replace the first item with its lower case version with a simple search and replace. We can however do it using a regular expression:

  • go to the top of the buffer,
  • enter the command query-replace-regexp or C-M-%,
  • for the query entry type: - \(.\),
  • and for the replacement entry type: - \,(downcase \1).

What we are doing here is to replace the first character after “-” (which we place in a group) with “-” followed by its lower case version. \, enables us to use an Elisp expression as part of the transformation. The Elisp expression is between parenthesis and uses the command downcase. \1 replaces the grouped expression.

If you have never used regular expression, I recommend having a look at this site which covers the topic in a very clear fashion. For Emacs specific regexps, you can find information in the manual.

For the end of line coma, we can replace the regexp $ with ,.

Your turn:

Try this yourself.

Keyboard macros

What are keyboard macros?

Keyboard macros are recordings of key presses. They are extremely convenient because they allow to automate any task, on the fly, without having to define functions or use complex regular expressions.

This is how it works:

  • you initiate the recording with C-x ( or <f3>,
  • then you do whatever task you wish to repeat,
  • finally you end the recording with C-x ) or <f4>.

Now, to repeat the task you recorded, you just have to press C-x e or <f4>.

You can use the macro any number of times, either in succession or at any later time in your editing session. You can apply them on any buffer and you can apply them multiple times in a row with the usual repeat kbds (e.g. C-u 10 <f4>).

Naming macros

If you define a new macro, it will replace the previously recorded one. If you want to use multiple macros at the same time, you can give them names using M-x name-last-kbd-macro. That way, there is no limit in how many you have access to simultaneously. To access any of these macros, call with as you would a command with M-x.

Saving macros

If you want to save named macros for future sessions, you can add them to your init file by running M-x insert-kbd-macro.

You can even give them a kbd with (global-set-key (kbd "<your kbd>") '<your macro>).

Your turn:

Go back to your buffer, undo the changes with C-/ until the comas are gone and the items are capitalized again, then try using a keyboard macro to re-edit it efficiently.