Emacs Tips

After using Emacs for a while and feeling comfortable with its basic operation, you'll find some default settings don't match the way you work. Not a problem. We all have preferences and that's okay. A lot of programs force you to work as they've been coded with little chance of modifying them.

Emacs is different. Emacs allows you to change any part of Emacs behaviour and tailor it to work the way you want. Emacs is such a powerful application, it's often referred to as an operating system. Well its not quite there, but I understand Emacs hackers are working on it.

I read Steve Yegge's blogpost on improving Emacs efficiency, Effective Emacs, and incorporated many of his suggestions. A big thanks to Steve Yegge. I suggest you take a look.
Changing things in Emacs can be a little daunting at first. Here's a run through of some changes and how it can help you better utilise the power of Emacs.

After working with the BASH shell in an Xterm, I got used to Ctrl-h to delete previous character. It was so ingrained, when I got to Emacs I kept launching the help screen. Emacs by default sets Ctrl-h to launch help.  I changed Ctrl-h to delete previous character. Now it works as it does in BASH. To launch help in Emacs, I re-mapped it to Ctrl-x h.

Text entry, moving and editing are probably the most common operations in Emacs. The standard set up works okay, but can be improved on.

The power of Emacs derives from using the keyboard and not the mouse. If you move your hands from the keyboard to manipulate the mouse, its less efficient, you lose time and momentum. Grabbing the mouse to move the cursor is clumsy and slow. The same applies to moving the Up/Down Left/Right arrow keys. To polish your performance and power your file edits, keep your hands on the 'Home Row' keys. Those are the keys 'A' to 'L' on a standard keyboard.

Avoid using the mouse at all costs. If your not using the mouse, how do you move around the buffer? (Emacs calls each file a buffer.)

I'll outline how to setup the changes in you dot.emacs file later in this post. I'll also post my dot.emacs file for you to cannibalise.

For example, to go to start of buffer, you can hit the 'Home' button. You move your fingers off the 'Home Row'. To go to the end of buffer, you can press 'End' button. Again your fingers stray off 'Home Row'. This is not so bad as using the mouse, but it can be improved on.

The first change you must make is to switch the caps-lock key to Ctrl key. Then using your left pinky finger you can hit Ctrl easily any time you need.

Here are some other changes I made. Some were taken from Steve Yegge's blog post.

I re-mapped some keys, to enable a faster method of moving around in Emacs:

Ctrl-x t -- Go to top of buffer

Ctrl-x e -- Go to end of buffer

Ctrl-/ -- Undo last operation

Ctrl-; -- Delete to start of line

Ctrl-x k -- Delete to end of line

Ctrl-x ; -- Delete to start of line

Ctrl-z -- redo last action

Emacs default set up, has no delete to start of line. I remapped that to Ctrl-x ;

To move to any point in the buffer, use search. This is such an under-rated feature. It is the fastest way to move around a buffer in Emacs. Even in the same line. Instead of hitting Alt-f six times to move to the sixth word, use Ctl-s and type the first few characters of the word your looking for, Emacs will highlight the each instance. Keep hitting Ctrl-s and Emacs jumps to the next instance of your search string. It is without doubt one of Emacs most powerful features. Use it!

Ctrl-s -- search forward

Ctrl-r -- search backwards.

Use it. And use it often.

A few Emacs default settings:

Forward one character: ... Ctrl-f
Back one character: .......... Ctrl-b
Forward one word: ........... Alt-f
Back one word: .................. Alt-b

Start of line: ....................... Ctrl-a
End of line: ......................... Ctrl-e

I felt Emacs lacked a word count function. You finish a doc or post and need to know how many words you output. So I included a word count in my dot.emacs init file. Its right at the end of the init file.

To use the word count function, do:

 Ctrl-c  Ctrl-c

Here's a copy of my minimal dot.emacs file.

Do your worst...

; *********************************************
; Patrick's .emacs init file
; 2009-12-18

