Emacs

My main .emacs just loads other configuration files which I keep in .emacs.d/:

;; set load paths
(add-to-list 'load-path (expand-file-name "~/.emacs.d"))
;; for extra elisp packages
(add-to-list 'load-path (expand-file-name "~/.emacs.d/lisp"))
;; for personal elisp projects
(add-to-list 'load-path (expand-file-name "~/.emacs.d/lisp-personal"))
 
;; load elisp customisations
(require 'SH-global)
(require 'SH-modes)
(require 'SH-temp)

SH-global.el is (or is supposed to be) for settings that affect everything:

;; global settings
(setq inhibit-startup-message t)
(fset 'yes-or-no-p 'y-or-n-p) ; no yes-or-no prompts
 
(setq transient-mark-mode t) ; selection coloring and stuff
(setq line-number-mode t)
(setq column-number-mode t)
(toggle-scroll-bar -1) ; no scroll bar
(tool-bar-mode -1) ; no tool bar
(global-font-lock-mode t)
(auto-compression-mode 1) ; when editing compressed files, uncompress first
(setq indent-tabs-mode nil)
(icomplete-mode t) ; minibuffer completion
 
(setq show-paren-delay 0)
(show-paren-mode 1) ; always highlight matching parens
 
;; I'm always accidentally invoking set-fill-column and don't need it
(global-set-key "\C-xf" 'find-file)
;; I can't believe there isn't a convenient binding for goto-line by default
(global-set-key "\M-g" 'goto-line)
(global-set-key [f10]  'start-kbd-macro)
(global-set-key [f11]  'end-kbd-macro)
(global-set-key [f12]  'call-last-kbd-macro)
 
(require 'find-file-root)
 
;; but don't offer to autocomplete files with these extensions
(setq completion-ignored-extensions
  '(".o" ".elc" ".class" ".ps" ".pdf"))
 
;; instead of dropping ~-suffixed backups everywhere, keep them here instead
;; (this directory has to exist and be writable)
(setq backup-directory-alist '(("" . "~/.emacs.d/emacs-backup")))
 
;; Color themes. The color-theme package usually needs to be installed
;; separately, in Debian it's in emacs-goodies-el.
(require 'color-theme)
(color-theme-intialize)
(color-theme-dark-blue2) ; matter of taste
 
;; make the screen blink for attention, also works with emacs -nw
(setq visible-bell t)
; (set-message-beep 'silent) ; disable beep altogether
 
;; define some functions
(defun save-and-kill-buffer ()
  (interactive)
  (save-buffer)
  (kill-buffer nil))
;; bind C-c C-c - this conflicts with various programming modes
;; (which override it), should choose something else
(global-set-key "\C-c\C-c" 'save-and-kill-buffer)
 
;; make split-window-vertically put next buffer in new window
(defadvice split-window-vertically
  (after my-window-splitting-advice first () activate)
  (set-window-buffer (next-window) (other-buffer)))
 
;; a find-file-other-frame that opens a new frame for all files we want
(defun find-file-other-frames (filename &optional wildcards)
  "Edit file FILENAME, in another frame.
 
Like `find-file-other-frame', but creates a new frame for each
file."
  (interactive (find-file-read-args "Find file(s) in other frame(s): " nil))
  (let ((value (find-file-noselect filename nil nil wildcards)))
    (if (listp value)
	(progn
	  (setq value (nreverse value))
	  (cons (switch-to-buffer (car value))
		(mapcar 'switch-to-buffer-other-frame (cdr value))))
      (switch-to-buffer-other-frame value))))
 
;; replace the keybinding for find-file-other-frame
(define-key
  (current-global-map) [remap find-file-other-frame] 'find-file-other-frames)
 
(provide 'SH-global) ; this tells .emacs that (require 'SH-global) is satisfied

SH-modes.el modifies the behavior of some modes:

;; C family
;; binds enter to newline-and-indent which is normally C-j
;; sets up no-tab indentation and depth 4
(add-hook 'c-mode-common-hook
	  (lambda()
	    (local-set-key (kbd "RET") 'newline-and-indent)
            (setq indent-tabs-mode nil)
	    (setq c-indent-level 4)
	    (setq c-basic-offset 4)))
 
;; Indentation style for C-family code
(setq c-default-style
      '((c++-mode . "stroustrup") (c-mode . "k&r") (java-mode . "java")))
(setq c-basic-offset 4)
(c-set-offset 'innamespace 0)
 
;; scheme
;; note: there used to be some custom Scheme stuff here,
;; but I've replaced all that by loading quack, an extra package
;; (...or should that somehow *be* the scheme mode?)
(add-hook 'scheme-mode-hook
	  '(lambda()
	     (require 'quack)))
 
(add-hook 'python-mode-hook
	  '(lambda ()
	     (setq python-indent 4)))
 
;; a find-file-other-frame for dired
(defun dired-find-file-other-frame ()
  "In dired, visit this file or directory in another frame."
  (interactive)
  (find-file-other-frame (dired-get-file-for-visit)))
(setq dired-load-hook
      (function
       (lambda ()
	 (define-key dired-mode-map "e" 'dired-find-file-other-frame))))
 
(provide 'SH-modes)

SH-temp contains temporary highlighting functions and such for ephemeral projects. lisp/ contains:

  • html-helper-mode.el
  • hhm-config.el (configuration for previous)
  • tempo.el (a template package)
  • quack.el (extra support for Scheme)

Which I won’t list here as they exist as distributed packages. There’s also find-file-root.el, which I found in EmacsWiki. It edits a file as root, using sudo and tramp (so those need to be present). There are many obvious improvements, but I’ve been happy with it. If you don’t like the idea of editing as root with your user password (as I don’t), append rootpw to Defaults in your sudoers file.

(defvar find-file-root-prefix
  (if (featurep 'xemacs) "/[sudo/root@localhost]" "/sudo:root@localhost:" )
  "*The filename prefix used to open a file with `find-file-root'.")
 
(defvar find-file-root-history nil
  "History list for files found using `find-file-root'.")
 
(defvar find-file-root-hook nil
  "Normal hook for functions to run after finding a \"root\" file.")
 
(defun find-file-root ()
  "*Open a file as the root user.
   Prepends `find-file-root-prefix' to the selected file name so that it
   maybe accessed via the corresponding tramp method."
 
  (interactive)
  (require 'tramp)
  (let* ( ;; We bind the variable `file-name-history' locally so we can
	 ;; use a separate history list for "root" files.
	 (file-name-history find-file-root-history)
	 (name (or buffer-file-name default-directory))
	 (tramp (and (tramp-tramp-file-p name)
		     (tramp-dissect-file-name name)))
	 path dir file)
 
    ;; If called from a "root" file, we need to fix up the path.
    (when tramp
      (setq path (tramp-file-name-localname tramp)
	    dir (file-name-directory path)))
 
    (when (setq file (read-file-name "Find file (UID = 0): " dir path))
      (find-file (concat find-file-root-prefix file))
      ;; If this all succeeded save our new history list.
      (setq find-file-root-history file-name-history)
      ;; allow some user customization
      (run-hooks 'find-file-root-hook))))
 
(global-set-key [(control x) (control r)] 'find-file-root)
 
(provide 'find-file-root)