Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1689 lines (1270 sloc) 46 KB

Introduction

This is a literate version of my base emacs config. You can generate emacs init script out of it by running org-babel-tangle.

The script assumes that this folder is either checked out to ~/.emacs.d or linked to it.

;; (package-initialize)
(load-file "~/.emacs.d/build/init-main.el")
(server-start)

Common Problems

URL not null in el-get

This is caused by missing “secure” url in some recipes. Just eval function from PR (if you hit it).

Slime install

Make sure you have this: brew link texinfo –force

Emacs essentials

Help is behind C-h or F1. To be more precise, in help:

  1. w (or where-is) - to find shortcuts for the command
  2. f (of describe-function) - to learn all about function.

General settings

Home directory

Let’s define our own constant for the emacs directory and a function to get subdir:

(defconst ra/emacs-directory (concat (getenv "HOME") "/.emacs.d/"))
(defun ra/emacs-subdirectory (d) (expand-file-name d ra/emacs-directory))

I don’t recall why I still have this setting, but let it be:

(setq emacs-root-dir user-emacs-directory)

Load system-specific overrides

We might have some local custom stuff around (e.g. brew location of erlang), so let’s look up that in machine-specific file:

(setq ra/emacs-machine-init
      (expand-file-name (concat system-name ".el") ra/emacs-directory)
      )

;; (setq custom-file (expand-file-name "init-local.el" ra/emacs-directory))
(when (file-exists-p ra/emacs-machine-init)
  (load ra/emacs-machine-init))

