Once in a while I show my Emacs configuration file (.emacs
) to
a friend and there is always something that they didn't know or for
which they have a better solution. So I thought I would go through my
.emacs
and extract the most useful, general parts of it to share
them with you. This should be an interesting read even if you don't use
Emacs, as you may want to try to apply them to your own favorite editor.
Or maybe you have a more elegant solution?
Each time you add something to your .emacs
I advise you to add a comment.
Explain what the piece of code does and where you got it from. It will prove
useful a few years from now when you want to clean up or update.
Let's start with the basics:
(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
This disables the tool bar, the menu bar and all scroll bars. This gives more space for what is actually important: editing.
Now, you may ask: but how can I use my editor without those bars? Well, this assumes that you are familiar with your key bindings. Once you are, not only will you work faster but you will also not need buttons to replace them, so the tool and menu bars become nothing but a waste of space. Regarding the scroll bars, the position in the file is actually indicated as a percentage below each buffer, so you don't need them either.
You may restore those bars temporarily by typing M-x tool-bar-mode
for instance. This can be useful if you forget a key binding,
or if you want to browse features which are provided by a mode you
do not use often.
ido-mode
Activate ido-mode
:
(ido-mode t)
This improves buffer switching (using C-x b
) and file loading (using
C-x C-f
). The default Emacs behavior (without ido-mode
) has you
type the whole buffer or file name. It has auto-completion, but it
assumes that what you typed is a prefix of what you are searching for,
and it is case-sensitive. So if you want to select "README.txt" you cannot
type "read" then auto-complete. Also, you have to press the Tab
key
twice to get a list of possibilities.
However with ido-mode
the list of possibilities is always visible
and reduces as you type. It reduces to all names which contain what
you typed. For instance, if you type "me" it will show "README.txt",
as well as "memo.txt" or "Camera". It has auto-completion and always shows,
in brackets, what auto-completion will add if you press Tab
.
Last but not least, you can press C-s
and C-r
to select the next or
the previous name for the proposed list.
For instance, let's say you have the following list of files:
lib_main.ml
lib_main.mli
lib_misc.ml
lib_misc.mli
lib_heap.ml
lib_heap.mli
If you type .mli
the list will only contain the three .mli
files
and you can then select the one you want using C-s
.
Or, if you want to load lib_misc.ml
, instead of having to type
lib_mi
before being able to autocomplete, just type mi
and the
list will be reduced to lib_misc.ml
and lib_misc.mli
.
If the one which is currently selected is not the one you want,
press C-s RET
. Else, just press RET
.
You may also type Tab
and it will auto-complete to
the longest common prefix which is lib_misc.ml
,
leaving you the choice to type the i
or not.
Before, to compile I used to go to a terminal and type make
.
I was taught to compile from Emacs, which is much better as jumping to
errors is then painless.
(global-set-key [f5] 'compile)
(global-set-key [(meta f5)] 'kill-compilation)
(global-set-key [f6] 'recompile)
(global-set-key [f7] 'next-error)
I press F5
to compile, which prompts for a command to run, like make
(default is make -k
). If compilation takes forever or freezes, I can
stop it easily with M-F5
. To run the same compilation again, I press
F6
. And if compilation fails with an error, F7
will move the cursor
to where the error is located.
(global-set-key [f9] 'comment-region)
(global-set-key [f10] 'uncomment-region)
Commenting and uncommenting code is a very easy task if you can just do
it by pressing F9
or F10
. This comments line by line, like this:
(* Line 1 *)
(* Line 2 *)
(* Line 3 *)
This makes it easy to uncomment only part of what you commented, to toggle parts of your code for instance.
My .emacs
contain several personal key-bindings. No user will probably
want the same set, but knowing how to bind a key is very useful,
as well as being aware of the kind of commands that exist.
Let me show you some examples from my .emacs
.
(global-set-key [f2] 'switch-to-buffer)
(global-set-key [f3] 'find-file)
F2
now does the same as C-x b
(switch to another buffer), and F3
now does the same as C-x C-f
(load file). I run those commands all
the time, so having to perform three kind of convoluted keystrokes is
absurd. Function keys make it much simpler, especially in combination
with ido-mode
(see above). Also, function keys work for all keyboard
layouts.
(global-set-key [f1] 'other-window)
F1
now does the same as C-x o
(select other window). Once again
this is something which you use all the time if you split your Emacs
using e.g. C-x 2
. Note that F1
is normally bound to help
.
(global-set-key [f4] 'kill-buffer)
Being able to close the current buffer easily saves time.
(global-set-key [(meta g)] 'goto-line)
Sometimes I want to go to a specific line number, and I just type M-g
.
This is less useful if you compile from within Emacs though.
(global-set-key [(meta f7)] 'ispell-region)
Check for spelling errors by typing M-F7
. Maybe I should add a binding
to switch language...
(global-set-key [f8] 'revert-buffer)
Sometimes the file I'm currently editing has changed on disk.
Or, I want to discard unsaved changes. I can revert
the buffer by pressing F8
. It will prompt for confirmation.
(global-set-key (kbd "<M-down>") 'scroll-up-line)
(global-set-key (kbd "<M-up>") 'scroll-down-line)
I may scroll up or down using M-down
or M-up
. The point is that
the cursor stays in the same position in the buffer. This is
convenient to have a peek at what is above or below the currently
visible part of your buffer. As it only moves by one line it is more
convenient to have a fast key repetition delay, but that is another topic.
(global-set-key (kbd "<C-delete>") 'delete-pair)
(global-set-key (kbd "<C-backspace>") 'backward-delete-pair)
Deleting a pair of parentheses requires a lot of keystrokes and moving
around, especially if the contents of the parentheses is large.
With those binding it becomes much easier. Put the cursor on the left
parenthesis and press C-delete
, or on the right parenthesis and press
C-backspace
. This works with several kinds of paired symbols, including
()
, []
, even ""
.
(global-set-key (kbd "C-z") nil)
(global-set-key (kbd "C-x C-z") nil)
This disables C-z
which, when Emacs is used in a terminal, suspends it.
Sometimes I run Emacs in a screen with no shell and Emacs then cannot even be
resumed.
After a while, binding keys to existing functions becomes limited and you start combining several functions into one key binding. This first example is subtle but it saves so much time.
(global-set-key
(kbd "<M-delete>")
(lambda () (interactive)
(save-excursion
(move-end-of-line nil)
(kill-line)
(just-one-space))))
Press M-delete
and it will go the end of the current line, delete
the end-of-line character so that the next line is now there instead,
and reduce indentation from said line to just one space. Then it will
go back to where you where before, so your cursor will not have moved.
For instance, let's say you want to put the following code in one line:
line
~x1: 42
~y1: 69
~x2: 111
~y2: 666
()
Just move the cursor somewhere in the first line and press M-delete
five times in a row:
line ~x1: 42 ~y1: 69 ~x2: 111 ~y2: 666 ()
This kind of subtle trick is why I love an editor where you can program your own macros. Turn a repetitive chore into a trivial task!
This is another example where no built-in function exists and you have to write your own, although I actually found it on Stack Overflow. To rename a file you have to close the buffer, rename the file from a shell, and reload the file. If you're like me and you change the filename several times before settling on a good one, this gets annoying very fast. In fact, it may even make you settle on a bad name just because it is annoying to change. Here is how to fix that.
(global-set-key [(meta f3)] 'rename-current-buffer-file)
(defun rename-current-buffer-file ()
"Renames current buffer and file it is visiting."
(interactive)
(let ((name (buffer-name))
(filename (buffer-file-name)))
(if (not (and filename (file-exists-p filename)))
(error "Buffer '%s' is not visiting a file!" name)
(let ((new-name (read-file-name "New name: " filename)))
(if (get-buffer new-name)
(error "A buffer named '%s' already exists!" new-name)
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil)
(message "File '%s' successfully renamed to '%s'"
name (file-name-nondirectory new-name)))))))
Now you just have to type M-F3
.
This one I found on the Emacs Wiki. It allows to indent or dedent a whole region, by adding or removing a space at the beginning of each line.
(global-set-key (kbd "<C-+>") (function push-region))
(global-set-key (kbd "<C-->") (function pull-region))
(defun move-region (beg en dir)
"Move the region defined by (beg en) by dir characters.
dir may be positive or negative; positive dir means right."
(save-excursion
(let ((deactivate-mark nil))
(move-beginning-of-line nil)
(indent-rigidly beg en dir)
(push-mark beg t t))))
(defun push-region (beg en)
(interactive "r")
(move-region beg en 1))
(defun pull-region (beg en)
(interactive "r")
(move-region beg en -1))
C-+
(Control-Plus) indents the selected lines, and C--
(Control-Minus) dedents them. If you are programming, you may not
need to indent by hand as M-q
often does the job. But sometimes
M-q
is just not going to do what you want.
The above tips have something in common: they discharge you of the boring repetitive tasks and let you focus on your actual goal, whether it is by giving you more space or by reducing the amount of keystrokes that you need. If you see yourself doing the same sequence of actions again and again, consider automating it into a simple key binding.
There is a particular action which I perform a lot, which is to
split Emacs into three columns. I naturally programmed a function to
perform the splitting for me. However, this was not satisfactory at
first as there are several small details which are needed to make it
really usable in practice, like: make it easy to swap columns, ensure
that special buffers like *compilation*
or *grep*
always appear in
the same column... What was originally a small function has started
to become a mode of its own, and it deserves a separate article.