Emacs -- Enhanced Features

Jesper Kjær Pedersen <blackie@imada.ou.dk>



Abstract

In this article I will describe some of the enhanced features of emacs. I will NOT start a flame war with people who use other editors (choice of editor is really religious). I won't just reiterate the manual either. The info pages on emacs is very comprehensive, and one should refer to these for more information. What I will do, is describe some of the features of emacs that I find very useful. And in the second part of this article, I will give some 2 cent tips. You are encouraged to have emacs at hand, when you read this article, since everything will be introduced with examples.


Enhanced Features

Modes

Of course... Major modes for many different languages. With these, emacs knows of the language you are editing, ie. latex (auc-tex), C (c-mode) or html (html-helper-mode). Furthermore, emacs knows how to interact with ispell, so it is very easy to spell check you files, Just type on of the following: ispell-word, ispell-region or ispell-buffer.

This is VERY useful, but if you know emacs just a little you already know that!

outline-minor-mode

This mode will let you get an overview of a file much easier than normal. Here's an example. Please find your largest C program, or pick one from a program, you compiled on your system, and load it into your emacs. Ok now where is this function called XX, I know it's here, but my files is 10,000 lines long...

Well type: M-x outline-minor-mode, and after that press M-x hide-other. If you've done that right, the only thing you can see is the function headings. Don't fear, your function bodies aren't gone, they have just been hidden, so you can get an overview. Now try to move the cursor to one of the function headings, and press M-x show-subtree. Now you can see the body of that function. That's basically that! It can, of course, do a lot more, which involves expanding only one level at a time. I personally don't use that, since it's almost always enough for me, just to expand/collapse a whole function, instead of the body of a for loop etc.

Please note that the function is bound to keys, but I don't use them in the above, since it seems to me that the key has changed from emacs version 19.28 to 19.30. In version 19.30 I believe they are bound to C-c @ C-o for hide-other, and C-c @ C-s for show subtree. To find out what combination is used in your emacs, just type C-h w hide-other etc.

To change the default prefix (from C-c @ in the example above) to something else, insert something like this into your .emacs:

