While it’s nice to have a function key to bring up an IDE so that we can automate our applications, we see that Emacs goes even further by allowing code to be edited and run from any window. There is no special, separate application that is used for extending or modifying the program. This is strange and unusual– and very fun. This short tutorial will show how to use one of Emacs’ most versatile commands, how to retrieve the code for executing complex commands, how to put them into function definitions, and how to attach them to hot-keys. (This more comprehensive introduction is very good if you need extra information.)
A basic out-of-the-box feature of Emacs is the C-M-% query-replace-regexp command. You can use this to search and replace patterns of text. I try to explain this to people and it doesn’t quite register: they think, “oh yeah, I’ve got find/replace built into my IDE, what are you talking about?!” (Evidently, you can get a Master’s degree in Computer Science and not know what a regular expression is….) I’m not talking about searching and replacing not just specific strings, but patterns as well.
Suppose you have inherited a project that has lots of data hard coded into visual basic files. You might have something that looks like this:
strOptions = “OptionOne, OptionTwo, OptionThree,”
strOptions = strOptions & “OptionFour,” ‘ Don’t forget this one!
strOptions = strOptions & “OptionFive, OptionSix”
How can we get rid of all the code and get ourselves a nice simple list of options?
What we first want to do is search for lines that have a series of upper and lowercase letters, equal signs, and/or ampersands… followed by upper and lower case letters and commas inside a pair of double quotes… followed, perhaps, by a code comment. We could search for that specific pattern of text and then replace it with just the stuff that’s inside the double quotes.
To do that, just use C-M-% to search for this:
[A-Za-z=& ]*”/([A-Za-z ,]*/)”[' A-Za-z!.,()@#$%^&*]*
And replace it with this:
The [A-Za-z=& ]* part represents the first part of the pattern. The double quotes represent (surprise!) double quotes. The [A-Za-z ,]* represents the stuff inside the double quotes. The /( and /) markers are used to tag regions of text so that we can refer to them later. The [' A-Za-z!.,()@#$%^&*]* represents the comment. The /1 is a reference back to the text that was between the double quotes.
After we apply query-replace-regexp with these two arguments, we should end up with this:
OptionOne, OptionTwo, OptionThree,
(Note that to apply the replace to a section of highlighted text, press the space bar. To apply it to every line after the cursor, press the “!” key. Note that the search begins at the place that the cursor is….)
To get rid of the commas and get a nice simple list of options, we’ll need to know a little Emacs trick. To enter a carriage return as part of an argument to a command like query-replace-regexp, you need to hit C-q C-j. (I’ll use a ~ character to denote that key chord.) So to remove the commas and line up our options we, search for:
And replace it with “nothing.” (Just hit enter when prompted for what to replace it with.) Running the command should produce the following:
Now… you may want to reuse these sorts of commands that have complex arguments… or you may want to be able to save and modify them some more when you find out they don’t work quite like you want them to. To see these commands as Emacs sees them, hit C-x esc esc. This will display in the mini-buffer the last complex command you’ve entered. You can then hit enter to rerun it or cut and paste it to somewhere else.
The skeleton below shows a basic outline for an elisp function. You can paste complex command “stolen” with C-x esc esc into the place marked <<<PUT YOUR CODE HERE>>>:
(defun your-function (n)
“Put your function’s documentation here”
(interactive “p”) ; n = value passed by the C-u “universal argument”
<<<PUT YOUR CODE HERE>>>)
The “interactive p” part means that the command can be run with from the mini-buffer by typing M-x, entering the name of the function, and then hitting “enter”. For that to work, though, you must first get the function into the environment. You can do this by moving the cursor just to the right of the very last parenthesis in your function definition. From there hit C-x C-e. The name of your function should appear in the mini-buffer when you do this. In fact, you can evaluate any lisp expression that way. Type “(+ 30 12)” and hit C-x C-e after the final parentheses and you should see “42” appear in the mini-buffer!
To wire in a hot-key, evaluate a function like this:
(global-set-key [f8 ‘your-function)
You can collect your code into a text file marked “.el”. Files with that extender will be highlighted properly when you load them into the editor. To execute all of the code in a file, type M-x load-file and then enter the path and/or filename of the code you want running in your environment. Here’s an example file with the code from our tutorial set to run with the function keys f3 and f4.
With regular expressions and the above commands, you can automate just about any complicated text manipulation. In some cases, it can take a while to figure out a good regex to solve a problem, but that’s generally more fun than editing loads of text files by hand.