VIMonad is a fork of XMonad that manages windows in a modal way like that in VIM. Some of the features include
find
and grep
) as complete-able options (for selecting files)taskwarrior
)VIMonad is built upon XMonad and it borrows a lot of great modules already existing in its Contrib library. I'd like to thank all the people who have made XMonad a fantastic window manager in the first place.
$PATH
~/.xmonad
(note your old xmonad configuration will be overriden)
cd
into xmonad; cabal install
cd
into XMonadContrib; cabal install
(Zoom in to see how the layout is represented on the statusbar)
workspace(s)
└── row(s)
└── line(s)
└── tab(s)
:<name>
`
(the temporary workspace)cd
in the DynamicPrompt1
, the second gets 2
, so on and so forth; the entire stream of symbols used as labels can be found in the source[num]G
as in vimM-<
: shrink current rowM->
: expand current rowM-\
: restore default size for the current rowM--
: shrink current lineM-+
: expand current lineM-=
: restore default size for the current lineA major concept of VIMonad is task group. A task group defines a groups of windows that share the same or similar characteristics e.g., vim terminal windows, browser windows, etc.
Each task group has
filterKey
to be referenced in motions. This can be a single key or a sequence of keys.manageHooks
that define the window styles that you can cycle using M-t
and M-S-t
Checkout xmonad.hs for how to define task groups.
Checkout Taskgroup.hs for source about task groups.
Registers server two purposes in VIMonad:
Attached registers are displayed for each window within the sqaure brackets of its tab label as '<reg>['<another reg>]
.
Insertion of windows/workspaces emulate the relevant aspects from vim
a
: insert after the current window/workspacei
: insert before the current window/workspaceA
: insert at the end of the line/workspacesI
: insert at the beginning of the line/workspacesWhen a window is inserted, you can choose to keep the focus on the old window without switching to the new window
M-C-a
toggles this behaviorg
temporarily toggles this behavior as wellSome points to note:
g2w
(move down 2 windows), press M-g
followed by 2
and w
.
M1-<tab>
, for which you press the exact key combo{}
means the key inside is not needed when the motion is passed as an argument to a command[]
means the key inside is optional<num>
can be any number from 2 to 9<tab>
means any tab label in the current line<row>
means any row label in the current workspace<workspace>
means any workspace label in the current X session<reg>
means a single alpha-numeric character register
/
: a special register that pops out a prompt for you to enter the exact arbitrary name for the register"
: the unnamed register used by move and paste
1
to 9
*
: always references the minimized windows that aren't present in any other register'
: always references the last visited window'Adw
deletes the window and appends it to register a
, whereas 'adw
deletes the window and it then replaces the original content in register a
<group>
means the filterKey
of a task group in the current workspace
c
, which is the task group of the current window gc
cycles to the next window for the current task group, dgc
deletes all the windows in the current task group<macro>
means a single- or multi- character macro register; the characters can be any that can be typed on the keyboard, except
/
: a special register that pops out a prompt for you to enter the exact name for the macrof<tab>
: moves to the tab with label <tab>
<M1-<tab>>
: leaps to the given tab
f
is that leap references the tab without travelling along any windowf<C-<row>>
: moves to the given row<C-<row>>
: leaps to the given row
f<M-<workspace>>
: moves to the given workspaceM-<workspace>
: leaps to the given workspace
[{g}<num>]b
: to the <num>
'th windows/tabs back[{g}<num>]w
: to the <num>
'th windows/tabs forward{g}0
: to the beginning of the line{g}$
: to the end of the line{g}<C-0>
: to the first row{g}<C-$>
: to the last row{g}<M-0>
: to the first workspace{g}<M-$>
: to the last workspacegg
: go to the top line
{g}G
: go to the bottom line
{g}<num>G
: go to the <num>
'th line
g<group>
: cycle to the next window in <group>
G<group>
: cycle to the previous window in <group>
{g}'<reg>
: cycle to the next window in the <reg>
[{g}<num>]k
: to the <num>
'th line up
[{g}<num>]j
: to the <num>
'th line down
[{g}<num>]h
: to the <num>
'th row back
[{g}<num>]l
: to the <num>
'th row forward
[{g}<num>][
: to the <num>
'th workspace back
[{g}<num>]]
: to the <num>
'th workspace forward
;
: repeat the last g<group>
, G<group>
, '<tag>
search motion,
: reverse the last g<group>
, G<group>
, '<tag>
search motionM-o
: move to the previous window in the jumplistM-i
: move to the next window in the jumplistObjects are used with commands, where the same command is applied to all the windows contained in the object.
[<num>]<command>
: apply the command to <num>
of lines starting from the current line
<command>
means the same letter as the command, e.g., dd
deletes the current line[<num>]r
: apply the command to <num>
of rows starting from the current one[<num>]s
: apply the command to <num>
of workspaces starting from the current one['<reg>]d<motion/object>
'<reg>
is given, minimize the windows selected by the <motion/object>
and then attach them to register <reg>
<motion/object>
<motion/object>
is workspace-wise, and the range includes the temporary workspace, `
, the windows inside `
will be deleted but the temporary workspace itself will always persist['<reg>]m<motion/object>
Same as delete, except
'<reg>
is not given, minimize the windows into "
register
"12345678
one step forward to 123456789
and then forgetting the windows in register 9
*
)'<reg>y<motion/object>
yank the windows selected by <motion/object>
into register <reg>
<motion/object>
are not supported['<reg>][g]p
paste the windows in register <reg>
g
is supplied, temporarily alter the current insertion order<reg>
is not supplied, paste windows in the unnamed register "
['<reg>]c<motion/object><group>
delete the windows selected by <motion/object>
into <reg>
and replace them by a new window constructed for group <group>
/
, which brings up the DynamicPrompt to launch arbitrary windows['<reg>]c[<num>][g]<insert position><group>
delete the visually selected windows into <reg>
(only applicable within active visual mode), construct <num>
of new window(s) for group <group>
and insert it/them at the position specified by <insert position>
, which can be:
a
: after the current window
i
: before the current window (the default behavior of XMonad)
A
: at the end of the line
I
: at the beginning of the line
C-j
: as a new line down
C-k
: as a new line up
C-h
: as a new row on the left
C-l
: as a new row on the right
similar to change, a special group is /
, which brings up the DynamicPrompt to launch arbitrary windows
when g
is supplied, temporarily alter the current insertion order
u<motion/object>
remove the association between the windows selected by <motion/object>
with any registers
.
repeat the last command
Window style is a convenient way to configure the commonly used positions and dimensions for float windows.
For each type of window (as defined by the task group), you have the opportunity to define the list of float styles.
Note you would almost certainly want to include doSink
in the list so that one of the styles is sinking the window back into the tiles.
M-t
: cycle forward in the style list for the current windowM-S-t
: cycle backward in the style list for the current windowMacros are by default stored under ~/.macros
. There are two types of macros
xdotool
, like a snippetq<macro>
: start recording the ensuing key sequences into <macro>
●
followed by the name of the macroq<Esc>
: stop recordinga<macro>
: play the macro stored in <macro>
Similar to vim, VIMonad allows you to visually select windows. There is, however, an added subtlety about passive/active visual.
Passive visual is indicated by a small triangle on the right edge of the selected tab. It stays on unless M-<Esc>
is pressed.
Passive visual is useful for chaining commands - you can for example, move the selected windows into the left adjacent row and continue moving them up/down different lines.
Active visual is indicated by a small square on the right edge of the selected tab. This is more like the visual mode in vim.
You can enter the active visual mode by
M-v
: visually select the current window and enter window-wise selection modeM-S-v
: visually select the current line and enter line-wise selection modeM-C-v
: visually select the current row and enter row-wise selection modeIn the active visual mode you can perform any motion to toggle the selection of windows in the respective range.
To quit the active visual mode, press M-<Esc>
; this commits the selected windows to passive visual (press M-<Esc>
again to remove passive visual).
These commands operate on
['<reg>]x
: delete counterpart for selection['<reg>]X
: same as ['<reg>]x
, but focuses the previous window after deleting the selected ones['<reg>]C-x
: move counterpart for selection['<reg>]C-S-x
: same as ['<reg>]C-x
, but focuses the previous window after moving the selected onesy<reg>
: yank counterpart for selectionM-S-u
: unregister counterpart for selectionM-S-j
: move the selected windows down a lineM-S-k
: move the selected windows up a lineM-S-h
: move the selected windows left a rowM-S-l
: move the selected windows right a rowM-C-j
: move the selected windows to a new line downM-C-k
: move the selected windows to a new line upM-C-h
: move the selected windows to a new row leftM-C-l
: move the selected windows to a new row right[g<num>]W
: swap the selected windows <num>
of times down the line
[g<num>]B
: swap the selected window <num>
of times up the line
[g<num>]}
: shift the selected windows to the workspace <num>
of distance down[g<num>]{
: shift the selected windows to the workspace <num>
of distance up<M1-S-<tab>>
: insert the selected windows at <tab>
<C-S-<row>>
: shift the selected windows to <row>
<M-S-<workspace>>
: shift the selected windows to <workspace>
<M-S-6>
: shift the selected windows to the last visited workspace[g<num>]<S-C-j>
: swap the current line <num>
of times down[g<num>]<S-C-k>
: swap the current line <num>
of times up[g<num>]<S-C-h>
: swap the current row <num>
of times left[g<num>]<S-C-l>
: swap the current row <num>
of times right[g<num>]<C-]>
: swap the current workspace <num>
of times down[g<num>]<C-[>
: swap the current workspace <num>
of times up<M-6>
: switch to the last visited workspace<M-C-6>
: swap the current workspace with the last visited workspaceM-<Space>
: toggle Full
layout for the current row (maximize the focused window in the current row)M-S-<Space>
: toggle Full
layout for the current workspace (maximize the current row in the workspace)As mentioned before, each workspace in VIMonad is dynamically allocated, and linked to a directory when being created. This is achieved via the workspace prompt - the prompt allows you to search in a tag database composed of directories with their names as tags (by default under ~/DB
), and select/create the directory for initializing the workspace.
For example, say I want to create a new workspace after the current one for research on VIMonad
, I can
M-s a
(mnemonic: space create after), and enter in the prompt VIMonad
indie/VIMonad
to create a new tag inside indie
and root the new workspace in that new directoryVIMonad
in the prompt; this gives me a new workspace rooted on home directoryThe full syntax for the workspace prompt is:
s[<num>]<space action>
where <space action>
can be
a
: create workspace after the current one (or switch to an existing workspace)<M-a>
: clone the current workspace after itself
i
: create workspace before the current one (or switch to an existing workspace)<M-i>
: clone the current workspace before itselfA
: create workspace at the end of the workspace list (or switch to an existing workspace)<M-A>
: clone the current workspace at the end of the workspace listI
: create workspace at the beginning of the workspace list (or switch to an existing workspace)<M-I>
: clone the current workspace at the beginning of the workspace listC
: change the name of the current directoryDynamic prompt is an integral part of VIMonad as it handles almost all program-related aspects of the system. Instead of being a simple program launcher like dmenu, dynamic prompt is more like a full-fledged shell environment.
Dynamic prompt is activated via M-r
.
You can
execute arbitrary shell commands, with full shell completion support
rifle
from ranger
<Enter>
is pressed, the prompt will run the command on the prompt, block user input and eventually show the output of the command via completionC-<Enter>
is pressed, the prompt will silently run the command on the prompt in the background
sil
, e.g., sil chmod +x bin/binfile
preview files
search files dynamically with search widgets
l
(locate): search for files recursively in a given directory (or the current one, if not specified) using find
l [directory/to/search] KEYWORD KEYWORD ...
<Tab>
and S-<Tab>
to select the files/directoriest
(tag): search for a directory in the tag database using findg
(grep): list all files containing the given words inside a given directory (or the current one, if not specified)
g [directory/to/search] KEYWORD KEYWORD ...
<Tab>
and S-<Tab>
to select the filesh
(history): search for files launched in the past enter application-specific completion environment
execute shortcut commands, e.g.
input Chinese words
\pinyin
<Tab>
or S-<Tab>
to select the word you'd like拼
for \pinyin
, after selecting 拼
the prompt will become 拼yin
with cursor positioned after 拼
Search windows by register/title/workspace name in the current X session
M-/
: search windows and navigate to the selected oneM-?
: search windows and bring the selected one to the current workspaceThe wallpaper prompt enables you to switch wallpapers on the fly; it also has a wallhaven backend as well as a rss downloader backend (for flickr) for you to search and download wallpapers by tag/description.
Wallpaper prompt is triggered by M-z
. When the prompt is active, all the windows will be painted semi-transparent so that you can look through them to see the glory of the wallpapers.
I've put a lot of effort into VIMonad over the years, but there is no guarantee that it will work on your system. More specifically:
If you intend to try VIMonad and have encountered any problem, you're welcome to use the issue tracker.