Emacs is so big, and so complex, that it actually has its own programming language! I'm not kidding: to really customize Emacs to suit your needs, you have to write programs in this language. It's called Emacs Lisp, and it's a dialect of Lisp, so if you have previous experience in Lisp, it will seem quite friendly. If not, don't worry: I'm not going to go into a great deal of depth, because it's definitely best learned by doing. To really learn about programming Emacs, you should consult the Info pages on Emacs Lisp, and read a lot of Emacs Lisp source code.
Most of Emacs's functionality is defined in files of Emacs Lisp code. Most of these files are distributed with Emacs and collectively are known as the ``Emacs Lisp library''. This library's location depends on how Emacs was installed on your system -- common locations are /usr/lib/emacs/lisp, /usr/lib/emacs/19.19/lisp/, etc. The ``19.19'' is the version number of Emacs, and might be different on your system.
You don't need to poke around your filesystem looking for the lisp library, because Emacs has the information stored internally, in a variable called load-path. To find out the value of this variable, it is necessary to evaluate it; that is, to have Emacs's lisp interpreter get its value. There is a special mode for evaluating Lisp expressions in Emacs, called lisp-interaction-mode. Usually, there is a buffer called `` *scratch*'' that is already in this mode. If you can't find one, create a new buffer of any name, and type M-x lisp-interaction-mode inside it.
Now you have a workspace for interacting with the Emacs Lisp interpreter. Type this:
and then press C-j at the end of it. In lisp-interaction-mode, C-j is bound to eval-print-last-sexp. An ``sexp'' is an `` s-expression'', which means a balanced group of parentheses, including none. Well, that's simplifying it a little, but you'll get a feel for what they are as you work with Emacs Lisp. Anyway, evaluating load-path should get you something like this:
It won't look the same on every system, of course, since it is dependant on how Emacs was installed. The above example comes from my 386 PC running Linux. As the above indicates, load-path is a list of strings. Each string names a directory that might contain Emacs Lisp files. When Emacs needs to load a file of Lisp code, it goes looking for it in each of these directories, in order. If a directory is named but does not actually exist on the filesystem, Emacs just ignores it.
When Emacs starts up, it automatically tries to load the file .emacs in your home directory. Therefore, if you want to make personal customizations to Emacs, you should put them in .emacs. The most common customizations are keybindings, so here's how to do them:
global-set-key is a function of two arguments: the key
to be bound, and the function to bind it to. The word ``
global'' means that this keybinding will be in effect in all major
modes (there is another function, local-set-key, that binds a
key in a single buffer). Above, I have bound C-c l to the
function goto-line. The key is described using a string. The
special syntax ``
\C-<char>'' means the
key held down while the key <char> is pressed. Likewise, ``
\M-<char>'' indicates the key.
All very well, but how did I know that the function's name was ``goto-line''? I may know that I want to bind C-c l to some function that prompts for a line number and then moves the cursor to that line, but how did I find out that function's name?
This is where Emacs's online help facilities come in. Once you have decided what kind of function you are looking for, you can use Emacs to track down its exact name. Here's one quick and dirty way to do it: since Emacs gives completion on function names, just type C-h f (which is describe-function, remember), and then hit without typing anything. This asks Emacs to do completion on the empty string -- in other words, the completion will match every single function! It may take a moment to build the completion list, since Emacs has so many internal functions, but it will display as much of it as fits on the screen when it's ready.
At that point, hit C-g to quit out of describe-function. There will be a buffer called `` *Completions*'', which contains the completion list you just generated. Switch to that buffer. Now you can use C-s, isearch, to search for likely functions. For example, it's a safe assumption that a function which prompts for a line number and then goes to that line will contain the string ``line'' in its name. Therefore, just start searching for the string ``line'', and you'll find what you're looking for eventually.
If you want another method, you can use C-h a, command-apropos, to show all functions whose names match the given string. The output of command-apropos is a little harder to sort through than just searching a completion list, in my opinion, but you may find that you feel differently. Try both methods and see what you think.
There is always the possibility that Emacs does not have any predefined function to do what you're looking for. In this situation, you have to write the function yourself. I'm not going to talk about how to do that -- you should look at the Emacs Lisp library for examples of function definitions, and read the Info pages on Emacs Lisp. If you happen to know a local Emacs guru, ask her how to do it. Defining your own Emacs functions is not a big deal -- to give you an idea, I have written 131 of them in the last year or so. It takes a little practice, but the learning curve is not steep at all.
Another thing people often do in their .emacs is set certain variables to preferred values. For example, put this in your .emacs and then start up a new Emacs:
Emacs checks the value of the variable inhibit-startup-message to decide whether or not to display certain information about version and lack of warranty when it starts up. The Lisp expression above uses the command setq to set that variable to the value `t', which is a special Lisp value that means true. The opposite of `t' is `nil', which is the designated false value in Emacs Lisp. Here are two things that are in my .emacs that you might find useful:
The first expression causes searches (including isearch) to be case-insensitive; that is, the search will match upper- or lower-case versions of a character even though the search string contains only the lower-case version. The second expression sets the default indentation for C language statements to be a little smaller than it is normally -- this is just a personal preference; I find that it makes C code more readable.
The comment character in Lisp is ``;''. Emacs ignores anything following one, unless it appears inside a literal string, like so:
It's a good idea to comment your changes to Lisp files, because six months later you will have no memory of what you were thinking when you modified them. If the comment appears on a line by itself, precede it with two semicolons. This aids Emacs in indenting Lisp files correctly.
You can find out about internal Emacs variables the same ways you find out about functions. Use C-h v, describe-variable to make a completion list, or use C-h C-a, apropos. Apropos differs from C-h a, command-apropos, in that it shows functions and variables instead of just functions.
The default extension for Emacs Lisp files is ``.el'', as in ``c-mode.el''. However, to make Lisp code run faster, Emacs allows it to be byte-compiled, and these files of compiled Lisp code end in ``.elc'' instead of ``.el''. The exception to this is your .emacs file, which does not need the .el extension because Emacs knows to search for it on startup.
To load a file of Lisp code interactively, use the command M-x load-file. It will prompt you for the name of the file. To load Lisp files from inside other Lisp files, do this:
Emacs will first add the .elc extension to the filename and try to find it somewhere in the load-path. If it fails, it tries it with the .el extension; failing that, it uses the literal string as passed to load. You can byte-compile a file with the command M-x byte-compile-file, but if you modify the file often, it's probably not worth it. You should never byte-compile your .emacs, though, nor even give it a .el extension.
After your .emacs has been loaded, Emacs searches for a file named default.el to load. Usually it's located in a directory in load-path called site-lisp or local-elisp or something (see the example load-path I gave a while ago). People who maintain Emacs on multi-user systems use default.el to make changes that will affect everyone's Emacs, since everybody's Emacs loads it after their personal .emacs. Default.el should not be byte-compiled either, since it tends to be modified fairly often.
If a person's .emacs contains any errors, Emacs will not attempt to load default.el, but instead will just stop, flashing a message saying ``Error in init file.'' or something. If you see this message, there's probably something wrong with your .emacs.
There is one more kind of expression that often goes in a .emacs. The Emacs Lisp library sometimes offers multiple packages for doing the same thing in different ways. This means that you have to specify which one you want to use (or you'll get the default package, which is not always the best one for all purposes). One area in which this happens is Emacs's Scheme interaction features. There are two different Scheme interfaces distributed with Emacs (in version 19 at least): xscheme and cmuscheme.
I happen to like the interface offered by cmuscheme much better than that offered by xscheme, but the one Emacs will use by default is xscheme. How can I cause Emacs to act in accordance with my preference? I put this in my .emacs:
The function autoload takes the name of a function (quoted with ``''', for reasons having to do with how Lisp works) and tells Emacs that this function is defined in a certain file. The file is the second argument, a string (without the `` .el'' or ``.elc'' extension) indicating the name of the file to search for in the load-path.
The remaining arguments are optional, but necessary in this case: the third argument is a documentation string for the function, so that if you call describe-function on it, you get some useful information. The fourth argument tells Emacs that this autoloadable function can be called interactively (that is, by using M-x). This is very important in this case, because one should be able to type M-x run-scheme to start a scheme process running under Emacs.
Now that run-scheme has been defined as an autoloadable function, what happens when I type M-x run-scheme? Emacs looks at the function run-scheme, sees that it's set to be autoloaded, and loads the file named by the autoload (in this case, `` cmuscheme''). The byte-compiled file cmuscheme.elc exists, so Emacs will load that. That file must define the function run-scheme, or there will be an autoload error. Luckily, it does define run-scheme, so everything goes smoothly, and I get my preferred Scheme interface.
An autoload is a like a promise to Emacs that, when the time comes, it can find the specified function in the file you tell it to look in. In return, you get some control over what gets loaded. Also, autoloads help cut down on Emacs's size in memory, by not loading certain features until they are asked for. Many commands are not really defined as functions when Emacs starts up. Rather, they are simply set to autoload from a certain file. If you never invoke the command, it never gets loaded. This space saving is actually vital to the functioning of Emacs: if it loaded every available file in the Lisp library, Emacs would take twenty minutes just to start up, and once it was done, it might occupy most of the available memory on your machine. Don't worry, you don't have to set all these autoloads in your .emacs; they were taken care of when Emacs was built.