(setq outline-minor-mode-prefix "\C-o")
This will give the prefix C-o instead (but first you have to ask your self: do you ever use open-line, which C-o is bound to, well do you, punk?

To start a new C file up into minor-mode, and with all function collapse, you can insert the following into your .emacs:

(add-hook 'c-mode-hook
	  (function (lambda ()
		      (outline-minor-mode)
		      (hide-other)
		      )))
NOTE: outline-minor-modes works with other modes too, though it's most useful in modes which involves programming languages.

WATCH OUT! if you delete the three dots after the function heading, you actually delete the whole body of the function, so this is a caveat, you have to watch out for all the time, when you use outline-minor-mode.

TAGS

When you program, you'll often find your self searching all the files in your program, for a particular function, or for a given pattern, right?!

Well, if you have, you should really try to use TAGS. Tags is a table of keywords and files, which emacs uses to find it's way around in your files.

Try to go to a directory with a lot of C files, and type etags *.c *.h in your shell, and after that go to your emacs, and open one of the files in this directory. Move the cursor to a function apply (use of a function), and press M-., and after that Return. Now emacs will move to the location, where the function has been defined. Nice hah?

Ok now we want to find out where in the h.., the program prints, "Goodbye", so type M-x tags-search, and press enter, and type printf. If this pattern exists anywhere in your program, emacs will move to the first location, and if you press M-, afterwards, it will move to the next occurrences.

Finally, you found out that in C, you print out with the command printf, and NOT puts, like you are used to in Tcl/Tk. This is simple to change with tags. Type M-x tags-query-replace, then hit return, and type puts(, when it ask for a regular expression to search for, and type printf(, when it ask for an expression to replace with, and now you've started. Emacs will place the cursor at the first occurrences, and ask you what to do.

Aha, you saw the magic word right: regular expression. Ok now you've found out that you print out with printf(...) instead of puts<abc>, and wants emacs to correct this little problem. Ok here we go: M-x tags-query-replace, type puts<\(.*\)> to the question about what to search for, and printf(\1) to the question about what to replace with.

OK what is this all about? The \( \) tells emacs to group every thing in between, and .* tells emacs to match anything, \& finally tells emacs to inserts the first match. Ie. the one within \( and \).

Complicated? well then I believe you have to learn a bit more about regular expression, so turn up for info, by pressing C-h i, now move to the line which says:

* Emacs: (emacs). The extensible self-documenting text editor.

Press enter with the cursor on this line, and move to the line which says:

* Regexps:: Syntax of regular expressions.

Here you are, read about regular expression, and when you are though with this page, press next on the top of the page, twice, and you can from there read, how you replace with regular expressions.

Bookmarks

Bookmarks is, as the word says, a list of locations in different files. Well actually files can be anything emacs can show, eg. a dired buffer, and info page, a ftp location, or just an ordanary file. Here is how you do: go to the location, where you want to leave a bookmark, and press C-x r m, and type a good name for the location. Now you've created a bookmark, and can go to that specific location when ever you want, if the location still exists. Here is a few examples:

Press C-h C-f bookmark-set, which will take you to the info page which describe bookmarks. Here you can read about bookmarks. Well I believe this is a good location for a bookmark, so press C-x r m, and give it an appropriate name

If you are on Internet, open this file, like any other /ftp@ftp.denet.dk:/pub/OS/Linux/slackware/, and now you are in Denmark, in their mirror of the slackware distribution. Press C-x r m, to set a bookmark there.

Finally open your own .emacs file, goto line 15, and press C-x r m.

If you now wants to go to one of the locations, you can press C-x r l, and see a list of all the bookmarks. (press ? on this page to see what you can do from here). Another way to go to a specific bookmark is to press C-x r b, and the name of the bookmark you want to go to. (press the tab-key to see a list, or complete the characters you've typed)

NOTE: When you jump to a bookmark, you will be positioned on the correct line, if possible!

Comparing files with ediff

If you have to compare two files, then use emacs instead of just an ordinary diff: Start up emacs, and type M-x ediff-files, when you've told emacs which files to diff, they will appear in each their frames. A third frame will come up in a window for itself. From this window you control the diff session. Now you can type n to go to the first diff, and emacs will highlight the diff in the two buffers. Another n, will take you to the next diff, and so on. As you can see, when you start ediff: Just type ? to get an overview of commands.

Binding macros to keys, and saving them to your .emacs

In the following I will show you have you can bind a keyboard macro to a key, and how you can save this (the easy way) to your .emacs file.

First you have to define the keyboard macro. PressC-x (, then press the key sequence which is your macro, and end it with C-x ). Now the macro is defined, and can be executed by pressing C-x e.

Now find a good name for the macro, and press M-x name-last-kbd-macro and follow that with the name you've chosen for that macro. Now you've given the macro a name

The next thing to do is to assign the macro to a key, which you do by pressing M-x global-set-key, press the key you want your macro to be assigned to, and type the name of your macro. Now the macro will be runed every time you press this key.

Finally you have to save this into your .emacs file, so the macro will be defined the next time you start up emacs. This is done by opening your .emacs file, moving the cursor to where you want the definition, and pressing C-1 M-x insert-kbd-macro, and typing the name of your macro. Now the definition, and the key binding is in your .emacs file. I admit that the code isn't very beautiful, but it works, and you don't have to learn any elisp.

2 cent tips

Which key bindings exists in mode XX ?

To see which key bindings exists for a particular mode, try pressing C-c C-h. Almost all key bindings for different major modes start with the prefix C-c. So if you press C-c C-h, emacs will show you which possible completions exists for C-c.

How to do the same thing 10 times

Have you ever tried to insert the same text on ten lines, on the third position?, or something like that? Well search-and-replace doesn't apply here, so you have to do it manually...Wrong, use macro's!

Here's how you do. Press C-x (, which will start the definition of a macro. Do what you have to do, for one line, and move to the same position on the next line, and the press C-x ). Now you have defined your macro, and can apply it one line at time, just press C-x e, that many times, which is necessary. Even better: if you have to do this a 1000 times, it gets quite boring, so just press the escape button, and type the number of times, you want the macro repeated, and after that press C-x e, and there you go 1000 times.

Help when programming elisp

You may have noticed that your .emacs file is written in a language different from what you are used to. This language is called Lisp, and is extended with editor commands, to become Emacs Lisp, or short just elisp.

When you've started to play around with emacs, you may start to ask your self: Can emacs to just this thing for me, and the answers is YES. Emacs can do almost every thing (It can't make coffee..YET), so the question is just how. To answer this question, you have a very important tool: the info pages on elisp. When you've started to play around with elisp, you will suddenly find your self with one of the elisp functions, wanting to know what exactly it does. This is quiet easy, just type C-h C-f, and emacs will go right to the info page for that particular function.

Equally you might want to see an info page for a specific command sequence, eg what does C-u? Press C-h C-k C-u

Splitting / Byte compile you .emacs

As you go on, learning more about emacs, and configuring different part of it, (ie. defining macro's), your .emacs file will grow very fast, and become very difficult to maintain, to avoid this caveat, you may split your .emacs file into several files, like this:

in your original .emacs, called ~/.emacs, insert the following text:

(load-file "~/.emacs-lib/general.elc")
(load-file "~/.emacs-lib/macores.elc")
(load-file "~/.emacs-lib/functions.elc")
(load-file "~/.emacs-lib/dotfile.elc")
Now everything is split over several files:
~/.emacs-lib/general.el
This file might contain things from the original .emacs files
~/.emacs-lib/macores.el
This file may contain all the keyboard macro's you define (See above
~/.emacs-lib/functions.el
This file may contain the elisp function you have defined
~/.emacs-lib/dotfile.el
If you use The Dotfile Generator to configure emacs, you can tell it to save it's output into this file
NOTE: If the source file is called blahblah.el, in your .emacs you load the byte compiled version which is called blahblah.elc! Note the change in suffix.

As you can see, the files have to be byte compiled (for optimization purpose).That can be done automaticly, just insert the following code into all your emacs files, which have to be byte compiled:

;;; Local Variables:
;;; eval: (defun byte-compile-this-file () (write-region (point-min) (point-max) buffer-file-name nil 't) (byte-compile-file buffer-file-name) nil)
;;; write-file-hooks: (byte-compile-this-file)
;;; End:
Insert it as is, and emacs will byte compile the file, when you save it. NOTE: you have to exit the buffer and reopen it, before this takes effect the first time.

How did it do that?

You know this situation: You've played around with emacs, or just smashed your keyboard, and sudanly it did something you've been searching for, for month, try pressing C-h l, this will show you the last 100 characters you've typed.

A short break for advertisement

Well admitingly, I've played around with emacs for quiet a while, and this led me to the idea to create a tool, which gave the basic user the possibility to configure lots of things in emacs, without having to know a lot about elisp, or even the basic syntax of the .emacs file.

My boss thought this was a good idea, and I started programming. And almost half a year later I came up with a tool called The Dotfile Generator. It not only could configure emacs, but was a more general configuration tool, with modules for Emacs, Tcsh (the shell), and Fvwm (the Window manager) (this module is written by Jeppe Buk)

If you are new to emacs, or just have concluded, that emacs is very configurable, then you should out my program, Here's a link to it.


Jesper Kjær Pedersen <blackie@imada.ou.dk>
Last modified: Mon Feb 26 00:01:50 1996

Back up to the Linux Gazette!