Layout Management
Rune is a full virtualized tiling window manager, inspired by i3. You split the screen into windows, fill them with content from tabs, group projects into workspaces, and dock background work as tasks. This guide builds that picture up one primitive at a time, and along the way you will see why the default keybindings are the way they are.
On macOS, <meta> is the Command key. On Linux / Windows it is the
Super / Windows key. See the key syntax reference for
how modifiers are spelled.
The big idea
Every layout action is a command you can type at the prompt. The default keybindings are just shortcuts for those commands, and they are organized around a small, standardized system:
<meta>is the window and workspace layer. Anything that focuses, moves, splits, or sizes a window, or switches a workspace, is a<meta>chord.<alt>is the tab layer. Anything that switches or reorders the tabs inside a window is an<alt>chord.- Direction is
hjklor the arrow keys. With modal key bindings you point withhjkl; with modeless key bindings you point with the arrow keys. - Adding
<shift>means "move" instead of "go to".<meta>plus a direction focuses a window; add<shift>and the same direction moves the window. The same<shift>= move rule holds for tabs and for workspaces.
So, in modal mode:
| Modal | Modeless | Action |
|---|---|---|
<meta-h> | <meta-left> | Focus the window to the left. |
<shift-meta-h> | <shift-meta-left> | Move the current window left. |
<alt-h> | <alt-meta-left> | Go to the previous tab. |
<alt-shift-h> | <alt-shift-left> | Move the current tab one slot to the left. |
<meta-2> | <meta-2> | Focus workspace 2. |
<shift-meta-2> | Move the current workspace to slot 2. |
Once you internalize "<meta> = windows/workspaces, <alt> = tabs,
<shift> = move", most of the layout bindings stop being something to
memorize and start being something you can derive.
The pattern is cleanest in modal mode, where direction lives on hjkl
and the arrow keys are free. The modeless preset keeps the same spine
but spells direction with the arrow keys. Both layouts are listed side
by side in the reference tables at the end.
Windows
A window is a tile on screen. A fresh workspace has one window filling the editor area; you split it to get more.
Split the current window in two with windownew. With no argument it
uses your default split orientation (see below); pass a direction to
force one:
windownew right
<meta-enter> is the shortcut you will reach for most: it runs
terminalneworsplit, which drops a terminal into the current window if
it is empty, or splits off a new window with a terminal if it is not.
Once you have more than one window, <meta> plus a direction focuses
across them:
| Action | Modal | Modeless |
|---|---|---|
| Focus window left | <meta-h> | <meta-left> |
| Focus window right | <meta-l> | <meta-right> |
| Focus window down | <meta-j> | <meta-down> |
| Focus window up | <meta-k> | <meta-up> |
Add <shift> and the same direction moves the focused window's
content in that direction, swapping it with its neighbor. This is
windowmove:
| Action | Modal | Modeless |
|---|---|---|
| Move window left | <shift-meta-h> | <shift-meta-left> |
| Move window right | <shift-meta-l> | <shift-meta-right> |
| Move window down | <shift-meta-j> | <shift-meta-down> |
| Move window up | <shift-meta-k> | <shift-meta-up> |
New splits land relative to the current window according to the
default split orientation. windowdefaultsplit toggles it, or sets
it explicitly: horizontal puts the next split below the current
window, vertical puts it to the right. The shortcuts are <ctrl-meta-h>
(horizontal) and <ctrl-meta-v> (vertical), the same in both modes.
Close the focused window with windowclose (<meta-w> modal,
<shift-meta-w> modeless). It fails if only one window is left, since a
workspace always has at least one.
Resizing windows
windowresize grows or shrinks the focused window. The grammar is
windowresize (increase|decrease|max|min|reset) (width|height).
In modal mode resize lives on the arrow keys (which are otherwise
free, because direction is on hjkl):
| Action | Modal |
|---|---|
| Taller | <shift-meta-up> |
| Shorter | <shift-meta-down> |
| Narrower | <shift-meta-left> |
| Wider | <shift-meta-right> |
| Maximize both | <shift-meta-+> |
| Minimize both | <shift-meta--> |
| Reset | <shift-meta-backspace> |
In modeless mode the arrow keys are already taken by focus and move, so
resize shifts one modifier deeper, onto <ctrl-shift-meta> plus an
arrow:
| Action | Modeless |
|---|---|
| Taller | <ctrl-shift-meta-up> |
| Shorter | <ctrl-shift-meta-down> |
| Narrower | <ctrl-shift-meta-left> |
| Wider | <ctrl-shift-meta-right> |
| Maximize both | <ctrl-shift-meta-+> |
| Minimize both | <ctrl-shift-meta--> |
| Reset | <ctrl-shift-meta-backspace> |
windowtogglemaximize is the quick "blow this window up, then put it
back" toggle. It maximizes width and height, and a second press (or
focusing another window) resets the size. In modeless it is <shift-meta-f>.
Content and file tabs
A window does not own a file; it displays content, and the content it can show is a list of tabs. Open files, terminals, and task output are all tabs. Switching tabs swaps what the focused window shows without changing the window layout.
Tabs are the <alt> layer:
| Action | Modal | Modeless |
|---|---|---|
| New tab | <meta-t> | <meta-t> |
| Next tab | <alt-l> | <alt-meta-right> |
| Previous tab | <alt-h> | <alt-meta-left> |
| Focus tab N | <alt-1> … <alt-9> | |
| Search tabs | <alt-`> | <alt-`> |
| Close tab | <alt-w> | <meta-w> |
And, following the <shift> = move rule, <alt-shift> reorders the
current tab with tabmove:
| Action | Modal | Modeless |
|---|---|---|
| Move tab left | <alt-shift-h> | <alt-shift-left> |
| Move tab right | <alt-shift-l> | <alt-shift-right> |
| Move tab to slot N | <alt-shift-1> … <alt-shift-9> |
tabnext and tabprevious wrap around the ends of the list.
tabfocus N jumps straight to a position. tabmove takes a direction
or an absolute slot number, exactly like the keybindings suggest.
Splits versus tabs
Splits and tabs solve different problems. Split into a new window when you want to see two things at once (a test beside its source, a terminal under an editor). Open a new tab when you want another thing available in the same window, one at a time.
Not every piece of content needs a tab, though. Some content is
ephemeral: it lives in the focused window but is never added to the
tab list, so it does not clutter the bar and disappears when you move
on. A quick terminal is the common case. terminalnew drops an
ephemeral terminal into the current window when you just need to run
one command and throw it away. When you want that terminal to stick
around, say you are flipping between a test file and the tests running
beside it, use terminalnewtab instead, which gives the terminal a
durable tab you can switch back to.
You can convert between them. windowconverttab takes the content of
the focused window and turns it into a tab, collapsing the split.
The shortcut is <alt-enter> in modal mode:
windowconverttab <name> [<icon>]
If the focused window is a floating window, converting it to a tab closes the floater.
Floating windows
Some windows float above the tiling layout instead of taking a slot in
it. The canonical example is the file explorer:
it is a pre-minimized floating window docked on the left. fexplorer
(<shift-tab>) un-minimizes and focuses it, and invoking the command
again minimizes it back.
The location picker, fuzzy file and symbol search, and the command prompt itself are floating surfaces too. They appear on top of your windows, take focus while open, and get out of the way when you are done, without ever disturbing the windows underneath.
Workspaces
A workspace is a whole project: its own window layout, its own tabs, its own root directory. Rune keeps up to nine workspaces in numbered slots, with their tabs shown along the bottom of the screen.
Workspaces are the other half of the <meta> layer, this time with
digits instead of directions. The symmetry with windows is exact:
<meta> plus a digit focuses a workspace, and <shift> makes it move.
| Action | Modal | Modeless |
|---|---|---|
| Focus workspace N | <meta-1> … <meta-9> | <meta-1> … <meta-9> |
| Move workspace to slot N | <shift-meta-1> … <shift-meta-9> | |
| Search workspaces | <meta-`> |
workspaceopen <uri> opens another project in the first free slot (or
the current one if it is empty); if the URI has no scheme, file:// is
assumed. workspacefocus N switches to a slot, and workspacemove N
reorders the workspace tabs the same way tabmove reorders content
tabs.
This is the payoff of the system: <meta> always means "the window and
workspace layer", whether you follow it with a direction (a window) or a
digit (a workspace), and <shift> always means "move the thing rather
than go to it".
Tasks
A task is a long-running command (a build, a test run, a dev server) that Rune keeps as a first-class window instead of hiding it in another terminal. Tasks plug into the same layout primitives you have just seen.
tasknew creates a task and minimizes it to the side of the screen,
where it shows as a small colored window: gray while running, green on a
clean exit, red on failure, yellow if you cancelled it. Press <esc> to
minimize a focused task back down; taskfocus <name> brings it back up,
and taskclose <name> stops it.
tasknewtab is the tab-shaped variant. It is exactly tasknew followed
by focusing the task and running windowconverttab, so the task lives
as a durable tab whose name and color track its status. Reach for it
when the task's output is the thing you want to watch (a server log, a
tail -F), and for tasknew when only the task's status matters.
See the Tasks guide for the full command grammar, file watchers, and examples.
The pattern, summarized
| Layer | Focus / go to | Move |
|---|---|---|
| Window | <meta> + direction | <shift-meta> + direction |
| Workspace | <meta> + digit | <shift-meta> + digit |
| Tab | <alt> + direction / digit | <alt-shift> + direction / digit |
Direction is hjkl in modal mode and the arrow keys in modeless mode.
Window resizing rides alongside window moves: on the arrow keys in modal
mode, and on <ctrl-shift-meta> + arrows in modeless mode, where the
plain arrows are already spoken for.
Layout aliases
If you tend to arrange a workspace the same few ways, capture each
arrangement as an alias that tears the layout
down and rebuilds it. Because windowcloseall and windownew are
ordinary commands, a multi-step alias
can re-shuffle the workspace into one layout or another in a single
dispatch.
For example, a three-window layout for a wide auxiliary screen, and a two-window layout for the laptop:
- config.yaml
- config.star
command:
aliases:
layout-aux-screen:
- windowcloseall
- windownew right
- windownew right
layout-laptop:
- windowcloseall
- windownew right
"aliases": {
"layout-aux-screen": [
"windowcloseall",
"windownew right",
"windownew right",
],
"layout-laptop": [
"windowcloseall",
"windownew right",
],
},
layout-aux-screen closes every window, then splits twice for a total of
three windows side by side; layout-laptop leaves you with two. Run the
one that fits the screen you are on, and the workspace snaps into shape.
Reference tables
These are the shipped defaults. Every binding is a shortcut for the
command shown, and all of them live in command.key_bindings, so you
can remap any of them (see Rebinding).
Modal
| Command | Binding |
|---|---|
windowfocus left/right/down/up | <meta-h> / <meta-l> / <meta-j> / <meta-k> |
windowmove left/right/down/up | <shift-meta-h> / <shift-meta-l> / <shift-meta-j> / <shift-meta-k> |
windowresize width/height | <shift-meta-left> / <shift-meta-right> / <shift-meta-down> / <shift-meta-up> |
windowresize max / min / reset | <shift-meta-+> / <shift-meta--> / <shift-meta-backspace> |
windowtogglemaximize | <shift-meta-f> |
windowdefaultsplit h/v | <ctrl-meta-h> / <ctrl-meta-v> |
windownew | <meta-n> |
windowclose | <meta-w> |
tabnew | <meta-t> |
tabnext / tabprevious | <alt-l> / <alt-h> |
tabfocus 1..9 | <alt-1> … <alt-9> |
tabmove left/right | <alt-shift-h> / <alt-shift-l> |
tabmove 1..9 | <alt-shift-1> … <alt-shift-9> |
tabsearch | <alt-`> |
tabclose | <alt-w> |
windowconverttab | <alt-enter> |
terminalneworsplit | <meta-enter> |
workspacefocus 1..9 | <meta-1> … <meta-9> |
workspacemove 1..9 | <shift-meta-1> … <shift-meta-9> |
workspacesearch | <meta-`> |
Modeless
| Command | Binding |
|---|---|
windowfocus left/right/down/up | <meta-left> / <meta-right> / <meta-down> / <meta-up> |
windowmove left/right/down/up | <shift-meta-left> / <shift-meta-right> / <shift-meta-down> / <shift-meta-up> |
windowresize width/height | <ctrl-shift-meta-left> / <ctrl-shift-meta-right> / <ctrl-shift-meta-down> / <ctrl-shift-meta-up> |
windowresize max / min / reset | <ctrl-shift-meta-+> / <ctrl-shift-meta--> / <ctrl-shift-meta-backspace> |
windowtogglemaximize | <shift-meta-f> |
windowdefaultsplit h/v | <ctrl-meta-h> / <ctrl-meta-v> |
windownew | <meta-n> |
windowclose | <meta-w> |
tabnew | <meta-t> |
tabnext / tabprevious | <alt-meta-right> / <alt-meta-left> |
tabmove left/right | <alt-shift-left> / <alt-shift-right> |
tabsearch | <alt-`> |
tabclose | <alt-w> |
terminalneworsplit | <meta-enter> |
workspacefocus 1..9 | <meta-1> … <meta-9> |
Rebinding
None of these bindings are fixed. They are entries in
command.key_bindings, and you can override any of them in your config.
For example, to focus windows with <ctrl> plus the arrow keys:
- config.yaml
- config.star
command:
key_bindings:
"<ctrl-left>": "windowfocus left"
"<ctrl-right>": "windowfocus right"
"<ctrl-down>": "windowfocus down"
"<ctrl-up>": "windowfocus up"
for key, dir in [
("<ctrl-left>", "left"),
("<ctrl-right>", "right"),
("<ctrl-down>", "down"),
("<ctrl-up>", "up"),
]:
config["command"]["key_bindings"][key] = "windowfocus " + dir
Set a binding to "" to unbind it. See Config for where
the file lives and key syntax for the full grammar of
key combinations.
*** End Patch