;; This sets $MANPATH, $PATH and exec-path from your shell, but only on OS X and Linux.
(when (memq window-system '(mac ns x))
  (exec-path-from-shell-initialize))

Rinat’s rMBR

;;config for R on OSX
(setq inferior-R-program-name "/usr/local/Cellar/r/3.2.2_1/bin/R")

Setup load paths

I have two load paths, lisp for v1 logic and build for the literate version (or v2):

(add-to-list 'load-path (ra/emacs-subdirectory "lisp"))
(add-to-list 'load-path (ra/emacs-subdirectory "build"))

Add usr/local/bin

Emacs can be weird with PATH, so we set local bin path explicitly:

(add-to-list 'exec-path "/usr/local/bin/")

Tramp

(setq tramp-default-method "ssh")

Helper functions

Just a few helper functions to lighten up the day

(defun add-hook-list (callback hooks)
  "Adds callback to each one of the hooks."
  (mapc (lambda (hook)
      (add-hook hook callback))
        hooks))


(defun downcase-first-char (&optional string)
  "Capitalize only the first character of the input STRING."
  (when (and string (> (length string) 0))
    (let ((first-char (substring string nil 1))
          (rest-str   (substring string 1)))
      (concat (downcase first-char) rest-str))))

Packages

Install Package manager

Let’s install el-get, if it isn’t installed:

(add-to-list 'load-path (expand-file-name "el-get/el-get" emacs-root-dir))

(unless (require 'el-get nil 'noerror)
  (with-current-buffer
      (url-retrieve-synchronously
       "https://raw.github.com/dimitri/el-get/master/el-get-install.el")
    (let (el-get-master-branch)
      (goto-char (point-max))
      (eval-print-last-sexp))))

Load recipes from small files

We can also have dependencies spread across tiny files (legacy stuff) and load them like this:

;; load all .el files inside `modules-dir`
(setq modules-dir (expand-file-name "packages" emacs-root-dir))
(mapc 'load (directory-files modules-dir 't "^[^#].*el$"))

Describe dependencies explicitly

We can describe our common dependencies like this:

;; modern list library
(el-get-bundle dash)

(el-get-bundle queue)
(el-get-bundle dired-plus)
(el-get-bundle flycheck)
(el-get-bundle yasnippet)
(el-get-bundle company-mode)
;; Swap buffers without typing C-x b on each window
(el-get-bundle buffer-move)
(el-get-bundle hydra)
(el-get-bundle web-mode)
;; undo tree git-style
(el-get-bundle undo-tree)

(require 'company)

Common requires

(require 'dash)

Key-chords

Key-chord lets you define keystrokes (e.g. zz) which, if pressed in rapid sequence, will trigger some effect. It has a side-effect: if a key is present in a key-chord, it will work slower. So we’ll try to keep these to a bare minimum.

Let’s enable key-chord:

(el-get-bundle key-chord)
(require 'key-chord)
(key-chord-mode 1)

Display settings

Hide some things

;; I know what the scratch is for
(setq initial-scratch-message "")

;; don't show the startup help screen
(setq inhibit-startup-screen t)

;; disable alarm bell beep
(setq visible-bell t)
;; flash on OSX looks ugly
(setq ring-bell-function 'ignore)

Windows

Wind move

WindMove (in GnuEmacs v21+) lets you move point from window to window using Shift and the arrow keys. I wire it to use Super+VIM keys (CMD on OSX). This way moves are consistent with Super+Arrow keys I use for the primary window manager.

;; move to a neighbor window using SUPER + VIM KEY
(require 'windmove)
(global-set-key (kbd "s-k") 'windmove-up)
(global-set-key (kbd "s-j") 'windmove-down)
(global-set-key (kbd "s-h") 'windmove-left)
(global-set-key (kbd "s-l") 'windmove-right)

Buf move

Let’s bind similar keys (but with Shift) to move windows around:

(global-set-key (kbd "s-S-H") 'buf-move-left)
(global-set-key (kbd "s-S-J") 'buf-move-down)
(global-set-key (kbd "s-S-K") 'buf-move-up)
(global-set-key (kbd "s-S-L") 'buf-move-right)

Winner mode

Winner mode allows you to “undo” (and “redo”) changes in the window configuration with C-c left and C-c right.

(winner-mode 1)

Hydra

Hydra-based way of manipulating windows. Let’s define a few helpers (taken from hydra samples):

(defun hydra-move-splitter-left (arg)
  "Move window splitter left."
  (interactive "p")
  (if (let ((windmove-wrap-around))
        (windmove-find-other-window 'right))
      (shrink-window-horizontally arg)
    (enlarge-window-horizontally arg)))

(defun hydra-move-splitter-right (arg)
  "Move window splitter right."
  (interactive "p")
  (if (let ((windmove-wrap-around))
        (windmove-find-other-window 'right))
      (enlarge-window-horizontally arg)
    (shrink-window-horizontally arg)))

(defun hydra-move-splitter-up (arg)
  "Move window splitter up."
  (interactive "p")
  (if (let ((windmove-wrap-around))
        (windmove-find-other-window 'up))
      (enlarge-window arg)
    (shrink-window arg)))

(defun hydra-move-splitter-down (arg)
  "Move window splitter down."
  (interactive "p")
  (if (let ((windmove-wrap-around))
        (windmove-find-other-window 'up))
      (shrink-window arg)
    (enlarge-window arg)))

Ok, let’s define a hydra head for moving windows around on F2:

(defhydra ra/hydra-windows (global-map "<f2>")
  "winops"
  ("SPC" nil)
  ("<left>"  hydra-move-splitter-left)
  ("<down>" hydra-move-splitter-down)
  ("<up>" hydra-move-splitter-up)
  ("<right>" hydra-move-splitter-right)
  ("x" delete-window :color blue)
  ("X" delete-other-windows :color blue)
  ("z" (progn
        (winner-undo)
        (setq this-command 'winner-undo))
   )
  ("Z" winner-redo)
  ("r" split-window-right :color blue)
  ("b" split-window-below :color blue)
  )

Mode line

Smart mode line improves a lot normal emacs mode line by adding:

  • colors;
  • directory prefixing (e.g. convert ~/.emacs.d/ to :ED:;
  • smart truncation to work well on small displays.

Line format was taken from Sasha Chua.

;; get smart-mode-line
(el-get-bundle smart-mode-line)
;; respect the current theme
(setq sml/theme 'respectful)
;; don't ask for confirmation
(setq sml/no-confirm-load-theme t)
;; taken from Sasha Chua
(setq-default
   mode-line-format
   '("%e"
     mode-line-front-space
     mode-line-mule-info
     mode-line-client
     mode-line-modified
     mode-line-remote
     mode-line-frame-identification
     mode-line-buffer-identification
     "  "
     mode-line-position
     (vc-mode vc-mode)
     "  "
     mode-line-modes
     mode-line-misc-info
     mode-line-end-spaces))

(sml/setup)

If I ever needed to hide some minor modes, this could be done via rich-minority package.

Oh, while we are at it, let’s display battery percentage:

(display-battery-mode)

Cursor

Make the cursor blink:

;; blinking cursor
(blink-cursor-mode t)

GUI Client

Emacs can have a nice GUI window that lets you have fine-grained control over fonts and sizes. Let’s put that stuff into a separate config file and load when we have us a window system.

(require 'init-client)

Header for the client-specific file would say:

(provide 'init-client)

Fonts

I like Monaco on OSX:

(when (eq system-type 'darwin)
  ;; set default font for the frames as well (daemon + ec)
  (setq default-frame-alist '((font . "MonacoB-14")))
  (set-fontset-font t 'cyrillic "Droid Sans Mono")
  )

Color theme

I like to use solarized theme by default:

(el-get-bundle color-theme-solarized)
(load-theme 'solarized t)

It would be nice to switch to solarized dark, if needed. Let’s add hydra for that:

(defhydra hydra-themes (global-map "<f9>")
  "themes"
  ("SPC" nil)
  ("q"
   (lambda ()
     (interactive)
     (load-theme 'solarized-light t)
     )
   )
  ("w"
   (lambda ()
     (interactive)
     (load-theme 'solarized-dark t)
     )
   )
  )

Zooming with Hydra

With this simple code, hit F9 to enter zooming mode:

(defhydra hydra-zoom (global-map "<f6>")
  "zoom"
  ("+" text-scale-increase "in")
  ("=" text-scale-increase "in")
  ("-" text-scale-decrease "out"))

Remove clutter

Some things just waste space, let’s kill them once and for all frames (this works even for emacs in daemon mode and emacsclient).

(add-to-list 'default-frame-alist '(vertical-scroll-bars . nil))
(add-to-list 'default-frame-alist '(left-fringe . 0))
(add-to-list 'default-frame-alist '(right-fringe . 0))
(add-to-list 'default-frame-alist '(menu-bar-lines . 0))
(add-to-list 'default-frame-alist '(tool-bar-lines . 0))

Editing experience

Dired

Dired can work like a total commander and guess targets when two windows are open:

(setq dired-dwim-target t)

iBuffer

Let’s group our buffers in the ibuffer window.

(setq ibuffer-saved-filter-groups
      (quote (("default"
               ("dired" (mode . dired-mode))
                  ;;("perl" (mode . cperl-mode))
               ;;("erc" (mode . erc-mode))

               ("org" (or
                       (mode . org-mode)
                       (name . "^\\*Calendar\\*$")
                       (name . "^diary$")
                       (name . "^\\.org$")
                       (mode . muse-mode)))
               ("emacs" (or
                         (name . "^\\*scratch\\*$")
                         (name . "^\\*Messages\\*$")
                         ))

               ("clojure" (or
                           (mode . clojure-mode)
                           (name . "^\\*cider\\*$")
                           (name . "^\\*nrepl\\*$")
                           ))
             
               ("go" (mode . go-mode))
               ("js" (or
                      (mode . rjsx-mode)
                      (mode . js-mode)
                      ))
                  ;; ("gnus" (or
                  ;;          (mode . message-mode)
                  ;;          (mode . bbdb-mode)
                  ;;          (mode . mail-mode)
                  ;;          (mode . gnus-group-mode)
                  ;;          (mode . gnus-summary-mode)
                  ;;          (mode . gnus-article-mode)
                  ;;          (name . "^\\.bbdb$")
                  ;;          (name . "^\\.newsrc-dribble")))
               ))))


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

Markdown

Load the package with el-get:

(el-get-bundle markdown-mode)

And bind it do the files:

(add-to-list 'auto-mode-alist
             '("\\.\\(md\\|mdown\\|markdown\\)\\'" . markdown-mode)
             )

Unfill paragraph

Unfilling a paragraph joins all the lines in a paragraph into a single line. It is the contrary of FillParagraph.

;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun ra/unfill-paragraph (&optional region)
  "Takes a multi-line paragraph and makes it into a single line of text."
  (interactive (progn (barf-if-buffer-read-only) '(t)))
  (let ((fill-column (point-max)))
    (fill-paragraph nil region)))

And let’s bind it to a keystroke:

(define-key global-map "\M-Q" 'ra/unfill-paragraph)

Auto-fill mode

To turn auto-filling on (saves M-q presses):

(global-set-key (kbd "C-c q") 'auto-fill-mode)

Expand Region

Expand region increases the selected region by semantic units. Just keep pressing the key until it selects what you want.

;; smart region expansion
(el-get-bundle expand-region)
(global-set-key (kbd "C-=") 'er/expand-region)

VIM emulation

Evil emulates vim inside emacs. It works pretty well out of the box:

;; VIM emulation
(el-get-bundle evil)
(require 'evil)
(evil-mode 1)

Escape is too far, but we can use jk to enter the normal mode:

(key-chord-define evil-insert-state-map "jj" 'evil-normal-state)
(key-chord-define evil-visual-state-map "jj" 'evil-normal-state)
(key-chord-define evil-normal-state-map "jj" 'evil-normal-state)

Something that I can’t get used to is to disable cursor keys:

;;Motion state map disables the cursor keys in normal, operator, visual
;; as well as the special motion states.
(define-key evil-insert-state-map [left] 'undefined)
(define-key evil-insert-state-map [right] 'undefined)
(define-key evil-insert-state-map [up] 'undefined)
(define-key evil-insert-state-map [down] 'undefined)

(define-key evil-motion-state-map [left] 'undefined)
(define-key evil-motion-state-map [right] 'undefined)
(define-key evil-motion-state-map [up] 'undefined)
(define-key evil-motion-state-map [down] 'undefined)

Parentheses

Highlight matching parens:

(show-paren-mode t)

IDO (Interactively DO stuff)

I love IDO:

(add-hook 'ido-setup-hook (lambda ()
                (setq ido-enable-flex-matching t)))


; Use IDO for both buffer and file completion and ido-everywhere to t
(setq ido-everywhere t)
(setq ido-max-directory-size 100000)
(ido-mode (quote both))
; Use the current window when visiting files and buffers with ido
(setq ido-default-file-method 'selected-window)
(setq ido-default-buffer-method 'selected-window)


(ido-mode t)

Auto-load changes

When file wasn’t modified, reload changes automatically:

(global-auto-revert-mode t)

UTF8 Encoding

C’mon, it is 21st century already. Set environment coding system to UTF8:

(set-language-environment "UTF-8")

Yasnippet

Yasnipped lets you define snippets of code for different languages:

(require 'yasnippet)
(yas-global-mode)

Inside the snippets directory should be directories for each mode, e.g. clojure-mode and org-mode. This connects the mode with the snippets.

(setq yas-snippet-dirs (list (ra/emacs-subdirectory "snippets")))

Jump Hydra

(defun ra/kill-this-buffer-if-not-modified ()
  (interactive)
  (if (menu-bar-non-minibuffer-window-p)
      (kill-buffer-if-not-modified (current-buffer))
    (abort-recursive-edit)))

(defhydra hydra-jump (:color blue)
  "jumps"
  ("d" dired-jump "dired")
  ("." ido-find-file "file")
  ("l" ido-switch-buffer "buffer")
  ("k" ra/kill-this-buffer-if-not-modified "kill")
  ("z" undo-tree-visualize "undo")
  (";" execute-extended-command "meta-x")
  ("w" ra/hydra-windows/body "win")
  ("b" ibuffer "buf")
  )

We will call this helper via a key-chord:

(key-chord-define-global ";'" 'hydra-jump/body)

Follow symlinks

I get tired of Symbolic link to Git-controlled source file; follow link? (y or n) error message. So just follow it without asking.

;; just follow symlink and open the actual file
(setq vc-follow-symlinks t)

Compile

Emacs has a default compile command (which defaults to the make). Let’s bind it:

(global-set-key [f5] 'recompile) 
(setq compilation-ask-about-save nil)

Jumping around

(global-set-key (kbd "M-*") 'pop-tag-mark)

Org-mode

This is my emacs setup for the mighty org-mode!

;; latest version of org-mode
(el-get-bundle org-mode)
(require 'org)

Intro

Nice orgmode summary - http://orgmode.org/orgcard.txt

Good high-level presentation with pictures: http://web.psung.name/emacs/2009/part1.html

Formatting

We support a wide variety of fonts styles: bold, italic, underlined, verbatim and code.

Outlines

Org-mode is based on outline management. Some shortcuts:

ShortcutOperation
M-<Arrow>Move
M-RETInsert a new headingCan break lines
C-RETCreate a new item at the same level
C-c C-qSet tags for the current headline
C-x n s/wFocus on a subtree or Widen

Sexp

That’s how we can define complex dates. Worg description

Settings

View preferences

Make org-mode look pretty

(setq org-startup-indented t)
(setq org-hide-leading-stars t)
(setq org-odd-level-only t)
(setq org-indent-mode t)

I want to see inline images:

(setq org-startup-with-inline-images t)

File aliases

Default for org, txt and archive files

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

Locations

My default org folder is:

(setq org-directory "~/org")

But I want to compose agenda from all org files in projects as well:

(defun ra/remove-lock-files (fs)
  "Removes file names matching .# pattern (emacs lock files"
  (-remove(lambda (x) (string-match "\.#" x)) fs)
  )

(defun ra/list-possible-org-files ()
  "Provides a list of all matching org files"
  (ra/remove-lock-files
   (append
    (file-expand-wildcards "~/org/*.org")       ;; core org files
    (file-expand-wildcards "~/org/links/*.org") ;; linked org files
    ;;(file-expand-wildcards "~/proj/*/*.org")
    ;;(file-expand-wildcards "~/proj/*/org/*.org")
    )
   )
  )

(setq org-agenda-files (ra/list-possible-org-files))

Use IDO

Use IDO for both buffer and file completion and ido-everywhere to t

(setq org-completion-use-ido t)

Navigation

Switch between org buffers:

(global-set-key "\C-cb" 'org-iswitchb)

Clocking shortcuts

(defhydra hydra-org-clock (:color blue :hint nil)
  "
Clock   In/out^     ^Edit^   ^Summary     (_?_)
-----------------------------------------
        _i_n         _e_dit   _g_oto entry
        _c_ontinue   _q_uit   _d_isplay
        _o_ut        ^ ^      _r_eport
      "
  ("i" org-clock-in)
  ("o" org-clock-out)
  ("c" org-clock-in-last)
  ("e" org-clock-modify-effort-estimate)
  ("q" org-clock-cancel)
  ("g" org-clock-goto)
  ("d" org-clock-display)
  ("r" org-clock-report)
  ("?" (org-info "Clocking commands")))

(define-key org-mode-map  (kbd "C-c w") 'hydra-org-clock/body)

Links and IDs

Use org ids to create perma-links (as taken from SO):

;; wire up
(require 'org-id)
;; Create if storing link interactively and no CUSTOM_ID is present
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)

Bind shortcut to store a link at the current location:

(define-key org-mode-map  (kbd "C-c l") 'org-store-link)

Daypage

(eval-when-compile (require 'cl))

(setq daypage-path "~/org/days/")

(defvar daypage-mode-map
  (let ((map (make-sparse-keymap)))
    map)
  "The key map for daypage buffers.")

(defun find-daypage (&optional date)
  "Go to the day page for the specified date, or todays if none is specified."
  (interactive (list 
                (org-read-date "" 'totime nil nil
                               (current-time) "")))
  (setq date (or date (current-time)))
  (find-file (expand-file-name (concat daypage-path (format-time-string "%Y-%m-%d" date) ".org"))))

(defun daypage-p ()
  "Return true if the current buffer is visiting a daypage"
  (if (daypage-date)
      t
    nil))

(defun daypage-date ()
  "Return the date for the daypage visited by the current buffer
or nil if the current buffer isn't visiting a dayage" 
  (let ((file (buffer-file-name))
        (root-path (expand-file-name daypage-path)))
    (if (and file
               (string= root-path (substring file 0 (length root-path)))
               (string-match "\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\).org$" file))
        (flet ((d (i) (string-to-number (match-string i file))))
          (encode-time 0 0 0 (d 3) (d 2) (d 1)))
      nil)))


(defun maybe-daypage ()
  "Set up daypage stuff if the org file being visited is in the daypage folder"
  (let ((date (daypage-date)))
    (when date
      ; set up the daypage key map
      (use-local-map daypage-mode-map)
      (set-keymap-parent daypage-mode-map
                         org-mode-map)
      (run-hooks 'daypage-hook))))

(add-hook 'org-mode-hook 'maybe-daypage)

(defun daypage-next ()
  (interactive)
  (find-daypage 
   (seconds-to-time (+ (time-to-seconds (daypage-date))
                       86400)))
  (run-hooks 'daypage-movement-hook))

(defun daypage-prev ()
  (interactive)
  (find-daypage 
   (seconds-to-time (- (time-to-seconds (daypage-date))
                       86400)))
  (run-hooks 'daypage-movement-hook))

(defun daypage-next-week ()
  (interactive)
  (find-daypage 
   (seconds-to-time (+ (time-to-seconds (daypage-date))
                       (* 86400 7))))
  (run-hooks 'daypage-movement-hook))

(defun daypage-prev-week ()
  (interactive)
  (find-daypage 
   (seconds-to-time (- (time-to-seconds (daypage-date))
                       (* 86400 7))))
  (run-hooks 'daypage-movement-hook))

(defun todays-daypage ()
  "Go straight to todays day page without prompting for a date."
  (interactive) 
  (find-daypage)
  (run-hooks 'daypage-movement-hook))

(defun yesterdays-daypage ()
  "Go straight to todays day page without prompting for a date."
  (interactive) 
  (find-daypage 
   (seconds-to-time (- (time-to-seconds (current-time))
                      86400)))
  (run-hooks 'daypage-movement-hook))

(defun daypage-time-stamp ()
  "Works like (and is basically a thin wrapper round)
org-time-stamp except the default date will be the date of the daypage."
  (interactive)
  (unless (org-at-timestamp-p)
    (insert "<" (format-time-string "%Y-%m-%d %a" (daypage-date)) ">")
    (backward-char 1))
  (org-time-stamp nil))

(defun daypage-new-item ()
  "Switches to the current daypage and inserts a top level heading and a timestamp"
  (interactive)
  (todays-daypage)
  (end-of-buffer)
  (if (not (bolp))
      (insert "\n"))
  (insert "* <" (format-time-string "%Y-%m-%d %a" (daypage-date)) "> "))


(provide 'org-daypage)

and now configure keyboard

(define-key daypage-mode-map (kbd "<C-left>") 'daypage-prev)
(define-key daypage-mode-map (kbd "<C-right>") 'daypage-next)
(define-key daypage-mode-map (kbd "<C-up>") 'daypage-prev-week)
(define-key daypage-mode-map (kbd "<C-down>") 'daypage-next-week)
;; (define-key daypage-mode-map "\C-c." 'daypage-time-stamp)
;;
(global-set-key [f8] 'todays-daypage) 
(global-set-key [f7] 'yesterdays-daypage) 
;; (global-set-key "\C-con" 'todays-daypage)
(global-set-key [f9] 'find-daypage)

GTD Workflow

Keywords and states

A list of keywords and their colors, initially taken from Bernt Hansen:

(setq org-todo-keywords
      (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
              (sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)"))))

;;; color keywords
(setq org-todo-keyword-faces
      (quote (("TODO" :foreground "red" :weight bold)
              ("NEXT" :foreground "blue" :weight bold)
              ("DONE" :foreground "forest green" :weight bold)
              ("WAITING" :foreground "orange" :weight bold)
              ("HOLD" :foreground "magenta" :weight bold)
              ("CANCELLED" :foreground "forest green" :weight bold)
              )))

State Transitions

There are two ways to change task state:

;; Changing a task state is done with =C-C C-t KEY=:
(setq org-use-fast-todo-selection t)
;; changing states with S + arrow does not trigger full change
(setq org-treat-S-cursor-todo-selection-as-state-change nil)

Triggered state changes

(setq org-todo-state-tags-triggers
      (quote (("CANCELLED" ("CANCELLED" . t))
              ("WAITING" ("WAITING" . t))
              ("HOLD" ("WAITING") ("HOLD" . t))
              (done ("WAITING") ("HOLD"))
              ("TODO" ("WAITING") ("CANCELLED") ("HOLD"))
              ("NEXT" ("WAITING") ("CANCELLED") ("HOLD"))
              ("DONE" ("WAITING") ("CANCELLED") ("HOLD")))))

Capture mode

Let’s use C-c c to start capture mode:

(setq org-default-notes-file "~/org/inbox.org")
(global-set-key (kbd "C-c c") 'org-capture)

And define some capture templates (see docs):

(setq org-capture-templates
      (quote (
              ("i" "index" entry (file+datetree "~/org/index.org")
               "* INDEX: %?")
              )))

Agenda

Load agenda globally either with C-c a or with F12 (my shortcut)

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

Inside agenda window:

OperationShortcutWhen to use
Quit agendaq
List all TODO entriest
Search for entryTe.g. for TODO OR TODO \vert NEXT
Match metadatame.g. for +car&+call [1]
Match metadata for active taskMsame as above
Next/previous periodf/b
View log for the current fileL
show agendaa
view by daysv d
view by weeksv w
go to today.
quit agendaq
close other windowso
view by monthv m
view by yearv y
recreate the agenda bufferr
jump to a datej

There is a great article in Advanced Searching.

Let’s setup custom commands (explained in manual):

(setq org-agenda-custom-commands
      '(
        ;; ("X" agenda "" nil ("agenda.html" "agenda.ps"))
        ;; ("Y" alltodo "" nil ("todo.html" "todo.txt" "todo.ps"))
        ;; ("h" "Agenda and Home-related tasks"
        ;;  ((agenda "")
        ;;   (tags-todo "home")
        ;;   (tags "garden"))
        ;;  nil
        ;;  ("~/views/home.html"))


        ("F" "full agenda view"
         ((agenda ""
                  ;; array of constraints
                  (
                   ;; next 30 days
                   (org-agenda-ndays 30)
                   ;; drop empty blocks
                   (org-agenda-show-all-dates nil)
                   ))
          ;; agenda command options
          ;;(tags-todo "work")
          ;;(tags "office")
          )
         nil
         (
          "~/org/views/agenda_full.ps"
          "~/org/views/agenda_full.ics"
          "~/org/views/agenda_full.html"
          ))
        ))

These can be called with C-c a e (org-store-agenda-views)

Refile

Refile allows us to move org entries between org files. Disabled for now. It can be triggered with C-c C-w.

; Targets include this file and any file contributing to the agenda - up to 9 levels deep
(setq org-refile-targets (quote ((nil :maxlevel . 9)
                                 (org-agenda-files :maxlevel . 9))))

; Use full outline paths for refile targets - we file directly with IDO
(setq org-refile-use-outline-path t)

; Targets complete directly with IDO
(setq org-outline-path-complete-in-steps nil)

; Allow refile to create parent tasks with confirmation
(setq org-refile-allow-creating-parent-nodes (quote confirm))
; Use the current window for indirect buffer display
(setq org-indirect-buffer-display 'current-window)

;;;; Refile settings
; Exclude DONE state tasks from refile targets
(defun bh/verify-refile-target ()
  "Exclude todo keywords with a done state from refile targets"
  (not (member (nth 2 (org-heading-components)) org-done-keywords)))

(setq org-refile-target-verify-function 'bh/verify-refile-target)

Literate Programming

This is an article by an admin with very little head space :)

Templates

Templates are supported in org-mode out-of-the-box. Just type < followed by a char and TAB. See Easy Templates for more details.

Babel

Some initial languages that we want babel to support:

(org-babel-do-load-languages
 'org-babel-load-languages
 '(
   (sh . t)
   (shell . t)
   (python . t)
   (R . t)
   (ruby . t)
   (ditaa . t)
   (dot . t)
   (octave . t)
   (sqlite . t)
   (perl . t)
   (gnuplot . t)
   (clojure . t)
   (scheme . t)
   ))

Let’s be risky and evaluate all blocks without asking:

(setq org-confirm-babel-evaluate nil)

Editing source code

I don’t want org src to open code editing in another window. Current is just fine.

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

Refresh inline images

I want inline images to be refreshed automatically (taken from SS):

(defun ra/fix-inline-images ()
  (when org-inline-image-overlays
    (org-redisplay-inline-images)))
(add-hook 'org-babel-after-execute-hook 'ra/fix-inline-images)

Org publishing

(setq org-export-backends (quote (
       ascii
       ;;beamer
       html
       ;;latex
       md
       ;;odt
       ;;s5
       ;;taskjuggler
       )))


;; don't include default style
(setq org-html-head-include-default-style nil)
;; don't include scripts
(setq org-html-head-include-scripts nil)

Publishing to HTML

as per tutorial.

Requirements:

  1. no absolute paths in HTML,
  2. no base element
  3. Emacs + org-mode

File structure (inside ~/org/)

  1. index.org (will transform to index.html)
  2. remember.org (or whatever)
  3. /css/styles
  4. /img/images

To link from one file to another - use a standard link

Components

Publish notes
(setq org-publish-project-alist
      '(


        ("org-notes"
         :base-directory "~/org/"
         :base-extension "org"
         :exclude "organizer.org\\|journal.org\\|people.org"
         :publishing-directory "~/org/_publish/"
         :recursive nil
         :publishing-function org-html-publish-to-html
         :headline-levels 4             ; Just the default for this project.
         :auto-preamble t
         )


        ("org-static"
         :base-directory "~/org/_org/"
         :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
         :publishing-directory "~/org/_publish/_org/"
         :recursive t
         :publishing-function org-publish-attachment
         )

         ("org-deploy"
          :base-directory "~/org/_publish/"
          :base-extension ".*"
          :publishing-directory "/ssh:vault:/var/www/org"
          :publishing-function org-publish-attachment
          :recursive t

     )

        ("org" :components ("org-notes" "org-static" "org-deploy"))

       ;; ... add all the components here (see below)...

      ))

Renders notes to HTML

Static component

Copies static content to the target folder

Inherit component

Allows sharing styles and settings between multiple projects

Sitemap

Subj, generates a simple sitemap

Miscellaneous

Unknown origins

This was copied from somewhere, not sure if I still need these:

;; mode line settings
(column-number-mode t)
(line-number-mode t)
(size-indication-mode t)

;; set your desired tab width
(setq-default indicate-empty-lines t)

Another unknown bit:

;; S-up does not work properly in terminals
;; http://lists.gnu.org/archive/html/help-gnu-emacs/2011-05/msg00211.html
 (if (equal "xterm" (tty-type))
      (define-key input-decode-map "\e[1;2A" [S-up]))

(defadvice terminal-init-xterm (after select-shift-up activate)
  (define-key input-decode-map "\e[1;2A" [S-up]))

and one more:

;; This won't affect the size of the emacs window, but the term process will always think the window is 80 columns wide
(defun term-window-width () 80)
;;  turn on line truncation
(add-hook 'term-mode-hook
      (lambda () (setq truncate-lines t)))

Tabs vs Spaces

Let’s stick with tabs for now:

;; display tab chars as 4
(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)

Enable Y/N answers

y is shorter than yes:

(fset 'yes-or-no-p 'y-or-n-p)

Disable auto-save

Auto-save never really worked for me:

(setq make-backup-files nil)
(setq auto-save-default nil)

Disable escape

Escape key hurts my pinky :)

(global-set-key (kbd "<escape>")      'nil)

Line numbers

This is a very nice way to highlight jumps for vim.

(el-get-bundle linum-relative
  (setq linum-relative-current-symbol "")
  )
(global-linum-mode 1)

(defconst linum-mode-excludes '(
                                doc-view-mode
                                compilation-mode
                                term-mode
                                dired-mode
                                ibuffer-mode
                                eshell-mode
                                cider-repl-mode
                                'repl-mode
                                )
  "List of major modes preventing linum to be enabled in the buffer.")

(defadvice linum-mode (around linum-mode-selective activate)
  "Avoids enabling of linum-mode in the buffer having major mode set to one
of listed in `linum-mode-excludes'."
  (unless (member major-mode linum-mode-excludes)
    ad-do-it))

And highlight current line:

;; highlight current line
(add-hook 'after-change-major-mode-hook 'hl-line-mode)

Inherit shell environment

Process environment of emacs might benefit from inheriting shell environment variables (e.g. for running external tools):

(defun ra/load-unix-shell-env ()
  "Adds the shell environment variables to Emacs' process environment."
  (interactive)
  (let* ((env (shell-command-to-string "$SHELL -i -c 'printenv'"))
     (entries (split-string env "\n" t)))
    (mapc (lambda (entry)
        (add-to-list 'process-environment entry))
      entries)))

(ra/load-unix-shell-env)

Languages

Lisp

Taken from here: https://astraybi.wordpress.com/2015/08/02/how-to-install-slimesbclquicklisp-into-emacs/

;;(el-get-bundle slime)
;;  (require 'slime-autoloads)
(load (expand-file-name "~/.roswell/helper.el"))
(setq inferior-lisp-program "ros -Q run")

Grab the packages and wire them into lisp mode:

(setq lisp-mode-hooks '(emacs-lisp-mode-hook
            lisp-mode-hook
            lisp-interaction-mode-hook
            scheme-mode-hook
            clojure-mode-hook))

(el-get-bundle paredit
  (add-hook-list 'paredit-mode lisp-mode-hooks)
  )
(el-get-bundle rainbow-delimiters
  (add-hook-list 'rainbow-delimiters-mode lisp-mode-hooks)
  )

Go-mode

Taken from this article.

(el-get-bundle go-mode)
(el-get-bundle company-go)
(el-get-bundle multi-compile)
(el-get-bundle go-eldoc)

(require 'company)
(require 'flycheck)
(require 'yasnippet)
(require 'multi-compile)
(require 'go-eldoc)
(require 'company-go)

(add-hook 'before-save-hook 'gofmt-before-save)
(setq-default gofmt-command "goimports")
(add-hook 'go-mode-hook 'go-eldoc-setup)
(add-hook 'go-mode-hook (lambda ()
                            (set (make-local-variable 'company-backends) '(company-go))
                            (company-mode)))
(add-hook 'go-mode-hook 'yas-minor-mode)
(add-hook 'go-mode-hook 'flycheck-mode)
(setq multi-compile-alist '(
    (go-mode . (
("go-build" "go build -v"
   (locate-dominating-file buffer-file-name ".git"))
("go-build-and-run" "go build -v && echo 'build finish' && eval ./${PWD##*/}"
   (multi-compile-locate-file-dir ".git"))))
))

Clojure

(el-get-bundle spinner)
(el-get-bundle clojure-mode)
(el-get-bundle cider)

Enable company mode in cider mode and cider repl

(add-hook 'cider-repl-mode-hook #'company-mode)
(add-hook 'cider-mode-hook #'company-mode)

Tell org-babel to use cider backend for clojure:

(require 'ob-clojure)
(setq org-babel-clojure-backend 'cider)

In source code:

C-c C-k
C-c C-d C-dShow documentation for the symbol
C-x C-ecider-eval-last-expression
C-c C-kcompile file within current REPL session
C-c-C-d C-aSearch docs for text

References

@abdullin All talks by Hickey are worth seeing but besides these I’d say “Are we there yet”, “Language of systems” & “hammock driven dev” View conversation 0 retweets 0 likes

Read references

Clojure vs Erlang (blogpost)

Clojure vs Erlang

There is a nice comment:

I have had the pleasure of working with both languages. They both have their place.

Rich argues why he didn’t use an actor-like setup in clojure here http://clojure.org/state in the middle under “Message Passing and Actors”. He makes some good points. (IE, Unless you are doing distributed programming, you pay a price for message passing).

We have developed some neat simple message passing on top clojure on our project using RabbitMQ and clojure sequences & actors. So :P :)

Clojure wins for us by keeping it functional, being awesome on cores and giving access to a hundred thousand java libraries.

and a follow-up

I agree with Tim. I think Clojure’s sweet spot is an app which needs some sanity around concurrency – and what app these days doesn’t? – and needs either the JVM or some set of Java libraries.

Personally, I shudder a little bit at the prospect of doing distributed stuff with any JVM language since I’ve started using Erlang. The simplicity really is a game changer if you’re doing any amount of distributed work.

Value of Values

The Value of Values (Video by RH). He goes into the semantics of what is a value, focusing on 2 characteristics: immutability and referential transparency.

Because of that, values are:

  • language independent
  • Generic
  • easy to fabricate
  • values aggregate to values (list of strings is a value)
  • values make best interfaces (we already send them over the wire)
  • reduce coordination (no need to lock things)

Basically, his thoughts are aligned with value proposition of event sourcing.

Information systems are fundamentally about facts: maintaining and manipulating them. To give users a leverage in making decisions.

Information is a fact, it isn’t a machine.

I’m building systems for information management and decision support.

What do we use for ourselves?

  1. Source control (and not a directory) - append + timestamps
  2. Logs - append + timestamps
  3. Releases

New facts require new space.

Web

(el-get-bundle rjsx-mode)
 (evil-define-key 'insert rjsx-mode-map (kbd "C-d") 'rjsx-delete-creates-full-tag)

Footnotes

Loading the configuration

To reload with a require:

(provide 'init-main)

Notes

Sexp

  1. Worg description

Agenda

The Cycle

Working with agenda

KeyActionWhen
C-x n sNarrow to a subtree
C-x n wWiden a subtree

Recording a Journal

KeyActionWhen
C-c !Insert inactive timestamp

Agenda View

Good commands for navigating agenda (once shown with F12)

KeyActionWhen
ashow agenda
v dview by days
v wview by weeks
.go to today
qquit agenda
oclose other windows
fmove period forward
bmove period back
v mview by month
v yview by year
rrecreate the agenda buffer
jjump to a date