help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RFC: intro to customizing Emacs


From: '
Subject: RFC: intro to customizing Emacs
Date: 17 Jan 2003 02:10:19 -0800

I have written an introduction to customizing GNU Emacs.  The official
version is and will be at
http://www.ideogram.com/do-nothing/GNU_Emacs.html.  A text version is
included below for your conveniencs.

The target audience is users who have completed the GNU Emacs tutorial
but are otherwise unfamiliar with GNU Emacs and are interested in
customizing it (running functions at startup, setting initial frame
parameters, adding keybindings).  They may be programmers or
non-programmers, Unix novices or experts.

The environment assumed is Debian/woody and GNU Emacs 21.2.2.

Any and all comments are welcome.

Please do link to the page if you find it worthy.

Thanks,
Adam

Copyright © 2003 Adam Kao.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license can be found at
http://www.fsf.org/copyleft/fdl.html.
Prerequisites

Before reading this you should have completed or already understand
the GNU Emacs tutorial. If you don't know what that is, read this.

You do not need to know Lisp or how to program.
What is this document?

This document examines a real GNU Emacs customization file and
explains each customization in it. This document shows you:

   1. The .emacs file and where it goes.
   2. How to get the source code for GNU Emacs (in Debian).
   3. How to get rid of the menu bar, scroll bar, and tool bar.
   4. How to specify properties for the initial frame (the first
editing window created by Emacs).
   5. What properties can be specified for a frame in X.
   6. How to specify colors to Emacs in X.
   7. How to create more frames at startup.
   8. How to change the background color of highlighted text.
   9. How to bind keys to commands so that hitting that key runs that
command.
  10. Many useful Emacs functions.
  11. How to disable functions so they are less likely to be executed
accidentally.

Keys to remember

C-h is help. You can type C-h ? to get a list of help commands. C-h a
is command-apropos, which lists all the commands that contain the
string you enter. You can see just about all the useful functions by
entering C-h b, which shows you a list of all the functions currently
bound to keys. You can get more information on a function in this list
by middle-clicking on it. C-h c key tells you how Emacs identifies the
pressed key or key combination and tells you what command is bound to
that key in the current buffer. C-h f gives you the info for the
function name you enter.

C-g is quit. If Emacs asks you a question you don't understand while
executing a command, or you accidentally start a command you don't
want, you can always hit C-g to stop and go back to the base state.

Sometimes Emacs will enter a wierd state where it seems to be asking
for something in the minibuffer (the one-line area below the bottom
white status bar) but you are editing something and you can't get rid
of what's in the minibuffer. This usually happens when you are in the
middle of a command and you click the mouse on some part of the Emacs
window outside of the minibuffer. This is technically called a
"recursive edit" (you don't need to remember this) and you can get out
of it by pressing C-] repeatedly until the minibuffer says "No
recursive edit is in progress".

f1 through f12 represent the function keys across the top of your
keyboard labeled F1 through F12. Thus M-f1 means hold down a META key
and press F1.
Environment

My environment is Debian/woody, GNU Emacs 21.2.2. If you modify this
document for other environments, please send me email.
Make ~/.emacs

Make this ~/.emacs (the ~ stands for your home directory):

(menu-bar-mode nil)
(scroll-bar-mode nil)
(tool-bar-mode nil)

(setq
 initial-frame-alist
 '((width . 78) (height . 80) (internal-border-width . 0)
   (foreground-color . "white") (background-color . "#003800")
   (cursor-color . "white") (mouse-color . "white")))
(frame-update-face-colors (selected-frame))

(select-frame
 (make-frame
  '((width . 78) (height . 80) (internal-border-width . 0)
    (foreground-color . "white") (background-color . "#003800")
    (cursor-color . "white") (mouse-color . "white"))))
(frame-update-face-colors (selected-frame))

