;; Emacs Configuration File (-*- emacs-lisp -*-) ;; Author: Sean B. Palmer, inamidst.com ;; Source: http://inamidst.com/config/emacs ;; Backups and Autosave (but not Locking, yet...) ;; Turn off the annoying default backup behaviour (if (file-directory-p "~/.emacs.d/backup") (setq backup-directory-alist '(("." . "~/.emacs.d/backup"))) (message "Directory does not exist: ~/.emacs.d/backup")) ;; - http://www.debianusers.pl/articles/resources/emacs-devel/emacs ;; - http://www.emacswiki.org/cgi-bin/wiki/JorgenSchaefersEmacsConfig ;; Autosave to a single directory (defun auto-save-file-name-p (filename) (string-match "^autosave\..*$" (file-name-nondirectory filename))) (defun make-auto-save-file-name () (concat (expand-file-name "~/.emacs.d/backup") "/" (if buffer-file-name (concat "autosave." (file-name-nondirectory buffer-file-name)) (expand-file-name (concat "autosave.%" (buffer-name)))))) ;; - http://snarfed.org/space/gnu+emacs+backup+files ;; Default Behaviours (setq-default default-fill-column 79 blink-matching-paren nil visible-bell t ;; Turns off audible bell default-major-mode 'text-mode ;; Silly "Fundamental" ;; - http://www.gnu.org/software/emacs/manual/html_node/Init-Examples.html inhibit-startup-message t ;; Should have been made more compact ;; - http://www.eecs.berkeley.edu/~clancy/sp.unix.stuff/emacs.ref.pdf require-final-newline 'ask ;; - http://odin.himinbi.org/config/emacs ;; - http://www.emacswiki.org/cgi-bin/wiki/JorgenSchaefersEmacsConfig sentence-end-double-space nil sentence-end "[.?!][]\"')]*\\($\\|\t\\| \\)[ \t\n]*" colon-double-space nil ;; - http://users.tkk.fi/~rsaikkon/conf/dot.emacs ) ;; Turn off syntax highlighting! New in emacs 22.1? ;; Cf. http://www.gnu.org/software/emacs/manual/html_mono/emacs.html#Font-Lock (global-font-lock-mode 0) ;; Suppress the GNU advertising, specifically with a setq... (setq inhibit-startup-echo-area-message "sbp") ;; http://www.rattlesnake.com/intro/Text-and-Auto-fill.html (add-hook 'text-mode-hook 'turn-on-auto-fill) ;; Turn off the lazy-highlighting ;; (setq isearch-lazy-highlight nil) ;; Turn off the annoying isearch formatting (if (facep 'isearch) (set-face-attribute 'isearch nil :foreground "White" :background "Black" :underline t)) (if (facep 'isearch-lazy-highlight-face) (set-face-attribute 'isearch-lazy-highlight-face nil :foreground "White" :background "Black" :underline t)) ;; - Cf. http://www.emacswiki.org/cgi-bin/wiki/start-opt.el ;; Turn off all the annoying distractions (if (fboundp 'tool-bar-mode) (tool-bar-mode -1)) (if (fboundp 'menu-bar-mode) (menu-bar-mode -1)) ;; - http://www.cabochon.com/~stevey/blog-rants/effective-emacs.html ;; Key-Bindings Galore! ;; ;; Aim: to change these as minimally possible. ;; Note how C-x C-b, for example, doesn't massively change in function. ;; It's nice to be able to learn the defaults so that you can edit ;; on more or less any system. Then again, downloading a .emacs file ;; isn't all that difficult... ;; Rebind C-x C-b to buffer-menu instead of list-buffers (global-set-key "\C-x\C-b" 'buffer-menu) ;; Since M-! doesn't work, bind shell-command to M-" (actually ESC-") ;; @@ Put this in Toucan Mode as "!" perhaps? (global-set-key "\e\"" 'shell-command) ;; @@ Deprecate this in favour of "D" in Toucan Mode? (global-set-key "\C-w" 'backward-kill-word) ;; Cf. http://www.cabochon.com/~stevey/blog-rants/effective-emacs.html (global-set-key "\C-cd" 'delete-region) (global-set-key "\C-cc" 'copy-region-as-kill) (global-set-key "\C-cv" 'yank) ;; @@ Does yank mean the same in vi? ;; Mainly one kills to move. See TM:mmp ;; (global-set-key "\C-cx" 'kill-region) ;; Set C-DEL to (forward-)kill-word (also available as M-d) ;; (global-set-key "\e[3^" 'kill-word) ;; Again, see "d" in Toucan Mode ;; Macro Key. @@ start-kbd-macro and end-or-call-kbd-macro (global-set-key [f4] 'call-last-kbd-macro) ;; Cf. http://www.gnu.org/software/emacs/manual/emacs.html#Basic-Keyboard-Macro (defun my-justify-paragraph () "Justify a paragraph and move to its end." (interactive) (fill-paragraph nil) (forward-paragraph)) ;; Set C-j to fill-paragraph (was newline-and-indent) (global-set-key "\C-j" 'fill-paragraph) (global-set-key "\C-cj" 'my-justify-paragraph) ;; @@ Could make a program do this Properly... ;; Make the "Home" and "End" keys work (define-key function-key-map "\e[7~" [home]) (define-key function-key-map "\e[8~" [end]) ;; - http://kellyfelkins.org/article/19/cygwin-terms-and-emacs (global-set-key "\C-cl" 'goto-line) ;; Cf. "I bind M-g to goto-line" ;; - http://www.emacswiki.org/cgi-bin/wiki/EmacsNiftyTricks ;; Run commands with C-c e, not M-x (defun my-execute-command (command) "Execute an emacs command." (interactive (list (completing-read "Command: " obarray))) (command-execute (intern command))) (global-set-key "\C-ce" 'my-execute-command) ;; (global-unset-key "\M-x") (defun my-mx-warning () (interactive) (message "Use 'C-c e' to execute a command")) (global-set-key "\M-x" 'my-mx-warning) ;; Cf. http://www.cabochon.com/~stevey/blog-rants/effective-emacs.html (global-set-key "\C-ca" 'apropos) ;; Non-incremental Search ;; (Also available as C-s RET) ;; @@ Get searches to be remembered, a la nano ;; (defun my-search-forward (term) ;; "Search forward, moving to the beginning of term." ;; (interactive (list (read-from-minibuffer "Find: "))) ;; (if (search-forward term) ;; (backward-char (length term)))) ;; ;; (global-set-key "\C-cf" 'my-search-forward) ;; @@ ;; C-c d = Delete selection ;; C-c x = Cut selection ;; C-c c = Copy selection ;; C-c v = Paste ;; C-c j = Justify paragraph ;; C-c l = Go to line ;; C-c e = Execute command ;; C-c a = Apropos ;; C-c m = Toggle visible-mark-mode ;; C-c g = Occur ;; C-c w = Collapse whitespace ;; C-c z = Zap up to character ;; If you depend on "cfz" and "dfz", use the `zap-to-char' command with M-z ;; If you prefer "ctz" and "dtz", use ZapUpToChar. ;; - http://www.emacswiki.org/cgi-bin/wiki/ViKeys ;; Cf. http://www.emacswiki.org/cgi-bin/wiki/ZapUpToChar ;; The following implementation is based on zap-to-char in simple.el, though ;; (defun my-zap-up-to-char (arg char) ;; "Kill up to the ARG'th occurrence of CHAR." ;; (interactive "p\ncDelete to: ") ;; (kill-region (point) ;; (progn (search-forward (char-to-string char) nil nil arg) ;; (backward-char) ;; (point)))) ;; ;; (global-set-key "\C-cz" 'my-zap-up-to-char) (defun my-collapse-whitespace () "Reduce all whitespace surrounding point to a single space." ;; @@ This seems to be quite buggy at the moment (interactive) (kill-region (progn (re-search-backward "[^ \t\r\n]") (forward-char) (point)) (progn (re-search-forward "[^ \t\r\n]") (backward-char) (point))) (insert-char ?\ 1)) (global-set-key "\C-cw" 'my-collapse-whitespace) ;; Bounce Between Parens (defun my-match-paren (arg) "Move to the matching paren, or insert arg." (interactive "p") (let ((syntax (char-syntax (following-char)))) (cond ((= syntax ?\() (forward-sexp 1) (backward-char)) ((= syntax ?\)) (forward-char) (backward-sexp 1)) (t (self-insert-command (or arg 1)))))) ;; Cf. http://www.emacswiki.org/cgi-bin/wiki/MatchParenthesis (define-key emacs-lisp-mode-map "%" 'my-match-paren) ;; Cutting and Moving Lines (defun my-kill-whole-line () "Kill an entire line, including trailing newline" (interactive) (beginning-of-line) (kill-line 1)) ;; Ignore what's-his-name's advice, and make C-k DTRT (global-set-key "\C-k" 'my-kill-whole-line) (global-set-key "\C-ck" 'kill-line) ;; @@ Deprecate for TM:K? (defun my-move-line-up () "Move a line up a single position." ;; @@ Moves lines without a newline at the end, too (interactive) (if (> (count-lines 1 (point)) 0) (let ((my-previous-column (current-column))) (progn (my-kill-whole-line) (previous-line 1) (beginning-of-line) (yank) (previous-line 1) (move-to-column my-previous-column))))) (defun my-move-line-down () "Move a line down a single position." (interactive) (if (< (count-lines 1 (point)) (1- (count-lines 1 (point-max)))) (let ((my-previous-column (current-column))) (progn (my-kill-whole-line) (next-line 1) (beginning-of-line) (yank) (previous-line 1) (move-to-column my-previous-column))))) ;; These keybindings are for cygwin-rxvt (global-set-key "\eOa" 'my-move-line-up) (global-set-key "\eOb" 'my-move-line-down) ;; @@ Count line-breaks as whitespace (defun my-backward-word () "Move backwards a word based on whitespace." (interactive) (if (= (char-syntax (following-char)) ?\ ) (re-search-backward "[^ \t]") (forward-char)) (re-search-backward "[ \t]")) (defun my-forward-word () "Move forwards a word based on whitespace." (interactive) (if (= (char-syntax (following-char)) ?\ ) (re-search-forward "[^ \t]")) (re-search-forward "[ \t]") (backward-char)) ;; On cygwin-rxvt: \eOc = C-; \eOd = C- (global-set-key "\eOc" 'my-forward-word) (global-set-key "\eOd" 'my-backward-word) ;; Reverse Solidus Micromode (defun my-insert-slash () "Insert a single '\\' character." (interactive) (insert-char ?\\ 1)) (global-set-key "\C-\\" 'my-insert-slash) (defun my-ca-warning () (interactive) (message "Type '\\m' to set mark")) (global-set-key "\C-@" 'my-ca-warning) ;; Finely Tuned Custom Mode-Line (defun my-buffer-filename () "Return pretty printed buffer filename." (let ((filename (buffer-file-name))) (if filename (let ((homedir (getenv "HOME")) (pwd (concat (getenv "PWD") "/"))) (cond ((and (> (length pwd) 0) (string-match pwd filename)) (substring filename (length pwd))) ((and (string-match homedir filename) (= (string-match homedir filename) 0)) (concat "~" (substring filename (length homedir)))) (t filename))) (buffer-name)))) ;; @@ Allow an optional length argument (defun my-trimmed-buffer-filename () "Return a possibly pre-truncated buffer filename." (let ((filename (my-buffer-filename))) (if (> (length filename) 32) (concat "..." (substring filename (- 0 (- 32 3)))) filename))) (defun my-mode-line-prefix () (concat " GNU Emacs " (if (buffer-modified-p) "-" "=") "> " (my-trimmed-buffer-filename))) ;; (defun my-is-toucan () ;; (if toucan-mode " TOUCAN!" "")) (defvar pelican-mode) (defun my-mode-line-suffix () (concat "Line %l, Pos %c (" mode-name (if pelican-mode " Pelican" "") ") ")) (defun my-mode-line-offset () (- (+ (length (number-to-string (1+ (count-lines 1 (point))))) (length (number-to-string (current-column)))) 4)) (setq default-mode-line-format '((:eval (let ((prefix (my-mode-line-prefix)) (suffix (my-mode-line-suffix))) (concat prefix (make-string (- (frame-width) (+ (length prefix) (length suffix) (my-mode-line-offset))) ?\ ) suffix))))) ;; Documentation for this includes: ;; ;; * http://www.delorie.com/gnu/docs/elisp-manual-21/elisp_361.html ;; * http://www.macosxhints.com/article.php?story=20041008195252133 ;; * http://www.delorie.com/gnu/docs/emacs-lisp-intro/emacs-lisp-intro_248.html ;; * http://www.tac.nyc.ny.us/manuals/elisp/elisp_290.html (defun my-save-message () (message (concat "Saved " (number-to-string (buffer-size)) " bytes to " (my-buffer-filename) "..."))) (add-hook 'after-save-hook 'my-save-message) ;; Packages to Load ;; nxml-mode, by James Clark ;; http://www.thaiopensource.com/nxml-mode/ (if (file-directory-p "~/.emacs.d/nxml-mode") (progn (load "~/.emacs.d/nxml-mode/rng-auto.el") (setq-default nxml-syntax-highlight-flag nil) (add-hook 'nxml-mode-hook 'turn-on-auto-fill) (add-hook 'nxml-mode-hook '(lambda () (define-key nxml-mode-map "\C-c\C-c" 'nxml-complete))) ;; - http://www.dpawson.co.uk/relaxng/nxml/nxmlGeneral.html#d201e273 (add-to-list 'auto-mode-alist (cons "\\.\\(html\\|xml\\|rdf\\|xsl\\)\\'" 'nxml-mode))) (message "Unable to load nxml-mode")) (if (file-regular-p "~/.emacs.d/pelican.el") (progn (load "~/.emacs.d/pelican.el") (global-set-key "\C-p" 'pelican-mode)) (message "Unable to load pelican-mode")) ;; Report Success (@@ or tip of the day or something) (message "Successfully loaded ~/.emacs...") ;; Todo, Furphies and Elusivities ;; @@ "Error!" on windows whose status is not 0? ;; @@ Some kind of tip-of-the-day thing? Reminder of the day... ;; @@ Automake, and other save hooks ;; @@ http://www.emacswiki.org/cgi-bin/wiki/RepetitionDetection ;; @@ Make wrap do so on any char, not just whitespace ;; [EOF]