February 10, 2013
My .stumpwmrc

In my efforts to learn Lisp, I started using StumpWM. Using a window manager configurable in Common Lisp seemed like a good way to practice, and as it turns out, I fell in love. It uses keybindings and acts similar to Emacs or Tmux, which for me at least makes it much nicer to work with than xmonad or awesome.

Coming up with a configuration that worked for me took some effort, so I thought I’d share what I came up with. Here it is:

;; -*-lisp-*-
(in-package :stumpwm)

(run-shell-command "xsetroot -cursor_name left_ptr -solid black -name root-window")

(defvar *battery-status-command* "acpi -b | awk -F '[ ,]' '{printf \"%s%s\", $3, $5}' | sed s/Discharging/\-/ | sed s/Unknown// | sed s/Full//  |  sed s/Charging/+/")
(defvar *vol-status-command* "amixer get Master | grep '[[:digit:]]\\+%' -o | tr -d '\\n'")

(setf *screen-mode-line-format*
      (list "[^B%n^b] %W^>"
	    '(:eval (run-shell-command *battery-status-command* t))
	    " | Vol. "
	    '(:eval (run-shell-command *vol-status-command* t))
	    " | %d"))

(setf *window-format* "%m%n%s%c")

(setf *mode-line-timeout* 1)

(toggle-mode-line (current-screen)
		  (current-head))

(defcommand terminator () ()
	    (run-or-raise "terminator" '(:instance "terminator")))
(define-key *root-map* (kbd "c") "Terminator")

(setf *mouse-focus-policy* :click)

;; Volume control
(define-key *top-map* (kbd "XF86AudioLowerVolume") "exec amixer set Master 5%-")
(define-key *top-map* (kbd "XF86AudioRaiseVolume") "exec amixer set Master 5%+")

;; Mute
(define-key *top-map* (kbd "XF86AudioMute") "exec amixer set Master toggle")

(defcommand google (search) ((:string "Google: "))
	    (let ((prefix "chromium http://www.google.com/search?q=")
		  (search (substitute #\+ #\Space search)))
	      (run-shell-command (concatenate 'string prefix search))))

(define-key *root-map* (kbd "b") "google")

download

The resulting layout:

StumpWM Screenshot

StumpWM Screenshot

A few highlights:

(defvar *battery-status-command* "acpi -b | awk -F '[ ,]' '{printf \"%s%s\", $3, $5}' | sed s/Discharging/\-/ | sed s/Unknown// | sed s/Full//  |  sed s/Charging/+/")
(defvar *vol-status-command* "amixer get Master | grep '[[:digit:]]\\+%' -o | tr -d '\\n'")

These are the commands that will be run to get the volume and battery levels, which I like to have in my top bar. Then:

(setf *screen-mode-line-format*
      (list "[^B%n^b] %W^>"
	    '(:eval (run-shell-command *battery-status-command* t))
	    " | Vol. "
	    '(:eval (run-shell-command *vol-status-command* t))
	    " | %d"))

Sets the layout of the top bar the way I like it. Window list on the left, with the volume and battery status on the right, followed by the date.

Lastly a fun little shortcut:

(defcommand google (search) ((:string "Google: "))
	    (let ((prefix "chromium http://www.google.com/search?q=")
		  (search (substitute #\+ #\Space search)))
	      (run-shell-command (concatenate 'string prefix search)))) 

(define-key *root-map* (kbd "b") "google")

This snippet set it up so when I hit Ctrl-t, b, it prompts me for a term to Google, then opens a new Chromium tab with the results (just change chromium to the browser of your choice).

Hopefully this helps someone get started.