What Emacs is to editors, Stumpwm is to window managers.
--Bill Clementson (link)
Introduction
Recently I switched from GNOME to Stumpwm (wiki), which means
that I jumped out of a desktop environment to a simple window manager.
So far, I'm very satisfied with such a change and never looked back.
Stumpwm, as its website says, is a tiling, keyboard driven X11
Window Manager written entirely in Common Lisp
. This definition
summarizes the reasons why Stumpwm is so suitable for me.
First, Stumpwm is a tiling, keyboard driven window
manager. This is very useful to boost productivity. When working, it
is desirable to minimize context switching. Tilting combined with
keyboard driven enables working with several applications
simultaneously as if your are dealing with one single program. Let me
give an example. As described in previous
post, with Emacs as development environment, it is easy to fire up
one browser within Emacs itself to preview blog post. However it is
painful to switch between Emacs and browser. Before using Stumpwm, I
am considering ways to integrate Emacs and Firefox together. With
Stumpwm, such dream is just trivial to fulfill: one can show
Emacs and browser side by side, with a few keystrokes to switch
between them. Everytime you make changes in Emacs and request the
results to be shown in Firefox, they are shown simultaneously. No more
need to leave your hand for mouse to click back and forth between
Emacs and Firefox. This gives you the feeling of integrated
environment. Note that I just use Emacs and Firefox as an example, and
such convenience is applicable for every application. Currently, the
problem is that I'm so accustomed to Stumpwm keystrokes that I somehow
confused the keystrokes of switching between windows in Stumpwm and
Emacs!
Second, Stumpwm is written in Common Lisp. which
means that you can build Stumpwm with your favorite CL implementation
and you have a Lisp runtime when you work under Stumpwm. A powerful
programming language is just embedded within your window manager and
you can invoke it at any time. The other benefit is that you can
configure your window manager as you like, even when it is
running!
You may get a feeling on how Stumpwm works by watching this nice video.
Installation
Given the above lengthy introduction of Stumpwm, you may wonder how
to install this gem. Here we assume that you have some knowledge about
Common Lisp. Basically, installing Stumpwm is to compile it with your
preferred CL implementation, and tell your system to run Stumpwm as
your window manager.
Installing Stumpwm on Gentoo Linux is straightforward. Throughout
this section, we will assume that SBCL is the CL
implementation. Stumpwm website suggests turn off threading support in
SBCL (disable USE flag threads) for better performance. To
install, simply type emerge stumpwm. Note
that at the time of writing, there is also an ebuild called
stumpwm-cvs. Simply ignore it since it is actually a very old version,
not the bleeding edge version suggested by its name. Advanced users
might consider to get git version for latest cool features.
There are mainly two ways to invoke Stumpwm. One is to run it by
calling SBCL, the other is to dump a core image containing Stumpwm
within SBCL and invoke that image. We will take the latter
approach. To proceed, first start SBCL by typing sbcl. Next
issue the following in REPL sequentially:
(asdf:oos 'asdf:load-op :stumpwm)
(sb-ext:save-lisp-and-die "stumpwm" :executable t
:toplevel #'(lambda () (stumpwm:stumpwm ":0")))
Next, put the generated executable stumpwm somewhere in
PATH (I put it under /usr/local/bin). Since I always start X Window by
typing startx, following command is used to use Stumpwm as
my window manager:
$ echo "exec stumpwm" >> ~/.xinitrc
Using Stumpwm
Configuration
All stumpwm configurations are stored in
file ~/.stumpwmrc, which is written in Common Lisp. Just
like .emacs, this file allows you to fully customize
Stumpwm. Following is my current configuration:
(in-package :stumpwm)
(load "/usr/share/emacs/site-lisp/slime/swank-loader.lisp")
(swank-loader:init)
(define-stumpwm-command "swank" ()
(setf stumpwm:*top-level-error-action* :break)
(swank:create-server :port 4005
:style swank:*communication-style*
:dont-close t)
(echo-string (current-screen) "Starting swank."))
(define-key *root-map* (kbd "C-s") "swank")
(setf *message-window-gravity* :center)
(setf *input-window-gravity* :center)
(toggle-mode-line (current-screen) (current-head))
(setf *screen-mode-line-format*
(list "%w | "
'(:eval (run-shell-command "date | tr -d '[:cntrl:]'" t))))
(set-prefix-key (kbd "C-i"))
(define-key *root-map* (kbd "c")
"exec urxvt +sb -fn \"xft:Bitstream Vera Sans Mono:pixelsize=20\"")
(define-stumpwm-command "firefox" ()
"Run or switch to firefox."
(run-or-raise "firefox" '(:class "Firefox")))
(define-key *root-map* (kbd "f") "firefox")
Some explanations of my configuration:
- Prefix key: I use C-i instead of
default C-t. The reason is that C-t is used in
Firefox to open a new tab and also in Emacs for transpose. Then why
choose C-i? I'd like to admit that it is quite difficult
to select a prefix key for Emacs user. Before settle down
on C-i, I fired up Emacs to see whether there is any key
binding C-x where x from a to z is not used by
Emacs. Unfortunately (fortunately?), Emacs binds every
combination. So I can only choose one prefix key which is easy to
type and I uses infrequently in Emacs. Then C-i is
selected. Note that you can send C-i to application like
Emacs by typing C-i i. For the following sections, please
replace C-i with your favorite prefix key.
- SLIME: the section staring with
comments Load swank provides ways to load
swank. Type C-i C-s to start swank. To connect to swank,
simply run Emacs, and type slime-connect within Emacs,
and type RET and RET to accept default host
(127.0.0.1) and default port (4005). Then you can play with Stumpwm
as you wish: change parameters, add your own functions etc. Note
that I do not start swank automatically for security reasons.
- Key bindings: I use C-i c to start
console: urxvt instead of xterm. Note that I have
also set the font for urxvt. In addition I have setup using C-i
f to start Firefox in case Firefox is not started, or bring
Firefox window to front if it is already running.
Key Bindings
Following is a list of key bindings I used frequently. For
simplicity, I have omitted the prefix key.
- ?: Stumpwm help
- ;: Run Stumpwm commands
- :: Send commands to Common Lisp interpreter.
- Space: Go to next window
- c: Run X terminal
- e: Run Emacs or raise it if it is already running
- f: Run Firefox or raise it if it is already running
- k: Kill current window
- g c: Create a new group
- g k: Kill current group
- g m: Move current window to a specified group
- g Space: Next group
- o: Focus shifts to next frame
- Q: Remove all splits
- s: Vertical split
- S: Horizontal split