Ask HN: What's in your .emacs file?

121 points by procrastinatus ↗ HN
I recently accidentally lost my .emacs file which I'd tweaked and put together over the last 5 years. I though this would be a good chance to ask you, what's in your .emacs file?

59 comments

[ 2.7 ms ] story [ 144 ms ] thread
Most important:

  ;; Don't mix tabs and spaces
  (setq-default indent-tabs-mode nil) 
  
  ;; Use "newline-and-indent" when you hit the Enter key so
  ;; you don't need to keep using TAB to align each line.
  (global-set-key "\C-m" 'newline-and-indent)

  ;; Get rid of the <2> with duplicate file names
  (require 'uniquify)
  (setq uniquify-buffer-name-style 'post-forward-angle-brackets)
And then a whole bunch of autoload statements for different programming languages.
(comment deleted)

  ;; Use "newline-and-indent" when you hit the Enter key so
  ;; you don't need to keep using TAB to align each line.
  (global-set-key "\C-m" 'newline-and-indent)
That's what C-j is for.
True, but I'm pretty sure mapping to C-m also maps it to the enter key.
178 lines of crap accumulated over about 20 years. I think I only use an indent variable setting, one key binding, and a handful of language autoloads.

delete-delete-delete save-buffer Much better.

lines of crap accumulated over about 20 years

I hear ya.

One of the things I started doing lately is not moving any dotfiles automatically when I get a new machine. After 3 days of moaning, I go and dig out just the stuff that I have noticed I am missing. (I do the same for firefox plugins and so on). It has definitely helped with the historical crud.

Yeah it really forces you to look into those dotfiles you haven't read in two years, or that hack script you banged out in 5 minutes, and give them all a bit of thought. That "Just get it into my PATH so I can try it out!" impulse has definitely gotten the better of me a number of times.
ditto. I recall spending many late nights optimizing my dot emacs file and it accumulated tons of cruft. Now it is very abbreviated, wait no that was a dream - Just looked at it, still tons of junk that I don't use. Most of what I use is buffer saving (desktop), hot-keys, turn off scrollbars, and mapping odd file extension to modes. Guess I should go through and clean house again.
http://bitbucket.org/[redacted]/dotfiles/src/tip/.emacs

http://bitbucket.org/[redacted]/dotfiles/src/tip/.emacs.d/pl...

Probably my favorite bit of the config is that it uses flymake to run Pyflakes on my Python code as I'm writing it. I also have a little plugin that shows the error in the minibuffer area when the point is over the offending line.

It also disables backup/autosave file littering by using a locked down directory in /tmp.

As far as bindings go, I wrote delete-backward-indent for python-mode which deletes a level of indentation instead of just one space. There's also newline-maybe-indent that doesn't indent if the previous line has no indentation.

Everything else is pretty straightforward customization, I think. flyspell-prog-mode is another thing worth mentioning: it highlights spelling errors, but only in strings and comments.

I have an emacs.d, which is a superior alternative to a .emacs.

The basic init.el file loads my various language modes, and some other minor modes (e.g., tempbuf-mode). It also loads a bunch of files from the "emacs.d/my_lisp" directory which contains various overrides and new functionality attached to existing modes (e.g., icicles customization, assorted one-off functions I want to add to modes). Lastly, it loads a bunch more files from my emacs.d/lisp directory which implement custom functionality.

For example, the current emacs M-x eshell doesn't behave the way I like. I often want multiple shells, so I've build a "ring of shells" functionality: f6 cycles through the ring of shells, C-f6 creates new shell window in the ring. I did something similar with window configurations.

Also, the emacs.d stores all modes which I use regularly. So when I migrate to a new computer, all I need to do is

    darcs get me@oldbox:emacs.d
and tweak a few settings.
Here is a one-liner that's quite useful:

   (add-hook 'c-mode-common-hook
	  (lambda ()
	    (font-lock-add-keywords nil
	     '(("\\<\\(FIXME\\|TODO\\|BUG\\):" 1 font-lock-warning-face t)))))
my emacs.d still needs a few tweaks but I'm convinced it always will.

most useful parts: replacing fundamental mode with text-mode as the default mode when a new buffer is open.

(setq default-major-mode 'text-mode)

turn auto fill (automatic line wraping) and flyspell (spellchecking) on by default

(add-hook 'text-mode-hook 'turn-on-auto-fill)

(add-hook 'text-mode-hook 'turn-on-flyspell)

also I find yasnippet http://code.google.com/p/yasnippet/ wonderful for coding html mockups and django templates.

my github repo if anyone cares to take a peek: http://github.com/bmac/emacs

Regarding newlines: in Emacs 23, I recommend visual-line-mode over auto-fill-mode, unless you actually need hard line breaks. For when you do want hard newlines, (setq-default fill-column 80). I never understood why the default is 72; it makes text files excessively narrow.
The default is 72, in my understanding, because of the historical use of email.

As folks successively quote each other in a thread, the prepending of '>' to the quoted text requires something narrower than 80, else it'll hit the 80-chars-wide limit and wrap.

72 would allow 4 or 8 quote-levels, depending on if your client decides to insert spaces around the '>'.

http://github.com/markhepburn/dotemacs

Lots of cruft (roughly 10 years worth), although I did recently start to refactor.

Most notable: it's fairly portable and relocatable, thanks to a snippet I cooked up (probably not original, but I haven't seen it else-where): http://everythingtastesbetterwithchilli.com/initialisation-f... (check it out anywhere and just symlink init.el to ~/.emacs, it figures out all paths from there. It'll also load platform-specific code, if you need that).

I try and make it lazier by combining autoload and eval-after-load, which helps with startup time.

On an organisational point (still work to be done here!), init.el mostly just loads a bunch of other files, which are roughly grouped by task or mode. Github has been a huge boon, combined with submodules to track a lot of third-party extensions.

I don't change many key bindings (most notable is the Yegge-suggested C-w for backward-kill-word), but I do have a /lot/ of extensions installed. I'm a fairly heavy user, although almost exclusively as an editor (+ lisp or python interaction, etc) -- I don't use it as a mail client, browser, or anything along those lines. The furthest away I get is the occasional twitter or IRC usage.

While I'm rambling: I'd like to make all my key-binding specifications consistent. Currently I have a mix of string specifications, vectors, kbd macros, etc. Does anyone know what the canonical approach is these days? Extra reference: http://www.nongnu.org/emacs-tiny-tools/keybindings/ and http://www.emacswiki.org/emacs/KeyBindingNotation

(comment deleted)
You'll want to check out dotfiles.com also, btw. I considered putting this in a separate link, but thought that since you asked, it wouldn't be too terrible to post here. There are a few things I include in every .emacs file I have across multiple shell accounts, and this is more or less the entirety of it:

  ;; how emacs behaves generally
  (setq scroll-step 1)
  (setq next-line-add-newlines nil)
  (setq search-highlight t)
  (setq-default indent-tabs-mode nil)

  ;; some niceties on the status bar
  (display-time)
  (setq column-number-mode t)
  (setq line-number-mode t)

  ;; other shortcuts
  (global-set-key "\C-^" 'enlarge-window)
  (global-set-key "\C-c\C-w" 'compare-windows)

  ;; fix broken backspace
  (global-set-key "\b" 'backward-delete-char)
  (global-set-key "\C-xt" 'term)

  ;; UTF-8 goodness
  (set-terminal-coding-system 'utf-8)
  (set-keyboard-coding-system 'utf-8)
  (prefer-coding-system 'utf-8)

  ;; I'm into Perl, but prefer cperl-mode over the default
  (defun modify-alist (alist-symbol key value &optional search-cdr)
    (let ((alist (symbol-value alist-symbol)))
      (while alist
        (if (eq (if search-cdr
                    (cdr (car alist))
                  (car (car alist))) key)
            (setcdr (car alist) value)
          (setq alist (cdr alist))))))
    
  (modify-alist 'interpreter-mode-alist 'perl-mode 'cperl-mode t)
  (modify-alist 'auto-mode-alist        'perl-mode 'cperl-mode t)

  ;; the one true indentation level
  (setq cperl-indent-level 4)
Wait - I thought it was dotfiles.org? It went down a few months ago and hasn't returned. I'm not getting a response from dotfiles.com either.
I wrote a long article and at the last paragraph, I decided to edit a sentence, I selected the "region" and pressed C-w to remove it :-(

For uninitiated, C-w is "yank text", i.e. cut it, and Firefox it is "close current tab without warning".

Seems the keybindings skip direct to the semantics in your brain, without passing through verbose names; C-w would "kill" the text.

Still, your lapse is pretty good. Sometimes I can't even name the keys -- but my fingers know :)

C-S-t in Firefox will bring it back. Don't know if the content of the text field remains though.
It does. It's not that hard to test.
(comment deleted)
;; Easymacs sets some common Windows key bindings like ctrl-c to copy, ctrl-s to save, etc. (load "c:/Otech/programs/easymacs/easymacs.el")

(defun init-streamfocus () (interactive)

;; Slime is for starting or connecting to SBCL ;; To start: C-x slime RET (add-to-list 'load-path "c:/Otech/sf/lib/slime")

;;(setq inferior-lisp-program "C:/Otech/programs/sbcl-1.0.9/sbcl")

                                        ;(setq inferior-lisp-program "C:/Program Files/LispWorks/lispworks-4450")
(add-hook 'lisp-mode-hook (lambda () (slime-mode t))) (add-hook 'inferior-lisp-mode-hook (lambda () (inferior-slime-mode t))) ;; (defun lw-start () ;; (interactive) ;; (shell-command (concat "C:/Program Files/LispWorks/lispworks-4450.exe -multiprocessing " ;; "-init c:/Otech/swank.lisp&")))

;;;For SBCL on Windows ;(setq inferior-lisp-program "sbcl") ;(add-to-list 'load-path "C:/Program Files/Steel Bank Common Lisp/1.0.22/sbcl.exe")

;;For Allegro on Windows (setq inferior-lisp-program "allegro") (add-to-list 'load-path "C:/Program Files/acl81/allegro.exe")

(require 'slime) (slime-setup '(slime-fancy slime-banner))

;;allegro (global-set-key "\C-cs" 'slime-selector) (setq slime-complete-symbol-fancy t) (setq slime-complete-symbol-function 'slime-fuzzy-complete-symbol)

(setq slime-multiprocessing t) ;; choose one of the below based on Express or non-Express usage ;(setq slime-lisp* "alisp.exe") (setq slime-lisp "allegro.exe")

  ;;(setq *slime-lisp* "allegro-express.exe")
  (setq *slime-port* 4005)
  
  (global-set-key
   [(f5)]
   '(lambda ()
      (interactive)
      (shell-command 
       (format "%s +B +cm -L c:/.slime.lisp -- -p %s --ef %s &"
               *slime-lisp* *slime-port*
               slime-net-coding-system))
      (delete-other-windows)
      (while (not (ignore-errors (slime-connect "localhost" *slime-port*)))
        (sleep-for 0.2))))  
  
  (let* ((cygwin-root "c:/cygwin")
         (cygwin-bin (concat cygwin-root "/bin")))
                                        ;(setenv "HOME" (concat cygwin-root "/home/frederick"))
    (setenv "PATH" (concat cygwin-bin ";" (getenv "PATH")))
    (setq exec-path (cons cygwin-bin exec-path)))
  (setq shell-file-name "bash")
  (setq explicit-shell-file-name "bash")
  
  (push ".fasl" completion-ignored-extensions)
  (push ".git" completion-ignored-extensions)

  ;;--------------------------------------
;;;; For remote slime ;; see http://a1k0n.net/blah/archives/2005/11/04/T18_00_44/index.ht... (require 'tramp) (defvar cayenne-path "/sshx:streamfocus@cayenne:") (defvar current-tramp-path nil)

  (defun slime-connect-to-host (path port)
    (setq *current-tramp-path* path)
    (setq slime-translate-from-lisp-filename-function
          (lambda (f)
            (if *current-tramp-path*
                (concat *current-tramp-path* f)
              f)))
    (setq slime-translate-to-lisp-filename-function
          (lambda (f)
            (if *current-tramp-path*
                (substring f (length *current-tramp-path*))
              f)))
    (slime-connect "localhost" port))
  
  (defun cayenne-slime ()
    (interactive)
    (slime-connect-to-host *cayenne-path* 4006))
  
  (defun cayenne-find-file ()
    (interactive)
    (find-file (concat *cayenne-path* "/home/streamfocus/sf/")))
  
  
;;;; TRAMP remote editing. See notes for NTEmacs on http://www.emacswiki.org/cgi-bin/wiki/TrampMode (setq tramp-default-method "sshx") ;;;; SLIME settings to edit remote files on rembrandt ;(push (list "^cayenne$" ; (lambda (emacs-filename) ; (subseq emacs-filename (length "/cayenne:"))) ; (lambda (lisp-file...
Apart from the usual utilities, I've got an emacs-lisp version of write-or-die; it deletes words if you stop typing for more than a few seconds. It's an excellent motivator for first drafts.
Some key ones

(setq transient-mark-mode t) ; visually show region

(setq line-number-mode t) ; show line numbers

(setq global-font-lock-mode 1) ; everything should use font

(windmove-default-keybindings) ; shift-arrow key moves to window in that direction

I set up `webjump' to search online API documentation

http://justinsboringpage.blogspot.com/2009/05/emacs-searchin...

I like to send gmail

http://justinsboringpage.blogspot.com/2009/02/sending-mail-w...

I think this is the most important one

(setq visible-bell t) ; annoying beeps off

I used to set transient-mark-mode to t myself. But being able to set a mark and use C-xC-x to switch the cursor and the mark point is too powerful. It allows you to set a mark, go edit something else, and then go back to where you were.

Granted, you could probably do that with transient mark mode, but seeing everything highlighted would be too annoying.

You can do the same thing with bm.el, but you also get multiple bookmarks (visible in the buffer) which you can then cycle through. I find it helpful to have bookmarks and the region decoupled.

http://www.nongnu.org/bm/

C-u C-SPC cycles through the mark ring and works with transient-mark. Just use C-g to deactivate the region so everything isn't highlighted.
I am completely surprised no one has linked to technomancy's emacs-start-kit: https://github.com/technomancy/emacs-starter-kit

Clone that as your emacs.d, add a .el file named the same as your logged in user, and add your specific preferences there. (I like to have it include stuff in a jmhodges directory in emacs.d, of course.)

On that note, my own fork of it with very minor personal changes: https://github.com/jmhodges/emacs-starter-kit

technomancy is a great developer and an excellent teacher
Pretty new to emacs, so my first move was to make it more familiar and avoid breaking my fingers:

;; Switch buffer

(global-set-key [f5] 'buffer-menu)

;; Save and load

(global-set-key [f2] 'save-buffer)

(global-set-key [f3] 'find-file)

;; Compile file

(global-set-key [f9] 'slime-compile-and-load-file)

;; Goto line

(global-set-key "\M-l" 'goto-line)

;; Go to other window

(global-set-key (kbd "<C-tab>") 'other-window)

;; And probably the most useful one, numpad Enter for eval line:

(global-set-key (kbd "<kp-enter>") 'slime-eval-last-expression)