Panes, Tabs & Workspaces
luvus is mouse-native: everything here works by click and drag, and every
action also has a key behind the Ctrl+Space prefix.
Most shortcuts act immediately; pane-navigation and keyboard-resize modes
temporarily capture keys until you leave them.
A pane is a real terminal. Inside a tab you can split it as many ways as you like, and luvus tiles them automatically.
| Do this | Mouse | Key |
|---|---|---|
| Split side by side | right-click a pane → Split | Ctrl+Space v |
| Split top / bottom | right-click a pane → Split down | Ctrl+Space s |
| Focus a pane | click it | Ctrl+Space then an arrow to preview; more arrows move, Enter focuses, Esc cancels; hjkl focuses immediately |
| Move a pane to another tab | right-click → Move to Tab | n/a |
| Zoom (fullscreen) a pane | n/a | Ctrl+Space z |
| Close a pane | the × on its title, or right-click → Close |
Ctrl+Space x |
Each split pane shows a title bar with a status dot and its working directory. The focused pane’s frame is brighter.
In a tiled tab, arrow navigation highlights a candidate without changing the
active pane or sending it input. When Commander is open, Down from the bottom
pane can highlight its input; Up returns to that pane. Enter commits the
highlighted focus; Esc keeps the original focus. Compact and zoomed layouts
retain one-step pane focus.
Resizing
Section titled “Resizing”Three ways, whichever fits your hands:
- Drag a divider. Hover the border between two panes (it brightens) and drag.
- Ctrl+drag anywhere inside a pane to nudge its edges. (
Ctrl+click on a URL or a file path opens it instead, see Opening links and files.) - Keyboard resize mode:
Ctrl+Space r, then the arrow keys grow/shrink the focused pane.EscorEnterleaves the mode.
Each workspace has a strip of tabs at the top. A tab holds one pane layout (or a
special dashboard, such as the ⎇ git tab or the ◇ orch board).
| Do this | Mouse | Key |
|---|---|---|
| New tab | the + on the tab bar |
Ctrl+Space c |
| Next / previous tab | click a tab | Ctrl+Space n / p / ⇥ |
| Close a tab | the × on the tab |
Ctrl+Space x (on a dashboard) |
| Rename a tab | right-click the tab → Rename, type a name, ⏎ |
luvus tab rename <name> |
| Move a tab one position | right-click the tab → Move Left / Move Right | luvus tab move left / right |
| Swap two tab positions | right-click a tab → Swap With, choose the other tab | luvus tab swap <first> <second> |
A renamed tab shows your label instead of its number (empty reverts to the number). Dashboard tabs keep their fixed labels. Swap With lists every other tab in the workspace, including tabs hidden by tab-bar overflow. Choosing one exchanges its position with the right-clicked tab without changing which tab is active.
The CLI exposes the same pane move plus tab reordering for scripts and agents:
luvus pane move 7 --tab 2 # existing tab in pane 7's workspaceluvus pane move 7 --new-tab # append a fresh tab for pane 7luvus tab focus 4 # focus exact tab 4luvus tab move left # move the active tab one position leftluvus tab move right --tab 4 # move exact tab 4 one position rightluvus tab move 3 1 # move current workspace tab 3 to position 1luvus tab swap 1 4 # exchange the tabs in positions 1 and 4All tab numbers are 1-based and validated; missing, zero, or out-of-range positions fail instead of silently selecting a different tab. A pane move keeps its process running and follows it with focus. Tab reordering uses the requested final position and preserves whichever tab was active.
Workspaces
Section titled “Workspaces”A workspace is one project folder, fixed at its cwd (see
Core Concepts). They
live in the sidebar’s top list.
Closing the final workspace leaves the client attached with the normal Luvus
chrome instead of closing the app or showing a separate landing screen. Luvus
immediately replaces it with a neutral workspace and real terminal rooted at
your home directory. You can type, change directory, create tabs or splits, and
open the folder picker normally. The sidebar path remains the workspace root.
Pane titles use an explicit pane name when one exists and otherwise show a
stable p<ID> fallback. Enable Show path in pane titles under
Settings → Layout to append each terminal’s live working directory.
- Open one: the
+button above the list, orCtrl+Space N, opens a folder picker. Browse with the arrows / wheel, use the Home row to jump home, or pressg(also clickable in the footer) to type an absolute, relative, or~/…path without leaving the picker. Tab completes folders in Go to;⏎only navigates. Select Open this folder afterward to confirm the workspace. Pressnto create-and-open a new folder, orwto open a repo as a new worktree. Runningluvusinside a folder also adds it automatically. - Switch quickly: use
Ctrl+Space u/Uto cycle to the next / previous workspace. - Navigate the list:
Ctrl+Space wfocuses WORKSPACES. Use arrows orj/k, pressEnterto switch,ato open the selected row’s action menu, andEscorqto return input to the pane. - Jump to its git tab: right-click the workspace and choose Open Git
Tab, or focus it and press
Ctrl+Space g.
Changing directory inside a pane
Section titled “Changing directory inside a pane”Running cd changes that pane’s live working directory without reorganizing
the workspace. The tab stays where you placed it, the workspace keeps its
project root, and an empty source workspace is never created by a directory
change. Open another repository or linked worktree explicitly when you want it
to become a workspace. You can still move panes and tabs with their existing
UI, CLI, and UHP controls.
Right-click a workspace
Section titled “Right-click a workspace”Right-click any workspace row for its menu:
- Close the workspace
- Rename its label (this changes the sidebar name only, never the folder on disk)
- Pin / Unpin it at the top of the list. A linked worktree stays with its parent, so pinning either one moves the complete group.
- Hide Path switches WORKSPACES to compact one-row entries. Right-click again and choose Show Path to restore the cwd rows. Luvus remembers this choice across restarts.
- New Git Worktree creates a checkout on a new branch; Open Worktree lists every existing, non-bare checkout git knows about and opens (or focuses) one. Both appear for git repos only; see Worktrees.
- Open Git Tab · Open Task Board · Open Mission Control
The same organization actions are available from the CLI using stable 0-based workspace indices:
luvus workspace listluvus workspace rename 2 "Luvus website"luvus workspace pin 2luvus workspace unpin 2workspace list reports both the stable API index and display_position, so a
pin never changes which workspace a later command targets. It also reports two
paths. cwd is the stable project root. terminal_cwd is the exact live path
of the focused pane in the active tab. Changing focus updates terminal_cwd, so
split panes with different directories report whichever terminal is currently
selected. The stable cwd and a custom workspace name remain unchanged.
Mission Control is also available without a mouse. Press Ctrl+Space m, choose
it from the desktop switcher with Ctrl+Space M, or open it through automation:
luvus mission openluvus mission open 2The sidebar
Section titled “The sidebar”The sidebar shows your workspaces and your live agents. Collapse it to give the panes the full width:
- Click the
«chevron in the sidebar header (orCtrl+Space b). - When hidden, a
»appears at the tab bar’s left edge to bring it back.
Two sidebars and docks
Section titled “Two sidebars and docks”The sidebar’s sections are docks, relocatable panels. The built-ins are Workspaces and Agents, and luvus has two sidebars (left and right), so you can split reference content from live content across both edges. Modules can add their own docks too (see Writing a Module).
Arrange them in Settings → Layout, under the ── Docks ── divider:
- Each side has a visible toggle and a width.
- Every dock has
[Left] [Right] [Off]buttons. Click to put it on the left sidebar, the right sidebar, or hide it. The current placement is highlighted. - Toggle both sidebars with
Ctrl+Space b.Ctrl+Space Btoggles only the right sidebar when you want to keep the left side visible. - Drag the horizontal rule between two stacked docks on the same side to resize them. Only those two docks change size. The split is remembered across restarts and terminal resizes, and a dock cannot be squeezed below three rows.
For example, move Agents to the right so your agent statuses sit on one edge and your project list on the other. If you hide the left sidebar entirely, the Menu button moves to the right sidebar so Settings is always reachable.
Luvus Bar
Section titled “Luvus Bar”Luvus Bar lets built-ins and modules use the otherwise flexible space beside the tabs and in the middle of the bottom status row. It never adds a row or changes pane/PTY dimensions. Tabs, sidebar toggles, the left prefix guidance, and the clickable version always keep priority.
Arrange declared widgets in Settings → Layout → Luvus Bar:
- Top places a compact widget beside the tabs.
- Bottom places it between the fixed shortcut hint and version.
- Off hides it without deleting module state or its placement declaration.
The declaration rows stay in a stable order while you change placement, so the selected widget does not jump under the pointer.
The built-in Runtime status widget shows NORMAL · 1 pane · tab 2/4 in
Bottom by default and can be moved or hidden. At narrow widths, widgets use
their compact content and then move into a read-only … +N overflow popup;
they never overlap navigation. See the dedicated Luvus Bar guide
for installation, placement, CLI control, module publishing, and troubleshooting.
Both Top and Bottom are capped at 100 display columns. They may be narrower when the viewport has less room: Top reserves the active tab, scroll arrows, and new-tab button, while Bottom reserves the fixed shortcut guidance and version. Extra tabs enter their existing scroll window. A single widget may use all 100 columns when its region has room. These are terminal columns rather than Unicode character counts; wide glyphs such as CJK and many emoji consume two.
Selecting text
Section titled “Selecting text”Drag across any pane to select, and releasing auto-copies to your clipboard. Full details, plus scrollback, are in Scrollback & Copy.
Pasting clipboard images
Section titled “Pasting clipboard images”Copy a screenshot or image, focus an agent pane, then use the paste chord your
terminal sends: Ctrl+V or Ctrl+Shift+V, plus Command+V or
Command+Shift+V on macOS. Luvus reads the clipboard only for that explicit
gesture. A supported image is staged as a private PNG and its path is pasted
into the focused pane without submitting the prompt. Agents that accept image
paths can then attach or inspect it.
Windows reads registered PNG and bitmap clipboard formats directly. macOS reads
PNG or TIFF from the system pasteboard and normalizes it to PNG. Wayland clients
use wl-paste; X11 clients on Linux or FreeBSD use xclip. These Unix helpers
run in the display client and inherit its WAYLAND_DISPLAY, DISPLAY, and
XDG_RUNTIME_DIR; install wl-clipboard or xclip when your desktop does not
already provide the applicable command.
If the clipboard has text, is unavailable, or contains an unsupported image, Luvus forwards the original key unchanged. Image paste is ignored while a Luvus modal, native file view, dashboard, copy mode, or navigation mode owns input, so the private path cannot leak into a pane behind it. The host terminal must pass the chord through to Luvus; a terminal-reserved paste binding can still consume it before Luvus sees it.
Opening links and files
Section titled “Opening links and files”Agents print references all day: the PR they opened, the doc they read, the file they just changed, the test that failed at line 42.
Hold Ctrl and whatever is under your cursor underlines. Ctrl+click
follows it. If you would rather not hold a modifier, right-click and pick
Open Link or Open File.
| Under the cursor | What a Ctrl+click does |
|---|---|
https://luvus.dev/docs |
opens in your browser |
luvus.dev/docs |
same, with https:// filled in |
localhost:3000 |
opens your dev server, over http |
src/main.rs |
opens in luvus, where File click behavior says |
src/main.rs:42 |
the same, scrolled to line 42 |
When the terminal forwards the click, a file path opens in luvus and lands where a click on that file’s FILES row would — your Settings → General → File click behavior choice:
- Preview (the default): the workspace’s reused preview pane, beside the pane you clicked in. The agent that printed the path stays on screen.
- Open in tab: a new tab, through your Open files with choice — the built-in read-only viewer, or your terminal editor if you set one.
Ctrl+Shift+click opens a permanent pane beside the focus instead, the
same as Shift+click on a FILES row.
path:42 preserves the requested line in Preview, permanent-pane and built-in
read-only tab placements. A configured terminal editor opens the file at the
top, because line-jump arguments differ between editors.
When an agent such as Claude prints a terminal file hyperlink, luvus uses its validated local file target rather than guessing from the visible label. It then follows the same File click behavior and Open files with settings.
If the agent prints a plain path instead, holding Ctrl lets luvus project the
validated path as a local file link for the outer terminal too. This prevents a
label such as server/scripts/task.mjs from being mistaken for a web address.
The placement behavior above applies when the terminal forwards the click to
luvus. A terminal that claims OSC 8 clicks itself opens the validated path with
its own file handler, so luvus cannot apply File click behavior to that
gesture.
Remote attachments do not project server file paths as host-local links. Those paths may not exist on the client machine; let the click reach luvus so its server-aware native file view handles the target instead. Luvus also suppresses these projections for SSH and tmux clients, where the outer terminal may belong to a different filesystem. A direct local terminal must identify itself before Luvus exposes server file paths to its file handler.
A path only underlines if the file is really there. Paths are resolved against
that pane’s working directory, so src/main.rs means what it means to the shell
you are looking at. Text that merely looks like a path stays inert, and so do
directories. That means a link you can see is always a link that works.
Compiler and test output usually prints file:line, and that whole reference is
one link. The line number is honoured by the built-in viewer. A terminal editor
opens the file at the top instead, since the flag for jumping to a line is
different for every editor.
You do not need the https://. A bare luvus.dev or google.com/search works,
and localhost:3000 opens your dev server over plain http.
Bare domains are matched conservatively, so ordinary text does not turn into links:
the name has to be lower case, end in a TLD luvus knows, and localhost needs a
port on it. If a domain of yours is not recognised, writing the https:// always
works.
One consequence worth knowing: a filename can also be a domain. .rs is
Serbia, .md is Moldova. So main.rs is ambiguous, and luvus settles it by
looking at the disk: if the file is there, it opens the file. If not, and the name
is a real domain, it opens the site. If neither, nothing happens.
Only http and https URLs open. Everything else is ignored on purpose: the text
comes from whatever is running in the pane, and a click would end up at whatever
your system has registered for that scheme.
Two more details:
- A URL that wrapped onto the next line still opens as one link. This is the part your terminal cannot do for you, because it only sees the finished screen.
- The browser that opens is on the machine you are sitting at, even when you
attached to a remote server with
--remote.
Ctrl+drag still resizes panes as it always did. The two never collide, because
a link only opens when you release without moving.
Detaching
Section titled “Detaching”Closing your terminal never loses work, because the server keeps every pane alive. Run
luvus again to reattach, or Ctrl+Space d to detach on purpose. See
Your First Session.