1 load extra extensions

Register custom Emacs extensions directory. I downloaded there various emacs extensions from the internet.

(add-to-list 'load-path "~/.emacs.d/extensions/")

Load some useful extensions from that directory.

(require 'bind-key)             ;; utility to simplify key binding
(require 'ox-twbs)              ;; utility to export Twitter Bootstrap themed HTML
(require 'ox-odt)               ;; add ODT export option to the export menu

1.1 Maxima integration

(push "/usr/local/share/emacs/site-lisp" load-path)
(autoload 'imaxima "imaxima" "Maxima frontend" t)
(autoload 'imath "imath" "Interactive Math mode" t)

2 file handling

2.1 convert tabs to spaces

More modes: http://www.emacswiki.org/CategoryModes

(defun untab-all ()
  (untabify (point-min)

(defun add-write-contents-hooks-hook ()
  (add-hook 'write-contents-hooks 'untab-all nil t ))

(add-hook 'emacs-lisp-mode-hook     #'add-write-contents-hooks-hook)
(add-hook 'c-mode-common-hook       #'add-write-contents-hooks-hook)
(add-hook 'sh-mode-hook             #'add-write-contents-hooks-hook)
(add-hook 'text-mode-hook           #'add-write-contents-hooks-hook)
(add-hook 'sql-mode-hook            #'add-write-contents-hooks-hook)
(add-hook 'css-mode-hook            #'add-write-contents-hooks-hook)

;; matches *.properties files
(add-hook 'conf-javaprop-mode-hook  #'add-write-contents-hooks-hook)

2.2 remove trailing whitespace

(add-hook 'before-save-hook 'delete-trailing-whitespace)

2.3 disable saving of backups

Disable those backup files with ~ suffix, because I keep important files under version control anyway.

(setq make-backup-files nil)

2.4 automatically reload files that were changed on disk by another process

(global-auto-revert-mode 1)

2.5 automatically save edited files

This prevents accidently leaving edited files open in the background with important unsaved changes, especially when using emacsclient with emacs daemon.

Save edited files when Emacs frame looses focus.

(defun save-all ()
    (save-some-buffers t))

(add-hook 'focus-out-hook 'save-all)

Save edited files when Emacs frame is closed.

(defun save-all2 (frame)
    (save-some-buffers t))

(add-hook 'delete-frame-functions 'save-all2)

2.6 make indentation commands use space only (never tab character)

emacs 23.1, 24.2, default to t

(setq-default indent-tabs-mode nil)

3 visual tweaks

3.1 better theme

Register custom Emacs themes directory.

(add-to-list 'custom-theme-load-path "~/.emacs.d/themes")

Load nice looking color theme.

(load-theme 'spolsky t)

3.2 enable current line highlighting

Enable highlighting

(global-hl-line-mode 1)

Ensure that no underlines are used for current line highlight.

(set-face-attribute hl-line-face nil :underline nil)

3.3 show opened file in window title

Show only file name (no path) in window title.

(setq-default frame-title-format "%b")

4 basic text editing customizations

4.1 keyboard shortcuts to ident/dedent selected region

  • Idents/dedents by 4 spaces.
  • Select text and use keys: <, >
(defun my-indent-region (N)
  (interactive "p")
  (if (use-region-p)
      (progn (indent-rigidly (region-beginning) (region-end) (* N 4))
             (setq deactivate-mark nil))
    (self-insert-command N)))

(defun my-unindent-region (N)
  (interactive "p")
  (if (use-region-p)
      (progn (indent-rigidly (region-beginning) (region-end) (* N -4))
             (setq deactivate-mark nil))
    (self-insert-command N)))

(global-set-key ">" 'my-indent-region)
(global-set-key "<" 'my-unindent-region)

4.2 mouse middle click should paste at text cursor location

Otherwise, by default it inserts text at mouse click location.

(setq mouse-yank-at-point t)

4.3 enable upcase-region / downcase-region commands

For mysterious reasons these commands are disabled by default because they are unfriendly for beginners. Here we enable them anyway.

Commands convert selected region into upper or lower case.

(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)

4.4 text alignment addons

(defun align-to-colon (begin end)
  "Align region to colon (:) signs"
  (interactive "r")
  (align-regexp begin end
                (rx (group (zero-or-more (syntax whitespace))) ":") 1 1 ))

(defun align-to-comma (begin end)
  "Align region to comma signs"
  (interactive "r")
  (align-regexp begin end
                (rx "," (group (zero-or-more (syntax whitespace))) ) 1 1 ))

(defun align-to-equals (begin end)
  "Align region to equal signs"
  (interactive "r")
  (align-regexp begin end
                (rx (group (zero-or-more (syntax whitespace))) "=") 1 1 ))

(defun align-to-hash (begin end)
  "Align region to hash ( => ) signs"
  (interactive "r")
  (align-regexp begin end
                (rx (group (zero-or-more (syntax whitespace))) "=>") 1 1 ))

;; work with this
(defun align-to-comma-before (begin end)
  "Align region to equal signs"
  (interactive "r")
  (align-regexp begin end
                (rx (group (zero-or-more (syntax whitespace))) ",") 1 1 ))

4.5 enable scroll commands

For mysterious reasons these commands are disabled by default because they are unfriendly for beginners. Here we enable them anyway.

(put 'scroll-left 'disabled nil)
(put 'scroll-right 'disabled nil)

4.6 enable horizontal scrolling with mouse

(global-set-key (kbd "<mouse-7>") '(lambda ()
   (scroll-left 4)))

(global-set-key (kbd "<mouse-6>") '(lambda ()
   (scroll-right 4)))

5 org-mode customizations

5.1 keyboard shortcut F5: full text search across all agenda files

(global-set-key (kbd "<f5>") 'org-search-view)

5.2 keyboard shortcut F6: publish ORG document as HTML file

Uses TWBS-HTML plugin: https://github.com/marsmining/ox-twbs

(global-set-key (kbd "<f6>") 'org-twbs-export-to-html)

5.3 keyboard shortcut F7: produce program source code from ORG document (tangle)

(global-set-key (kbd "<f7>") 'org-babel-tangle)

5.4 keyboard shortcut F8: show agenda

(global-set-key (kbd "<f8>") 'org-agenda-list)

5.5 keyboard shortcut F9: show global TODO list

(global-set-key (kbd "<f9>") 'org-todo-list)

5.6 recursively load org/agenda documents into RAM

In order to

  • use instant full text search over org mode documents
  • be able to display aggredated day/week agendas and TODO lists
  • navigate between org documents using UUID links

emacs needs to parse all org mode files after startup and before these features are used.

Recursively find .org files in provided directory.

(defun sa-find-org-file-recursively (directory &optional filext)
  "Return .org and .org_archive files recursively from DIRECTORY.
If FILEXT is provided, return files with extension FILEXT instead."
  ;; FIXME: interactively prompting for directory and file extension
  (let* (org-file-list
         (case-fold-search t)           ; filesystems are case sensitive
         (file-name-regex "^[^.#].*")   ; exclude .*
         (filext (if filext filext "org$\\\|org_archive"))
         (fileregex (format "%s\\.\\(%s$\\)" file-name-regex filext))
         (cur-dir-list (directory-files directory t file-name-regex)))
    ;; loop over directory listing
    (dolist (file-or-dir cur-dir-list org-file-list) ; returns org-file-list
       ((file-regular-p file-or-dir) ; regular files
        (if (string-match fileregex file-or-dir) ; org files
            (add-to-list 'org-file-list file-or-dir)))
       ((file-directory-p file-or-dir)
        (dolist (org-file (sa-find-org-file-recursively file-or-dir filext)
                          org-file-list) ; add files found to result
          (add-to-list 'org-file-list org-file)))))))

5.7 visual tweaks

I use underscores "_" a lot in variable/parameter names. I don't want those to be formatted as subscript.

(setq org-export-with-sub-superscripts nil)

I use * lot. I don't want those to be formatted as bold.

(setq org-export-with-emphasize nil)

Use beautiful dark theme for HTML exported files

(setq org-html-head-extra (concat "<link rel=\"stylesheet\" type=\"text/css\" href=\"http://thomasf.github.io/solarized-css/solarized-dark.min.css\" />"))

Remove leading stars for less visual garbage.

(setq org-hide-leading-stars t)

5.8 use UUID based document hyperlinks

Enable linking between org documents using global unique ID's that will be automatically generated and inserted on demand.

UUID is awesome because you can rename file or even headings within file but link will remain working.

(setq org-id-link-to-org-use-id t)

(defun anh-after-load-org ()
                (add-to-list 'org-modules 'org-id)
(eval-after-load "org" '(anh-after-load-org))
  • Map keyboard combination C-c l to store link to current location.
  • Afterwards keyboard shortcut C-c C-l inserts stored link into desired location within document.
(bind-key "C-c l" 'org-store-link)

5.9 task handling

(setq org-agenda-window-setup 'current-window)

5.9.1 todo keywords

(setq org-todo-keywords
  '((sequence "TODO" "WIP" "BLOCKED" "|" "DONE")))

5.9.2 log done dates


Then each time you turn an entry from a TODO (not-done) state into any of the DONE states, a line ā€˜CLOSED: [timestamp]ā€™ will be inserted just after the headline. If you turn the entry back into a TODO item through further state cycling, that line will be removed again. If you turn the entry back to a non-TODO state (by pressing <C-c C-t SPC> for example), that line will also be removed, unless you set org-closed-keep-when-no-todo to non-nil.

(setq org-log-done 'time)

5.10 org-mode/babel customizations

Do syntax highlighting for code blocks embedded in org documents..

(setq org-src-fontify-natively t)

Enoble ditaa support

 '((ditaa . t)))

6 private settings

6.1 load my org files

Scan all symlinks recursively under ~/.emacs.d/org/ for org files for org-mode agenda. Beware recursive loops with symlinks.

(setq org-agenda-files
       (sa-find-org-file-recursively "~/data/sync/" "org")
       (sa-find-org-file-recursively "~/data/projects/projects/" "org")
       (sa-find-org-file-recursively "~/data/liprafarm/" "org")
       (sa-find-org-file-recursively "~/workspace/" "org")