git clone 'git://github.com/shosti/wacspace.el.git'
The WACky WorkSPACE manager for emACS.
Wacspace is available on Marmalade and
Melpa, so you can install easily with
M-x package-install. You can also just put
wacspace.el on your
load path and
(require 'wacspace). Wacspace requires cl-lib
(included in Emacs >= 24.3) and
dash.el (available on Marmalade
The easiest way to set up wacspace is to just put
into your Emacs configuration somewhere. This will set up
C-z as a
prefix key with the various wacspace commands in convenient bindings.
If for some reason you don't want to use
C-z as a prefix, you can
put something like the following in your configuration:
(wacs-set-up-prefix) (global-set-key (kbd "C-c C-w") 'wacs-prefix-map)
(In this example,
C-c C-w would be the wacspace prefix.) If you
don't want to use the prefix map, you can also use your own custom
keybindings. The only commands you need to bind are
Once you have a good configuration (see below), using wacspace is very
easy: just press
C-z C-w (or
M-x wacspace) when you're in a
buffer, and your workspace (windows, buffers, and frame) will be
automatically set up according to your current mode.
C-z C-w will
use the default configuration for the mode, but you can also use
alternate workspaces (wacspace supports up to 10, including the
default). To use workspace number 3, for example, press
C-z C-3 (or
C-3 M-x wacspace).
The first time you use
wacspace on a buffer, your workspace will be
set up based on your configuration (see below). Once your workspace is
set up, wacspace will automatically save your window configuration. If
wacspace on any of the buffers that were set up this way, it
will jump to the window setup without re-running your configuration.
You can also save your configuration at any time using
C-z C-s (or
wacspace-save can also use a numeric prefix,
in which case using
wacspace with that numeric prefix will access
that saved workspace. When you kill a buffer in the configuration and
wacspace, it will again set up the workspace according to your
wacspace should “just work” most of the time—if
you want concrete behavior examples, check out
If you want to force reconfiguration of a workspace, use
C-w, which will clear the saved workspaces associated with the
If the variable
wacs-save-frame is set to
t (which it is by
default unless you're running Emacs in a terminal),
save and restore frame configuration as well as window configuration.
Managing project workspaces is easy with wacspace. When you use
wacspace, wacspace will associate your workspace with a project name
(by default, the name of the enclosing folder that contains a
but this is configurable). You can then easily switch between projects
C-z C-p (or
M-x wacspace-switch-project), which will prompt
for a project name (for best results, use
ido-mode, which you should
be using anyway). Wacspace will even remember which prefix key you
used last in that particular project, so you can resume right where
you left off. Wacspace also comes with a number of functions that help
you set up project-specific helper windows (see later).
Configuring wacspace is not much harder—you usually only need to use
defwacspace. Here's an example configuraton to get you
(defwacspace (ruby-mode (:var rinari-minor-mode)) (:before rinari-console) (:after-switch rbenv-use-corresponding) (:default (:winconf 3winv) (:aux1 "*rails console*") (:aux2 eshell)) (:1 (:frame full)) (:2 (:winconf 2winh) (:frame left)) (:3 (:main "*rails console*") (:aux1 :main) (:winconf 2winh) (:frame right)
The basic form is
(defwacspace (major-mode &optional aux-cond) &body
aux-cond can be either be a variable of the form
(:var VAR) (such as
(:var rinari-minor-mode), or any other minor
mode variable for that matter) or a function of the form
(:fn (lambda () (string-match "spec\\.rb$" (buffer-name)))).
You can also use an inline lambda instead of a
(:fn FN) pair, or a
variable name instead of a
(:var VAR) pair (in all cases, there is
no need for quoting).
The configuration currently supports the following options:
:beforeA function to run before setting up the workspace.
:after-switchA function to run after setting up the workspace and every time you switch to a project with that configuration.
:defaultThe default configuration.
:[1-9]The configuration to use with the corresponding prefix. keys. Note that these inherit from the default configuration.
:afterA function to run after setting up the workspace.
:base-fileA filename to look for to find the project root (useful for the path helper functions). Defaults to
:project-name-fnA function to customize the project name (should return a string).
Within the configurations, the following options are available:
:winconfThe window configuration to use (see later).
:frameThe frame alignment to use (see later).
:mainThe top-left window.
:aux[1-5]Auxiliary window number 1-5 (in the order of
There are 2 options to set up a window:
:bufferSwitch to buffer name (or
:main, which signifies the buffer from which
wacspacewas invoked). If
wacs-regexp-buffer-switchingis set to
t(which it is by default), wacspace will try to switch to the most recent buffer with a regexp match; if none is found, it will switch to a new buffer with that name.
:cmdA command to invoke.
You can also specify default wacspaces, which will be run when no wacspace associated with a major mode is found:
(defwacspace (:default) (:default (:aux1 wacs-eshell))) (defwacspace (:default rinari-minor-mode) (:before rinari-console) (:aux1 "*rails console*")
:default wacspace (without a minor mode condition) is special:
all wacspaces inherit from it. So if you put a useful base
configuration in your
:default, you can save a lot of configuration
in all your other modes!
Another useful option is to specify wacspace aliases:
(defwacsalias (js-mode rinari-minor-mode) (ruby-mode rinari-minor-mode))
As you might expect, the above example means that when you're in a
wacspace will run as if
rinari-minor-mode. You can also alias
multiple modes to a single wacspace using the
One thing to be aware of is the specific order in which
will look for configurations:
:defaultwacspace with auxiliary conditions
:defaultwacspace without auxiliary conditions
Wacspace comes with some nice path functions to help set up auxiliary
wacspace is invoked, the variable
is automatically bound to the buffer from which it was invoked, so you
can use it in any functions that set up windows or that test for
auxiliary conditions. The function
wacs-project-dir finds the base
project directory by looking for a file or folder equal to
wacs-project-base-file. This variable defaults to
".git" but can
be set globally or on a per-wacspace basis with the option
Wacspace also provides functions
designed to be used within wacspace configurations, that open an
eshell or shell (respectively) in the project directory. If you have
multiple files in the same directory, they will share the same eshell
or shell buffer.
A winconf is basically just a function to set up your windows. You can
define your own using
(defwinconf my-cool-winconf (split-window-right) (split-window-right) (split-window-below) (split-window-below) (other-window 3) (split-window-left))
(This is a terrible example of a usable window configuration). You can assume that your function will start with just one window and you don't have to worry about having the primary window active in the end. Wacspace comes with some nice winconfs built in:
+----------------------+ | | | | | | | :main | | | | | | | +----------------------+
+----------+-----------+ | | | | | :aux1 | | | | | :main +-----------+ | | | | | :aux2 | | | | +----------+-----------+
+----------+-----------+ | | | | | | | | | | :main | :aux1 | | | | | | | | | | +----------+-----------+
+----------+ | | | :main | | | +----------+ | | | :aux1 | | | +----------+
+----------+-----------+ | | | | :main | :aux2 | | | | +----------+-----------+ | | | | :aux1 | :aux3 | | | | +----------+-----------+
Due to the wide variety of GUI/terminal experiences for Emacs and
screen resolutions, I haven't attempted to include frame-setting
functions with wacspace. Instead, you can use your own functions and
set them using
(wacs-set-frame-function full my-fill-screen-fn)
In the future, I might add helper functions to set up your own frame functions.
Wacspace is in early alpha phase, and I plan to add more features and fix behavior. Any comments/suggestions/pull requests are much appreciated. Eventually, I would also like to include a variety of default configurations for various modes.