(set-face-background 'highlight "black")

(global-set-key [f1]    'find-file)
(global-set-key [M-f1]  'find-alternate-file)
(global-set-key [C-f1]  'insert-file)

(global-set-key [f2]    'switch-to-buffer)
(global-set-key [M-f2]  'list-buffers)

(global-set-key [f3]    'split-window-vertically)
(global-set-key [M-f3]  'delete-other-windows)
(global-set-key [f4]    'other-window)
(global-set-key [M-f4]  'delete-window)

(global-set-key [f5]    'c++-mode)
(global-set-key [M-f5]  'auto-fill-mode)

(global-set-key [f6]    'query-replace)
(global-set-key [M-f6]  'isearch-forward)
(global-set-key [C-f6]  'isearch-backward)

(global-set-key [f7]    'what-line)
(global-set-key [M-f7]  'what-page)
(global-set-key [C-f7]  'what-cursor-position)
(global-set-key [f8]    'goto-line)
(global-set-key [C-f8]  'goto-char)

(global-set-key [f9]    'save-buffer)
(global-set-key [M-f9]  'save-some-buffers)
(global-set-key [C-f9]  'write-file)

(global-set-key [f10]   'info)

(global-set-key [f11]   'undo)
(global-set-key [M-f11] 'vc-toggle-read-only)
(global-set-key [C-f11] 'revert-buffer)

(global-set-key [f12]   'kill-buffer)
(global-set-key [M-f12] 'kill-some-buffers)
(global-set-key [C-f12] 'save-buffers-kill-emacs)

(global-set-key [pause] 'keyboard-escape-quit)
(global-set-key [M-pause] 'top-level)
(global-set-key [C-pause] 'save-buffers-kill-emacs)

(put 'save-buffers-kill-emacs 'disabled t)

Download.

I will explain each group of lines below.

But first ...
Get the source

(You can skip this step if you have a slow internet connection.)

Enter:

$ mkdir ~/x; cd ~/x; apt-get -t unstable source emacs21
$ dpkg-source -x emacs21_21.2-5.dsc

This will download and unpack the source code for GNU Emacs into the
directory ~/x/emacs21-21.2/.
Turn off decorations

(menu-bar-mode nil)
(scroll-bar-mode nil)
(tool-bar-mode nil)

These turn off the menu bar, scoll bar, and tool bar respectively.
Set properties of initial frame

(setq
 initial-frame-alist
 '((width . 78) (height . 80) (internal-border-width . 0)
   (foreground-color . "white") (background-color . "#003800")
   (cursor-color . "white") (mouse-color . "white")))
(frame-update-face-colors (selected-frame))

Emacs calls the top level windows displayed by the windowing system
frames. Emacs reserves the term window for the possibly multiple areas
within a frame that can each display a buffer.

initial-frame-alist specifies properties for the first frame Emacs
creates. Most of the parameters that can be set are in
~/x/emacs21-21.2/src/xfns.c, starting at line 781 in my version of the
source:

static struct x_frame_parm_table x_frame_parms[] =
{
  "auto-raise",x_set_autoraise,
  "auto-lower",x_set_autolower,
  "background-color",x_set_background_color,
  "border-color",x_set_border_color,
  "border-width",x_set_border_width,
  "cursor-color",x_set_cursor_color,
  "cursor-type",x_set_cursor_type,
  "font",x_set_font,
  "foreground-color",x_set_foreground_color,
  "icon-name",x_set_icon_name,
  "icon-type",x_set_icon_type,
  "internal-border-width",x_set_internal_border_width,
  "menu-bar-lines",x_set_menu_bar_lines,
  "mouse-color",x_set_mouse_color,
  "name",x_explicitly_set_name,
  "scroll-bar-width",x_set_scroll_bar_width,
  "title",x_set_title,
  "unsplittable",x_set_unsplittable,
  "vertical-scroll-bars",x_set_vertical_scroll_bars,
  "visibility",x_set_visibility,
  "tool-bar-lines",x_set_tool_bar_lines,
  "scroll-bar-foreground",x_set_scroll_bar_foreground,
  "scroll-bar-background",x_set_scroll_bar_background,
  "screen-gamma",x_set_screen_gamma,
  "line-spacing",x_set_line_spacing,
  "wait-for-wm",x_set_wait_for_wm
};

width and height are specified in terms of characters. Emacs adds
one-character wide columns on the left and right side of each frame
(for marking continuation lines), so the actual frame in this case
will be 80 characters wide and 80 characters high, although any line
longer than 78 characters will produce continuation lines.

internal-border-width specifies how many pixels to add as margins (on
all four sides) around the data displayed in the frame. These add
space between the Emacs frame (area displaying data) and the window
manager frame (the widgets for resizing, etc.). If there is no window
manager frame, they just cover up more of the background.

There are two ways to specify colors to Emacs. You can use a color
name, which is a color defined in /usr/lib/X11/rgb.txt, or you can
specify a color directly in RGB values. Here we use both, "white"
(which could also be specified as "#ffffff"), and "#003800" which is a
barely perceptible dark green (looks black from a distance).

You must call frame-update-face-colors to update the display with the
selected colors. A face is a combined specification of a foreground
color, a background color, and possibly a font. We must call this
function because we changed the foreground and background colors of
the default face.

The (selected-frame) is the initial frame because at this time it is
the only frame.
Create second frame

(select-frame
 (make-frame
  '((width . 78) (height . 80) (internal-border-width . 0)
    (foreground-color . "white") (background-color . "#003800")
    (cursor-color . "white") (mouse-color . "white"))))
(frame-update-face-colors (selected-frame))

The argument to make-frame is a list with the same possible parameters
as initial-frame-alist. Here we set all the same parameters to the
same values.

make-frame returns the frame it creates, which means you can put the
entire call to make-frame inside the argument list of another function
that takes a frame, in this case select-frame. This sets the selected
frame to the frame created by make-frame, so we can call
frame-update-face-colors the same way we did before.
Highlight background

(set-face-background 'highlight "black")

Emacs uses the highlight face for things you can middle-click on, like
the buffer names in the list-buffers display.
File loading

(global-set-key [f1]    'find-file)
(global-set-key [M-f1]  'find-alternate-file)
(global-set-key [C-f1]  'insert-file)

find-file is the command run by C-x C-f. You can still use C-x C-f but
hitting F1 is a little faster.

find-alternate-file asks you for a file, replaces the current buffer
with a new buffer, reads the file into that buffer and shows it to
you. I call this the "oops" command because you typically use it when
you tried to open a file and somehow entered the wrong name.

insert-file takes a file and inserts its contents into the current
buffer at the current cursor location.
Buffer navigation

(global-set-key [f2]    'switch-to-buffer)
(global-set-key [M-f2]  'list-buffers)

You can switch to an existing buffer by using switch-to-buffer and
typing in the name of the buffer. If you can't remember the name of a
buffer, list-buffers shows you what the current buffers are. You can
go to a buffer from this list by middle-clicking on it.
Window management

(global-set-key [f3]    'split-window-vertically)
(global-set-key [M-f3]  'delete-other-windows)
(global-set-key [f4]    'other-window)
(global-set-key [M-f4]  'delete-window)

split-window-vertically is the command run by C-x 2. Typically you
would then use switch-to-buffer to change the buffer displayed in one
of the windows.

You can use split-window-vertically many times to create smaller and
smaller windows.

delete-other-windows is the command run by C-x 1.

other-window is the function run by C-x o. If you have many windows in
the current frame you may need to keep doing it until you get to the
window you want (or simply click in it).

You can get rid of the current window and give its display area to
another window with delete-window. However, this command almost never
gives the released display area to the window you want. You can adjust
the display areas by holding down the left mouse button on the white
status bar between windows and dragging up or down.

Deleting a window does not remove the buffer it was displaying, you
will still be able to find it with list-buffers. We will see how to
remove buffers later.

I almost never have more than two windows per frame.
Modes

(global-set-key [f5]    'c++-mode)
(global-set-key [M-f5]  'auto-fill-mode)

I use c++-mode because I edit C and C++ code a lot. auto-fill-mode is
also quite handy. Browse the Emacs info for useful modes.
Search and Replace

(global-set-key [f6]    'query-replace)
(global-set-key [M-f6]  'isearch-forward)
(global-set-key [C-f6]  'isearch-backward)

query-replace asks you for a search string, then asks you for a string
to replace it with, then starts searching at the current cursor
position, steps forward to the next matching string in the file, at
which point you can press the spacebar or "y" to replace it or Delete
or "n" to leave it alone or "q" or C-g to quit the entire process
(there are other options which I never use, you can see them by
pressing "?") and then keeps stepping forward to the next matching
string in the file and asking you whether to replace it until you quit
or reach the end of the file.

isearch-forward is incremental search. To search for the next
occurence you still need to hit C-s. I don't know why you can't
continue an incremental search with M-f6.

isearch-backward is the same going backwards.
Identifying and going to specific characters/lines/pages

(global-set-key [f7]    'what-line)
(global-set-key [M-f7]  'what-page)
(global-set-key [C-f7]  'what-cursor-position)
(global-set-key [f8]    'goto-line)
(global-set-key [C-f8]  'goto-char)

what-line tells you the number of the line the cursor is on. This is
not so useful now that the line number is displayed on the status bar
by default (preceded by "L", 2nd field from the right) but it is
included for completeness.

what-page tells you what page and line on that page you are on. This
is also not so useful since it doesn't assume pages are 66 lines (or
whatever) long, it merely counts form-feed characters, ASCII value
0xc, which can be entered with C-q C-l and appears as ^L when editing.

what-cursor-position gives you a lot of info about the character you
are on, including the decimal, octal, and hexadecimal ASCII values of
the character, how far into the file it is, and the column it is in
(this last is what I mainly use it for).

goto-line asks you for a line number and goes to it. Useful if you
compile your programs in a terminal window (as I do) and need to find
errors by line number.

I never use goto-char; it is included for completeness.
Saving buffers

(global-set-key [f9]    'save-buffer)
(global-set-key [M-f9]  'save-some-buffers)
(global-set-key [C-f9]  'write-file)

save-buffer is the command run by C-x C-s.

save-some-buffers is the command run by C-x s.

write-file asks you to enter a new file name to save the current
buffer to. After completing the command this buffer will be associated
with the new file name. You can use this to split off a new version of
a file and save your changes to a different file while leaving the
previously saved or loaded file unchanged.
Info

(global-set-key [f10]   'info)

The most excellent info, GNU's text-based hyperlinking documentation
system. Note that it was working and working well long before the
World Wide Web. Because it is a standard many GNOME and Debian
packages install info nodes. Read it. A lot.
Undo and preventing damage

(global-set-key [f11]   'undo)
(global-set-key [M-f11] 'vc-toggle-read-only)
(global-set-key [C-f11] 'revert-buffer)

One of Emacs' greatest features is unlimited undo/redo. Keep hitting
undo to keep going back. Insert some other non-editing command (like
moving the cursor) to "reverse" the direction of the undo/redo. After
a while you will find it perfectly natural.

vc-toggle-read-only switches a buffer between editable and not
editable. This is useful if you have a buffer of, say, library source
code that you are only using for reference or cutting and pasting from
and you don't want stray key presses modifying the file.

If you open a file with Unix permissions set to deny you modification
rights then it will appear in Emacs as non-editable (the two
characters to the right of the : at the left side of the status bar
will be %%). If you vc-toggle-read-only and try to save the file Emacs
will try to change the permissions to let you modify it. If it can't
Emacs will give you an error.

You can revert-buffer to discard all the changes you made to the file
since the last saved version.
Getting rid of buffers and leaving

(global-set-key [f12]   'kill-buffer)
(global-set-key [M-f12] 'kill-some-buffers)
(global-set-key [C-f12] 'save-buffers-kill-emacs)

kill-buffer gets rid of the current buffer. The main reason to use
this command is to reduce clutter when you list-buffers.

kill-some-buffers steps through all the buffers and for each one asks
you if you want to kill it.

The final get-me-out-of-here command is save-buffers-kill-emacs. Steps
through all the modified but not saved buffers, for each one asking
you if you want to save it, and then ends Emacs. If you are in the
middle of the saving process and change your mind about quitting, hit
C-g.
Getting out of trouble

(global-set-key [pause] 'keyboard-escape-quit)
(global-set-key [M-pause] 'top-level)
(global-set-key [C-pause] 'save-buffers-kill-emacs)

These functions are bound to this key because it is labelled
pause/break even though in Emacs it is only known as pause.

keyboard-escape-quit is like C-g.

top-level is like hitting C-] as many times as necessary to get out of
recursive edit (hmm I guess you should have remembered it after all).

And once again the get-me-out-of-here command.
Preventing accidental quitting

(put 'save-buffers-kill-emacs 'disabled t)

This sets it so that you can still execute the specified command, but
Emacs asks you first if you really want to execute it. Generally if
you really want to execute it you will then hit the spacebar, or if
you didn't want to execute it you can hit "n" or C-g.

There aren't many commands left which need this, since the defaults
already catch the really annoying ones like upcase-region.
Feedback

Send me email. 
History

16jan2003: Adam Kao. Added What is this document? and Download link.

15jan2003: Adam Kao. Created.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]