; Tell Emacs where elisp .el files reside then load-path
; (add-to-list 'load-path "~/.elisp")
; (add-to-list 'load-path "~/pager.el")

; Get rid of startup message
(setq inhibit-startup-message t)

; Scrap initial scratch message
; (setq initial-scratch-message nil)

(when window-system
(mwheel-install) ; Enable mousewheel support
(tool-bar-mode nil) ; Get rid of the toolbar
(menu-bar-mode nil) ; Get rid of the menu bar
(scroll-bar-mode nil)) ; Get rid of the scroll bar
; (set-scroll-bar-mode 'right) ; Set scroll bar on right
; Set initial window size
(setq initial-frame-plist '(top 0 left 0 width 300 height 300))

; Enable line number in mode line
(line-number-mode 1)

; Show column number on mode line
(column-number-mode t)

; Display time on mode line

; Display 24-hour format
(setq display-time-24hr-format t)

; Disable blinking cursor
(blink-cursor-mode nil)

; Color settings to make Emacs look pretty
(set-background-color "white")
(set-foreground-color "black")
;(set-background-color "#dfdfdf")
(set-face-background 'modeline "#4377B6")
(set-face-foreground 'modeline "#FFFFFF")
(set-face-background 'region "orangered")
(set-face-background 'highlight "white")
(set-cursor-color "blue")

; Set default font to Consolas

; Disable beep. Flash on error
(setq visible-bell t)

; Highlight incremental search
(setq search-highlight t)

; Highlight fonts - M-x describe-mode font-lock-mode for info
(global-font-lock-mode t)

; Highlight Parenthesis
(show-paren-mode t)
;(setq blink-matching-paren t)

; Typed text replace highlighted
(delete-selection-mode t)

; Color selected region
(setq-default transient-mark-mode t)

; Highlight during query
(setq query-replace-highlight t)

; Scroll faster
(setq lazy-lock-defer-on-scrolling t)

; Disable scroll jump
(setq scroll-step 1)

; Make y and yes both work
(fset 'yes-or-no-p 'y-or-n-p)

; End file with a newline
(setq require-final-newline t)

; Use spaces instead of tabs
(setq-default indent-tabs-mode nil)

; Spaces instead tabs
(setq default-tab-width 4);

; M-g runs the goto-line function.
(global-set-key "\M-g" 'goto-line)

; Delete auto-save files
; (setq delete-auto-save-files t)

; Disable file backup
(setq make-backup-files nil)

; Disable file saves
;(setq auto-save-list-file-name nil)

; Ctrl-h to delete left instead of help
(keyboard-translate ?\C-h ?\C-?)

; *********************************************
; Following from Steve Yegge's blog on Emacs
; Used some ideas and suggestions
; *********************************************

; Invoke M-x without Alt Key
(global-set-key "\C-x\C-m" 'execute-extended-command)
(global-set-key "\C-c\C-m" 'execute-extended-command)

; Ctrl-w replace <-backspace backward="backward" delete="delete" for="for" p="p">; C-w normally deletes whole region now reset to C-x C-k
(global-set-key "\C-w" 'backward-kill-word)
(global-set-key "\C-x\C-k" 'kill-region)
(global-set-key "\C-c\C-k" 'kill-region)

; Alt-n & Alt-p for page scrolling
(global-set-key "\C-[p" 'down-one)
(global-set-key "\C-[n" 'up-one)

; Re-Map M-<>
(global-set-key (kbd "C-x t") 'beginning-of-buffer)

; Re-Map M-> to Ctrl-x e
(global-set-key (kbd "C-x e") 'end-of-buffer)

; Steve Yegge entries end *********************

; *********************************************
; Word Count Function ; 'count-words-buffer
; Source: Programming in Emacs Lisp tutorial
; http://www.gnu.org/software/emacs/emacs-lisp-intro/html_node/recursive_count_words.html#recursive_count_words
; Source: Tutorial Contents Page
; http://www.gnu.org/software/emacs/emacs-lisp-intro/html_node/

; Final version: while
(defun count-words-region (beginning end)
"Print number of words in the region."
(interactive "r")
(message "Counting words in region ... ")

; 1. Set up appropriate conditions.
(let ((count 0))
(goto-char beginning)

; 2. Run the while loop.
(while (and (< (point) end)
(re-search-forward "\\w+\\W*" end t))
(setq count (1+ count)))

; 3. Send a message to the user.
(cond ((zerop count)
"The region does NOT have any words."))
((= 1 count)
"The region has 1 word."))
"The region has %d words." count))))))

; Count the words in the entire document
(defun count-words-buffer ()
"Count all the words in the buffer"
(count-words-region (point-min) (point-max) )

; Bind count-words-buffer to Ctrl-c Ctrl-c
(global-set-key "\C-c\C-c" 'count-words-buffer)

; End of Word Count function
; *********************************************

; End of file.