Emacs configuration

This file is used by org-babel to generate emacs.el from it. emacs.el is then loaded as my Emacs configuration and only re-generated when the org file changes.

Basic configuration

Load path

(setq dotfiles-dir (file-name-directory
                    (or load-file-name (buffer-file-name))))

(if (file-symlink-p (directory-file-name dotfiles-dir))
    (setq dotfiles-dir (file-truename dotfiles-dir)))

(add-to-list 'load-path dotfiles-dir)
(add-to-list 'load-path
             (expand-file-name "src" dotfiles-dir))

(add-to-list 'load-path "/home/andi/tmp/auctex-20110327-a")

;; No Gnus
(add-to-list 'load-path
             (expand-file-name
              "lisp"
              (expand-file-name "gnus"
                                (expand-file-name "src" dotfiles-dir))))
(require 'gnus-load)

;; org-mode
(add-to-list 'load-path
             (expand-file-name
              "lisp"
              (expand-file-name "org-mode"
                                (expand-file-name "src" dotfiles-dir))))

;; hehe, and I've some Lisp files in my Dropbox :)
(add-to-list 'load-path "~/Dropbox/lisp")

(setq package-user-dir (concat dotfiles-dir "elpa"))
;;  (setq custom-file (concat dotfiles-dir "custom.el"))

Default packages

These defaults are copied from the Emacs start kit:

(require 'cl)
(require 'saveplace)
(require 'ffap)
(require 'uniquify)
(require 'ansi-color)
(require 'recentf)
(require 'tramp)

Appearance

UI

The most basic look and feel for Emacs.

;; no startup message please
(setq inhibit-startup-message t)

;; Show column numbers
(column-number-mode 1)

;; Disable menu bar, toolbar and scrollbar. We don't need that stuff...
(menu-bar-mode -1)
(when window-system
  (tool-bar-mode -1)
  (scroll-bar-mode -1))

;; Show date and time in 24h format in modeline
(setq display-time-day-and-date t)
(setq display-time-24hr-format t)
(display-time-mode 1)

;; shhht, give me some time to think, don't blink
(blink-cursor-mode 0)

;; show matching parens
(show-paren-mode 1)

;; let tabs indent 4 spaces
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq indent-line-function 'insert-tab)

;; Set default font
;; In case of "Cousine" don't use the "-Latin.ttf" vesions of the font
;; files (those versions are provided in the zip file from Google's
;; webfonts page). The ttf files are also available here:
;; http://code.google.com/p/googlefontdirectory/source/browse/#hg%2Fcousine
(condition-case nil
    (set-default-font "Cousine")
  (error (condition-case nil
             (set-default-font "Monaco")
           (error nil))))

Visibility of leading and trailing whitespace

Leading and trailing whitespace is bad (practice) in some, but not in all modes. Set show-trailing-whitespace only for modes where it's really relevant to see leading and trailing whitespace characters.

(mapc (lambda (hook)
        (add-hook hook (lambda ()
                         (setq show-trailing-whitespace t))))
      '(text-mode-hook
        emacs-lisp-mode-hook
        python-mode-hook
        js2-mode-hook
        ))

Window configuration

http://www.emacswiki.org/emacs/NumberedWindows makes it easy to switch between windows by using Alt-NUMBER to switch between windows. The number is displayed in the modeline of each window.

(require 'window-number)
(window-number-mode)
(window-number-meta-mode)

Winner Mode makes it easy to switch back to a previous window layout. You'll love this after reading some news in Gnus :)

;; Winner mode
(winner-mode 1)

Keyboard shortcuts for window management and navigation:

ShortcutDescription
Alt+1..9Switch to window 1..9 (see modeline for window number)
C-x r fStore configuration in register
C-x r jJump to register
C-c <left>Winner undo
C-c <right>Winner redo
C-x 1Delete other window (in frame)
C-x 2Split vertically
C-x 3Split horizontally
C-x ^Make selected window taller
C-x -Shrink window
C-x }Make selected window wider
C-x {Make selected window narrower
C-x +Make all windows the same height

For detail about window configuration.

ispell

Usually I need to lookup the correct spelling of english words. So let's use the american dictionary by default.

(setq ispell-dictionary "american")

Buffer managment

http://www.emacswiki.org/emacs/IbufferMode is great for switching buffers. It's even that great, that I set it as the default buffer menu :)

(autoload 'ibuffer "ibuffer" "List buffers." t)
(global-set-key (kbd "C-x C-b") 'ibuffer)

Grouping

The following configures Gnus-style grouping.

(setq ibuffer-saved-filter-groups
  (quote (("default"
           ("Programming" ;; prog stuff not already in MyProjectX
              (or
                (mode . c-mode)
                (mode . c++-mode)
                (mode . python-mode)
                (mode . emacs-lisp-mode)
                (mode . lisp-mode)
                (mode . sql-mode)
                (mode . html-mode)
                (mode . pascal-mode)
                (mode . makefile-gmake-mode)
                (mode . nxml-mode)
                (mode . yaml-mode)
                (mode . sh-mode)
                (mode . rst-mode)
                ;; etc
                ))
           ("Version Control"
            (or
             (mode . magit-mode)))
           ("Org" ;; all org-related buffers
            (or
             (mode . org-mode)
             (mode . org-agenda-mode)
             (mode . diary-mode)
             (mode . calendar-mode)
             (name . "^*Fancy Diary")
             ))
           ("Mail"
            (or  ;; mail-related buffers
             (mode . message-mode)
             (mode . mail-mode)
             (mode . gnus-article-mode)
             (mode . gnus-summary-mode)
             (mode . gnus-group-mode)
             (mode . bbdb-mode)
             (name . "^\\.bbdb$")
             (name . "^\\.newsrc-dribble")
             (name . "^\\*-jabber.*")
             ;; etc.; all your mail related modes
             ))
           ("Emacs"
            (or
             (name . "^\\*scratch\\*$")
             (name . "^\\*Messages\\*$")
             (name . "^\\*ielm\\*$")
             (mode . help-mode)))
           ("Chat"
            (or
             (mode . garak-mode)
             (name . "^\\*Garak\\*$")
             (mode . twittering-mode)))
           ("Dired"
            (or
             (mode . dired-mode)))
           ))))

(add-hook 'ibuffer-mode-hook
  (lambda ()
    (ibuffer-switch-to-saved-filter-groups "default")))

Hiding

The following hides a bunch of uninteresting buffers from the buffer list. You can always switch to those buffers directly, i.e. "C-x b .newsrc-dribble".

(setq ibuffer-never-show-predicates
      (list
       ;; Gnus development version
       "^\\*nnimap"
       "^\\*gnus trace"
       "^\\*imap log"
       ;; Elim
       "^\\*elim"
       ;; others
       "^\\*Completions\\*$"
       "^\\*BBDB\\*$"
       "^\\.bbdb$"
       "^\\.newsrc-dribble$"
       "^\\*magit-"        ;; magit stuff
       "^\\*fsm-debug"     ;; jabber
       "\\.org_archive$"   ;; orgmode archive files
       "^\\*jekyll-aa\\*$" ;; local jekyll server
))

Dired

My Dired setup is pretty basic since I usually hop into a terminal running in another window to do my stuff there. So my http://www.emacswiki.org/emacs/DiredMode configuration is basically loading the extra features (dired-x) and configuring autosave and backup files I don't want to see by default.

(require 'dired-x)
(setq dired-omit-files 
      (rx (or (seq bol (? ".") "#")         ;; emacs autosave files 
              (seq "~" eol)                 ;; backup-files 
              (seq bol "svn" eol)           ;; svn dirs 
              (seq ".pyc" eol)
              )))
(setq dired-omit-extensions 
      (append dired-latex-unclean-extensions 
              dired-bibtex-unclean-extensions 
              dired-texinfo-unclean-extensions))
(add-hook 'dired-mode-hook (lambda () (dired-omit-mode 1)))
(put 'dired-find-alternate-file 'disabled nil)

TODO IDO - Interactively Do Things

Ido is a bitch and I'm not sure if I really like it. OTOH I don't want to miss it in the minibuffer… So my Ido setup is verrry basic, but still annoying sometimes. There are a lot of (not to say way too much) configuration examples on http://www.emacswiki.org/emacs/InteractivelyDoThings.

(ido-mode t)
(setq ido-enable-flex-matching t)

Web browser

Chromium is the default browser in this tiny universe. So let's use it:

(setq browse-url-browser-function 'browse-url-generic
      browse-url-generic-program "chromium-browser")

…but we want to use w3m too. Here's some basic configuration for this fine piece of software:

(autoload 'w3m-goto-url "w3m" "Ask a WWW browser to show a URL." t)
(setq w3m-use-cookies t)

ELPA

(setq package-archives
      '(("ELPA" . "http://tromey.com/elpa/")
        ("gnu" . "http://elpa.gnu.org/packages/")
        ("sunrise" . "http://joseito.republika.pl/sunrise-commander/")))
(setq package-user-dir (concat dotfiles-dir "elpa"))
(require 'package)
(package-initialize)

Shell

Enable ANSI colors for the shell by default.

(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)

Emacs Daemon

Fire up emacs server if not running already.

(server-mode)
(if (not (server-running-p))
    (server-start))

Copy & Paste

See CopyAndPaste.

(setq x-select-enable-clipboard t)

Misc.

Settings that didn't fit in another section.

;; y or n is enough
(defalias 'yes-or-no-p 'y-or-n-p)

;; never forget passwords
(setq password-cache-expiry nil)

Org-Mode

Diary and Calendar

The diary file is stored in the same directory as my agenda files. The main reason is that this directory is synced between different machines.

(setq diary-file "~/org/diary")

Finally make the calendar display a bit more fancy. See http://www.emacswiki.org/emacs/DiaryMode.

(setq view-diary-entries-initially nil
      mark-diary-entries-in-calendar t
      number-of-diary-entries 7
      diary-show-holidays-flag nil
      calendar-week-start-day 1 ;; week starts on Monday
)
(add-hook 'diary-display-hook 'fancy-diary-display)
(add-hook 'today-visible-calendar-hook 'calendar-mark-today)

The calendar should show the week numbers too. This snippet is copied from http://www.emacswiki.org/emacs/CalendarWeekNumbers, there's also some discussions about an "official" implementation.

(setq calendar-intermonth-text
      '(propertize
        (format "%2d"
                (car
                 (calendar-iso-from-absolute
                  (calendar-absolute-from-gregorian (list month day year)))))
        'font-lock-face 'font-lock-function-name-face))

Let calendar (and google-maps) know where home is:

(setq calendar-latitude 50.553065)
(setq calendar-longitude 6.757740)
(setq calendar-location-name "Bad Münstereifel")

Editing

Basic configuration

By default truncate lines is not enabled in org-mode, but I prefer to have it enabled:

(add-hook 'org-mode-hook
          (lambda ()
            (toggle-truncate-lines)))

And finally some more customizations:

(setf org-tags-column -75) ;; plays nicely with 80 char terminals
Links

Link abbreviations have two big advantages: You don't need to type too much. And without a link description you easily see where a links points too, e.g. the link emacswiki:DiaryMode is pretty self-explaining. See http://orgmode.org/manual/Link-abbreviations.html for details.

(setq org-link-abbrev-alist
      '(("emacswiki" . "http://www.emacswiki.org/emacs/%s")
        ("orgmanual" . "http://orgmode.org/manual/%s.html")))

Agenda

Add all files in the agenda directory and the diary in the agenda view:

(setq org-agenda-files '("~/org/agenda/"))
(setq org-agenda-include-diary t)

Tasks

Here's my TODO sequence. Markers are

  • '!' - record timestamp
  • '@' - record a note
  • '/!' - record a timestamp when leaving the state (iff target state doesn't alread logs a timestamp).
(setq org-todo-keywords
      '((sequence "TODO(t)" "WAITING(w@/!)" "NEXT(n!)" "STARTED(s!)"
                  "LATER(l@)"
                  "|" "MAYBE(m!)" "DONE(d!)" "CANCELLED(c!)")))

Part 2 is just to define some faces for the keywords:

(setq org-todo-keyword-faces
      (quote (("TODO"      :foreground "red"          :weight bold)
              ("STARTED"   :foreground "blue"         :weight bold)
              ("DONE"      :foreground "forest green" :weight bold)
              ("WAITING"   :foreground "yellow"       :weight bold)
              ("MAYBE"     :foreground "goldenrod"    :weight bold)
              ("CANCELLED" :foreground "orangered"    :weight bold)
              ("LATER"     :foreground "LightYellow4" :weight bold)
              ("NEXT"      :foreground "gold"         :weight bold))))

Hmmm… I have this in my current conf, but I don't know what it actually does… However, refiling tasks works as expected with this snippet.

(setq org-refile-use-outline-path 'file)
(setq org-refile-targets '((org-agenda-files . (:level . 1))))

By default checkbox counts are for direct children only. Setting this to nil sums up the counts for all children:

(setq org-hierarchical-checkbox-statistics nil)

Even with this option set, the way how checkbox counts are summed up seems to be somewhat flaky. It only seems to work, if every list item has a checkbox, i.e. list items that only exist for grouping need a checkbox too, which in turn affects the total count again. (The good news are: When you close the last item in a sub-list, you receive a double award!)

* A Heading
  - [ ] A grouping item [/]
    - [ ] Another grouping item [/]
      - [ ] Task 1
      - [ ] Task 2
    - [ ] Once again a grouping item [/]
      - [ ] Task 3

Finally, when a task is closed, log a timestamp:

(setq org-log-done 'time)

Remember

Basic setup

(setq org-default-notes-file "~/org/remember.org")

(setq remember-annotation-functions '(org-remember-annotation))
(setq remember-handler-functions '(org-remember-handler))
(add-hook 'remember-mode-hook 'org-remember-apply-template)

Templates

(setq org-remember-templates
      '( ("Todo" ?t "* TODO %^{Brief Description} %^g\n  - Added: %U%?"
          "~/org/agenda/todo.org" "Tasks")
         ("Idea" ?i "* %^{Summary} %^g\n%?"
          "~/org/ideas.org" "Ideas")
         ("Blog Post" ?p "\n* %^{Title} %^g\n  :PROPERTIES:\n  :END:\n%?\n"
          "~/web/org/2010.org" bottom)
         ("Todo (work)" ?w "* TODO %^{Brief Description}\n  SCHEDULED: %t\n  - %?"
          "~/org/agenda/prounix.org" "Tasks")
))

Export

Use CSS for highlighting source code when exporting to HTML. The default is 'inline-css', but somehow the result are good old font tags. It works when using 'css':

(setq org-export-htmlize-output-type "css")

See the documentation for this variable on how to generate the CSS styles. The basic procedure is to make sure that all required modes are loaded, e.g. by opening a file in that mode, and then calling the command org-export-htmlize-generate-css.

Clock

Setting up the clock in org-mode was somehow confusing. Most of the configuration is copy & paste - unfortunately I don't know the original location. If you (yes, you!) are missing credits here, drop me a line!

;; Resume clocking tasks when emacs is restarted
(org-clock-persistence-insinuate)
;;
;; Yes it's long... but more is better ;)
(setq org-clock-history-length 28)
;; Resume clocking task on clock-in if the clock is open
(setq org-clock-in-resume t)
;; Change task state to NEXT when clocking in
;;(setq org-clock-in-switch-to-state (quote bh/clock-in-to-next))
;; Separate drawers for clocking and logs
(setq org-drawers (quote ("PROPERTIES" "LOGBOOK" "CLOCK")))
;; Save clock data in the CLOCK drawer and state changes and notes in the LOGBOOK drawer
(setq org-clock-into-drawer "CLOCK")
;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
(setq org-clock-out-remove-zero-time-clocks t)
;; Clock out when moving task to a done state
(setq org-clock-out-when-done t)
;; Save the running clock and all clock history when exiting Emacs, load it on startup
(setq org-clock-persist (quote history))
;; Enable auto clock resolution for finding open clocks
(setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
;; Include current clocking task in clock reports
(setq org-clock-report-include-clocking-task t)

(setq org-agenda-clockreport-parameter-plist '(:link t :maxlevel 4 ))

Appointments

Load appointment mode and activate it.

(require 'appt)
(appt-activate)

Some details in http://www.emacswiki.org/emacs/AppointmentMode.

Babel

(require 'ob-ditaa)

Yasnippet

Org-Mode seems to need some extra configuration when used with Yasnippet. This fragment was in my original Emacs configuration, but - again - I need to figure out why it is needed.

(defun yas/org-very-safe-expand ()
  (let ((yas/fallback-behavior 'return-nil)) (yas/expand)))

(add-hook 'org-mode-hook
          (lambda ()
            ;; yasnippet (using the new org-cycle hooks)
            (make-variable-buffer-local 'yas/trigger-key)
            (setq yas/trigger-key [tab])
            (add-to-list 'org-tab-first-hook 'yas/org-very-safe-expand)
            (define-key yas/keymap [tab] 'yas/next-field)))

No Gnus

See "Load path" above. Gnus is loaded pretty early to avoid that the version shipped with emacs is loaded at some point.

Keep in mind that it's strongly adviced to run ./configure && make in Gnus checkout to compile Lisp files.

(require 'gnus-notify)

BBDB

Straight-forward bbdb setup. Validation of phone numbers is disabled.

(require 'bbdb)
(setq bbdb-north-american-phone-numbers-p nil) 
(bbdb-initialize)
(add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus)
(add-hook 'gnus-startup-hook 'bbdb-insinuate-message)
(add-hook 'message-setup-hook 'bbdb-define-all-aliases)

Tramp

TRAMP is a package for editing remote files. Type "/user@host:" in the minibuffer when finding a file to get TRAMP fired up. The http://www.emacswiki.org/emacs/TrampMode has a lot of tips and tricks if anything goes wrong.

Set the default method for accessing remote files to ssh.

(setq tramp-default-method "ssh")

Programming Languages

Python

(require 'ipython)
(autoload 'python-mode "python-mode" "Python Mode." t)
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(add-to-list 'interpreter-mode-alist '("python" . python-mode))

Flymake

Note: This requires tramp to be loaded. But in this setup tramp is already loaded very early.

(require 'flymake)

(setq flymake-no-changes-timeout 3)

(when (load "flymake" t)
  (load "flymake-cursor")
  (defun flymake-pyflakes-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list "pyflakes" (list local-file))))
  (add-to-list 'flymake-allowed-file-name-masks
               '("devel.+\\.py$" flymake-pyflakes-init)))

(add-hook 'python-mode-hook
          (lambda ()
            ; Activate flymake unless buffer is a tmp buffer for the interpreter
            (if (not (eq buffer-file-name nil))
                (progn
                  (flymake-mode t)
                  (local-set-key (kbd "M-n") 'flymake-goto-next-error)
                  (local-set-key (kbd "M-p") 'flymake-goto-prev-error)))))

Complexity

I've found this simple complexity checker very handy. The first column, i.e. left to the source code, is highlighted either in green, yellow or red. You can even see it change while coding - and hopefully stop and think things over when it turns red.

Unfortunately I don't know where I've found it…

(require 'linum)
(require 'pycomplexity)
(setq pycomplexity-python-path
      (expand-file-name "vim-complexity"
                        (expand-file-name "src" dotfiles-dir)))
(add-hook 'python-mode-hook
          (lambda ()
            (if (not (eq buffer-file-name nil))
                (progn
                  (pycomplexity-mode)
                  (linum-mode)
                  ))))

VirtualEnv

Virtualenv minor mode is available here: https://github.com/aculich/virtualenv.el

(require 'virtualenv)

pylint

(require 'python-pylint)
(add-hook 'python-mode-hook '(lambda ()
          (local-set-key (kbd "C-c m l") 'python-pylint)
))

HTML

Use tabs in HTML code.

(add-hook 'html-mode-hook
          (lambda()
            (setq sgml-basic-offset 2)
            (setq indent-tabs-mode t)))

JavaScript

;;  (autoload 'js2-mode "js2" nil t)
  (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
  (setq js2-basic-offset 2)
  (setq js2-auto-indent-p t)
  (setq js2-cleanup-whitespace t)
  (setq js2-enter-indents-newline t)
  (setq js2-indent-on-enter-key t)
  (add-hook 'js2-mode-hook
              (lambda()
                (setq indent-tabs-mode t)))

CSS

(setq css-indent-offset 2)

ReStructuredText

(require 'rst)
(setq auto-mode-alist
      (append '(("\\.txt$" . rst-mode)
                ("\\.rst$" . rst-mode)
                ("\\.rest$" . rst-mode)
                ("\\.wiki$" . rst-mode)
                ("README" . rst-mode)
                ("CHANGES" . rst-mode)
                ("TODO" . rst-mode)) auto-mode-alist))

LaTeX and friends

(load "auctex.el" nil t t)
(load "preview-latex.el" nil t t)
(add-hook 'LaTeX-mode-hook 'turn-on-reftex)

bibtext-utils is a nice addition to the BibTeX stuff comming with Auctex/Emacs.

(require 'bibtex-utils)

Generate PDF instead of DVI:

(add-hook 'LaTeX-mode-hook 'TeX-PDF-mode)

Enable Math mode by default, I use it quite often:

(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)

YAML

(require 'yaml-mode)
(add-to-list 'auto-mode-alist '("\\.yaml$" . yaml-mode))

Go

(require 'go-mode-load)

Pascal

Yope, I currently need it. But expect this part to be removed pretty soon again :-)

(add-hook 'pascal-mode-hook
          (lambda ()
            (set (make-local-variable 'compile-command)
                 (concat "gpc "
                         "--standard-pascal "
                         "--extended-pascal "
                         "--disable-keyword=\"case\" "
                         "--pedantic "
                         (file-name-nondirectory (buffer-file-name)))
                 ))
          t)

Version Control

Git

Magit is really cool when working with Git repositories. The entry point is "M-x magit-status". See the cheatsheet for key bindings.

(add-to-list 'load-path
             (expand-file-name "magit"
                               (expand-file-name "src" dotfiles-dir)))
(require 'magit)
(require 'magit-svn)

Mercurial

(require 'mercurial)

Extra packages

yasnippet

Load the package from src.

(require 'yasnippet)
(yas/initialize)

Configure snippet directory and load it

(setq yas/root-directory (expand-file-name "snippets" dotfiles-dir))
(yas/load-directory yas/root-directory)

Edit server extension (Chromium)

That's an nice addition. An extension for the Chromium browser that adds a little "edit" button to every textarea. When you click on it a new frame pops up in your Emacs and you can edit the field there. Setting edit-server-new-frame to nil is needed when Emacs runs in daemon mode.

(require 'edit-server)
(setq edit-server-new-frame nil)
(edit-server-start)

Jabber

Load Jabber package and configure GTalk account. See http://www.emacswiki.org/emacs/JabberEl for customization hints.

(add-to-list 'load-path
             (expand-file-name "jabber"
                               (expand-file-name "src" dotfiles-dir)))
(load "jabber-autoloads")
(setq jabber-account-list
      '(("albrecht.andi@googlemail.com" 
         (:network-server . "talk.google.com")
         (:connection-type . ssl))))
(setq jabber-default-show "")
(setq jabber-show-offline-contacts nil)

Color theme

;; (set-background-color "black")
;; (load-theme 'naquadah)
(require 'color-theme)
(setq color-theme-is-global t)
(color-theme-initialize)

(load "color-theme-tangotango")
(load "color-theme-leuven")

(setq my-color-themes (list
  'color-theme-tangotango
  'color-theme-leuven
))

(defun my-theme-set-default () ; Set the first row
  (interactive)
  (setq theme-current my-color-themes)
  (funcall (car theme-current)))

(defun my-describe-theme () ; Show the current theme
  (interactive)
  (message "%s" (car theme-current)))

; Set the next theme (fixed by Chris Webber - tanks)
(defun my-theme-cycle ()
  (interactive)
  (setq theme-current (cdr theme-current))
  (if (null theme-current)
      (setq theme-current my-color-themes))
  (funcall (car theme-current))
  (message "%S" (car theme-current)))

(setq theme-current my-color-themes)
(setq color-theme-is-global nil) ; Initialization
(my-theme-set-default)
(global-set-key [f4] 'my-theme-cycle)

nav

Emacs nav-mode provides a lightweight sidebar to access files, buffers and tags. M-x nav toggles the nav sidebar. See this wiki page for more shortcuts.

(add-to-list 'load-path
             (expand-file-name "emacs-nav"
                               (expand-file-name "src" dotfiles-dir)))
(require 'nav)

Column marker

http://www.emacswiki.org/emacs/ColumnMarker highlights one or more columns. I'm using it for the 80-column rule.

(require 'column-marker)
(mapc (lambda (hook)
        (add-hook hook (lambda () (interactive) (column-marker-1 80))))
      '(org-mode-hook
        emacs-lisp-mode-hook
        python-mode-hook
        js2-mode-hook
        text-mode-hook))

WinRing    contextswitch

With WinRing you can switch between named window configurations. It makes context switching much easier.

TODO Improvements

  • Is there a way to define default window configurations? Or do I have to start every day from scratch?
(require 'winring)
(winring-initialize)

Twitter

TwitteringMode is added as a submodule in my git repository. Type M-x twit to get started.

(add-to-list 'load-path
             (expand-file-name "twittering-mode"
                               (expand-file-name "src" dotfiles-dir)))
(require 'twittering-mode)
(if (window-system)
    (setq twittering-icon-mode t))
(setq twittering-timer-interval 300)
(setq twittering-use-master-password t)

Elim

(add-to-list
 'load-path
 (expand-file-name "elisp"
                   (expand-file-name "elim"
                                     (expand-file-name "src"
                                                       dotfiles-dir))))
(autoload 'garak "garak" nil t)
(setq garak-hide-offline-buddies t)

Elim stores private information in a directory elim on the same level as the generated emacs.el (this file). Therefore I've added this auto-generated elim directory to .gitignore.

Google Maps

See homepage for install instructions and shortcuts.

For org-mode it's C-c M-L to enter a location and C-c M-l to view a location.

(add-to-list 'load-path
             (expand-file-name "google-maps"
                               (expand-file-name "src" dotfiles-dir)))
(require 'google-maps)
(require 'org-location-google-maps)

Homepage and blog

This is the configuration that drives my homepage and blog.

Load some additional org-mode packages for publishing and define the project.

(require 'org-install)
(require 'org-publish)
(require 'htmlize)

(setq org-publish-project-alist
      '(
        ("org-andi"
         ;; Path to your org files.
         :base-directory "~/web/org/"
         :base-extension "org"
         :exclude "/files/"

         ;; Path to your Jekyll project.
         :publishing-directory "~/web/jekyll/"
         :blog-publishing-directory "~/web/jekyll/blog/"
         :site-root "http://andialbrecht.de"
         :jekyll-sanitize-permalinks t
         :recursive t
         :publishing-function org-publish-org-to-html
         :headline-levels 4
         :html-extension "html"
         :body-only t ;; Only export section between <body> </body>
         )
        ("org-static-andi"
         :base-directory "~/web/org/"
         ;:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|html\\|tgz"
         :base-extension ".*"
         :publishing-directory "~/web/jekyll/"
         :recursive t
         :publishing-function org-publish-attachment)
        ("andi" :components ("org-andi" "org-static-andi"))

))

Now load my fork of org-jekyll. Marking drafts as TODO items has the benefit, that they easily show up in the agenda (yes, I want to finish them). org-jekyll-entry-match is a customization of org-jekyll provided by my fork on github.

(add-to-list 'load-path
             (expand-file-name "org-jekyll"
                               (expand-file-name "src" dotfiles-dir)))
(require 'org-jekyll)
(setq org-jekyll-entry-match "+blog-TODO=\"TODO\"")

And finally load some custom functions that make it easy to generate the pages, start a Jekyll server for devlopment and publish the generated files to my server.

(require 'aa-homepage)

Custom functions

Show/hide menu bar and tool bar

Sometimes it's useful to actually have a menu bar and tool bar.

(defun aa/toggle-chrome ()
  "Show/hide toolbar and menubar."
  (interactive)
  (menu-bar-mode)
  (when (window-system)
    (tool-bar-mode)))

(global-set-key [f5] 'aa/toggle-chrome)

Toggle fullscreen

Toggle fullscreen function by using wmctrl as found on the EmacsWiki.

(defun switch-full-screen ()
  (interactive)
  (shell-command "wmctrl -r :ACTIVE: -btoggle,fullscreen"))

(global-set-key [f11] 'switch-full-screen)

Set window width or height

The following two functions prompt for a width/height in columns and tries to set the window size accordingly.

(defun aa/window-set-size-internal (is-width)
  "Prompts for window size (in columns) and adjusts buffer accordingly."
  (if is-width
      (progn
        (setq size (window-width))
        (setq prompt "Width: "))
    (progn
      (setq size (window-height))
      (setq prompt "Height: ")))
  (setq reqsize (string-to-int
                 (read-from-minibuffer prompt (format "%d" size))))
  (if (> reqsize size)
      (enlarge-window (- reqsize size) is-width)
    (shrink-window (- size reqsize) is-width)))

(defun aa/window-set-width ()
  "Set window width."
  (interactive)
  (aa/window-set-size-internal t)
)

(defun aa/window-set-height ()
  "Set window height."
  (interactive)
  (aa/window-set-size-internal nil)
)

Key Bindings

Applications

(global-set-key (kbd "C-c j") 'jabber-connect-all)
(global-set-key (kbd "C-c J") 'jabber-send-presence)
(global-set-key (kbd "C-c g") 'magit-status)
(global-set-key (kbd "C-c w") 'w3m-goto-url)

Org-Mode

(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-ca" 'org-agenda)
(global-set-key "\C-cb" 'org-iswitchb)
(global-set-key "\C-cr" 'org-remember)
(global-set-key "\C-cn" 'org-insert-todo-heading)
(global-set-key "\C-cN" 'org-insert-todo-subheading)
(global-set-key "\C-x\r" 'org-insert-todo-heading-respect-content)

Actions

(global-set-key (kbd "<f5>") 'browse-url-at-point)

(global-set-key "\C-c;" 'comment-or-uncomment-region)
(global-set-key "\C-cm" 'gnus-msg-mail) ;; hm... looks strange :)

(global-set-key (kbd "C-<f12>") 'save-buffers-kill-emacs)
(global-set-key (kbd "M-<f12>") 'fullscreen)

(global-set-key (kbd "<f2>") 'nav)
(global-set-key (kbd "<f7>") 'py-shell)

The default prefix key for WinRing C-x 7- is a bit awkward. F6 is much easier to remember:

(global-set-key (kbd "<f6>") 'winring-next-configuration)
(global-set-key (kbd "C-<f6>") 'winring-jump-to-configuration)

Let's bind F8 to various toggle actions:

(defun aa/flyspell-mode-en ()
  (interactive)
  (progn
    (if (equal (flyspell-mode) t)
        (ispell-change-dictionary "american")
      )))

(defun aa/flyspell-prog-mode-en ()
  (interactive)
  (progn
    (if (equal (flyspell-prog-mode) t)
        (ispell-change-dictionary "american")
      )))

(defun aa/flyspell-mode-de ()
  (interactive)
  (progn
    (if (equal (flyspell-mode) t)
        (ispell-change-dictionary "german8")
      )))

(defun aa/flyspell-prog-mode-de ()
  (interactive)
  (progn
    (if (equal (flyspell-prog-mode) t)
        (ispell-change-dictionary "german8")
      )))

(global-set-key (kbd "<f8> w") 'whitespace-mode)
(global-set-key (kbd "<f8> c") 'comment-or-uncomment-region)
(global-set-key (kbd "<f8> f f") 'aa/flyspell-mode-en)
(global-set-key (kbd "<f8> f g") 'aa/flyspell-mode-de)
(global-set-key (kbd "<f8> f p f") 'aa/flyspell-prog-mode-en)
(global-set-key (kbd "<f8> f p g") 'aa/flyspell-prog-mode-de)

Key Bindings Reminder

This section lists some key bindings. For some reason I've troubles to remember those listed here.

Gnus

KeyDescription
W wArticle washing: Do word wrap
W W cArticle hiding: Hide citations