Modes
Vimma's keys depend on the mode, as in Vim. Most of the time you are in normal mode, where letters are commands: j scrolls, f shows link hints. Click into a text field and you are in insert mode, where letters type. The badge at the left of the status bar always says which mode you are in, and Esc takes you back to normal.
The modes at a glance
| Badge | When you are in it | How to get back to normal |
|---|---|---|
NORMAL | On every page, by default. Letters are Vimma's commands; the page does not see them. | You are there. |
INSERT | While a text field has focus, or after i. Keys type into the page. | Esc |
HINT | After f or F: labels on everything you can click. | Type a label, or Esc |
VISUAL | Copy mode, after v: a caret and a selection (Copy mode). | y copies and leaves, or Esc |
COMMAND | While you type a : command or a / search, at the bottom of the window. | Enter runs it, Esc cancels |
HELP | While the ctrl+b ? key list or the ctrl+b g tab list is open. | Esc or q |
RESIZE | After ctrl+b r, to resize panes. | Esc |
Two kinds of keys
- Bare keys (j, f, /) depend on the mode. In normal mode they are Vimma's; in insert mode they type.
- ctrl+b keys work in every mode, even while you type in a field or the URL bar, because ctrl+b never types anything. Press ctrl+b, let go, then press the next key. The status bar shows
prefixwhile it waits; Esc cancels.
Keys Vimma does not use reach the page as usual: a site's own shortcut on s or m still works in normal mode.
Typing in a page
- Click a text field, pick it with f, or press i to focus the first one on the page (gi: the first one you can see; 3gi: the third). You are in insert mode.
- Esc leaves the field and puts you back in normal mode. The page does not see that Esc: if a site wanted it (to close its own pop-up), press Esc once more.
- On a page with its own keyboard controls, such as a game, i lets every key through to the page until you press Esc.
- While you type, Vim's editing keys work: ctrl+w deletes a word, ctrl+u the line before the caret, ctrl+h a character. They work in the URL bar and the : line too.
- I jumps to the address bar from normal mode, its address selected, ready to type over. Esc brings you back to the page.
The command line
: opens a Vim-style command line at the bottom of the window. Type a command, press Enter to run it or Esc to cancel. Tab completes, and Up brings back what you ran before. Some to start with:
| Command | What it does |
|---|---|
:open example.com | Opens the address in this tab; other words are a web search. |
:tabnew example.com | The same, in a new tab. |
:q | Closes the pane, or the tab when there is one pane. |
:workspace work | Switches to the workspace called work. |
:help | Lists every key, as ctrl+b ? does. |
The full list is under Details. Any action on the keys page runs by its name too, such as :scroll_down.
If keys seem to do nothing
- Look at the badge.
INSERTmeans a text field has focus: press Esc. - Settings (
about:preferences) focuses its search box when it opens, so it starts in insert mode: press Esc before j or k. - Extension pages,
data:andview-source:pages stay in insert mode: Vimma does not reach them. ctrl+b keys still work there. More on the troubleshooting page.
All the keys for this page
The default bindings, as Vimma's own ctrl+b ? overlay lists them. Name is the action's name, which you use to remap it or to run it as a : command. Every key is on the keys page.
Modes (5)
| Action | Keys | Name |
|---|---|---|
| Back to normal mode | escinsertescvisual | normal_mode |
| Insert mode: focus the first input | i | insert_mode |
| Copy mode (caret browsing + selection) | ctrl+b [v | copy_mode |
| Command line | : | command_line |
| Close the command line | esccommand | command_cancel |
Details
Everything below is Vimma's own user guide for this topic, in full: every edge case and exception. You do not need it to get started.
The two layers
Vimma splits the keyboard into two layers, as your editor and terminal already do: Vim's modes for the page, tmux's prefix for the window. One dispatcher sees every key before Firefox does, in the URL bar, on about: pages and in the PDF viewer too, so the keys behave the same everywhere.
- The prefix layer (tmux).
ctrl+bis the prefix, like tmux's default prefix. The next key is a command:ctrl+b ?shows the bindings,ctrl+b copens a tab,ctrl+b vsplits the pane, and so on. The prefix works in every mode and waits for the next key with no timeout.Esccancels it. - The modal layer (Vim). Bare keys act on the page depending on the mode:
j/kscroll innormalmode, while ininsertmode (focus in a text field) keys go to the page.visualis copy mode (caret and selection),hintis link hints,helpthe bindings overlay andcommandthe:line,resizeis resize mode for panes (ctrl+b r) andpanelthe side panel (ctrl+b b).
Normal and insert mode
Every tab starts in normal mode: Vimma's bare keys (the table below) act on the page, and the page never sees them. This is where you read, scroll and jump. Keys Vimma has no binding for, such as z or a site's own s or m, still reach the page.
Focusing a text field puts the tab in insert mode, so typing works as in Firefox: inputs, text areas, editable regions (contenteditable), ARIA text boxes, code editors (Monaco, CodeMirror, Ace, ProseMirror, Quill), fields inside web components and inside frames from other sites. Focusing a checkbox, button or link does not. Esc leaves insert: it takes focus out of the field and the tab is back in normal. i enters insert explicitly: it focuses the first text field on the page, or, on a page without one (a game), lets every key through until Esc.
Clicking into a page that is editable as a whole (a designMode document, such as some rich text editors' frames) also enters insert.
Each tab keeps its own mode. Settings (about:preferences) and the PDF viewer work the same way, but Settings focuses its search box when it opens, so it starts in insert: press Esc before j/k. Pages Vimma does not reach (extension pages, data: and view-source: pages) stay in insert, so their keys are untouched. With focus in the URL bar or the find bar, keys belong to that field; only ctrl+b sequences are Vimma's there (and, in a / search, Enter and Esc).
**I goes to the address bar** from normal mode, copy mode and the side and bookmarks panels, on any page Vimma's keys reach (web pages, about: pages, Settings, the PDF viewer, the start page, a frame with focus): it selects the address as ctrl+l does, and the status bar says INSERT while you type there. In a split it is the focused pane's address. An open panel closes first, and copy mode ends. Esc is then Firefox's: the first closes the suggestions list if it shows, the next (with the address unchanged) puts focus back in the page, in normal mode. In insert mode I is a capital I typed into the field, as in Vim; press Esc first.
Text fields have Vim's editing keys. In insert mode, and in the URL bar, the : line, the find bar and the panels' filters, ctrl+w deletes the word before the caret, ctrl+u everything before it on the line, and ctrl+h one character, as Backspace. They are the text field's own delete commands, so ctrl+z undoes them. A page that handles one of these keys itself (a web terminal, an editor with its own ctrl+w) keeps it: Vimma edits only when the page left the key alone. In normal mode the keys stay Vimma's (ctrl+u scrolls, ctrl+w h moves between panes). [modal] insert_editing = false in config.toml turns them off; Firefox's own actions on those keys stay off either way. On macOS, ctrl+h is already a backspace in text fields, so Vimma adds nothing there.
**Esc in a text field is Vimma's.** It leaves insert, so the page does not see that Esc: a site's own Esc (closing an autocomplete list or a dialog) does not fire from the field. Press Esc again: in normal mode Esc has no binding, so it reaches the page (the field no longer has focus, so the page's document gets it, not the field).
A key that starts a sequence passes when nothing in that sequence works yet. ctrl+w starts the ctrl+w h/j/k/l, H/J/K/L, o and < > + - pane keys, which do something only with two panes or more, so in a window with one pane ctrl+w reaches the page (Firefox's own ctrl+w, close tab, is off: below). With a split, ctrl+w in normal mode waits for the pane key (Esc cancels); close the tab with x or ctrl+b shift+x. g starts gg, which works, so g is Vimma's: the page does not see it, and Esc cancels it.
Every default binding runs. Should a future binding land before its command, it is never silent once it is Vimma's: a ctrl+b sequence, or a count followed by a key (3H), whose command is not built yet shows "… not implemented yet" in the bottom-right corner for 1.5 s (not while a video or page is fullscreen); a single key whose command is not built yet reaches the page or Firefox, with no message; and the ctrl+b ? overlay dims it.
Status bar
The status bar is the window's last line, and it is always there, so you never lose track of where you are. It hides only while a page is in fullscreen, such as a video; browser fullscreen with F11 keeps it. From the left:
- the mode badge in the mode's colour:
NORMALon a page,INSERTwhile a text field has focus (or afteri),COMMANDwhile you type a:command or a/search,HELPwhile thectrl+b ?overlay or thectrl+b gpicker is open,HINTwhile link hints are up,VISUALin copy mode; - the pending keys, e.g.
prefixafterctrl+b; - the workspace:
● 2:work, its number in workspace order and its name; tab 2/5: the selected tab and how many the workspace shows;- the page title, or your rename (
ctrl+b shift+t); - on the right, the search in this page:
/word [2/5](match 2 of 5), or/zzz not foundin red; loadingwhile the page loads, then its URL withouthttps://.
On a narrow window the least important parts give way first: the URL is shortened in the middle, then dropped, then the title is shortened, and so on. The mode badge always stays. Screen readers announce the mode when it changes, including when focus moves into or out of a text field, but not every title change.
After ctrl+b (or any key that starts a longer sequence) only the pending keys show in the bar; no list of next keys pops up. To see the bindings, press ctrl+b ? (ctrl+b shift+? on a layout where ? is shifted): the overlay is the one place that lists them.
The command line
: in normal mode opens a Vim-style command line just above the status bar, for everything that is quicker to type than to bind. Type a command and press Enter; Esc closes it and puts focus back on the page. While it is open nothing you type reaches the page, and ctrl+b sequences still work.
- Completion. A list of matching commands and actions, with what each does, follows what you type.
Tabputs the next match on the line,shift+Tabthe previous; both wrap around. Matching also takes letters in order (scdfindsscroll_down). - History.
Up/Downwalk the lines you ran before, newest first. With text typed,Uprecalls only lines that start with it, as in Vim. History lasts until Vimma quits; a private window keeps its own, forgotten when it closes. :openand:tabnewrefusejavascript:anddata:URLs (also behindview-source:), with a message, aspdoes. The line does not open over a fullscreen page.- Errors show under the line, which stays open so you can fix it:
:tabnwesaysnot a command: "tabnwe"; did you mean :tabnew?. - A command name can be shortened while it stays unique (
:tabr,:wsp), and leading colons are fine (::q). When the shortened name starts several commands and one of them begins all the others, that one wins, as in Vim::woris:workspace(not:workspaces),:bo:bookmark.:wsnis:wsnext, as Vim's:wsn[ext]. - An argument is the rest of the line, as typed. Quotes are removed only when one pair wraps all of it:
:tabrename "my tab".
| Command | What it does |
|---|---|
:open text | Opens text in this tab as the URL bar would: example.com becomes a web address, other words a web search. |
:tabnew, :tabnew text | Opens a new tab; with text, opens it there (as :open). |
:q, :quit | Closes the pane, as ctrl+b x; with one pane the tab, as x: a pinned tab is kept and the next one selected. |
:map, :help, :h | Shows every binding (the ctrl+b ? overlay). |
:scroll_down, :tab.next… | Any action by its name in bindings.md, or by its dotted id. Actions take no argument. |
:tabrename [name] | Renames the tab; without a name, opens the rename prompt. |
:ls, :b | Opens the goto picker. |
:vsplit/:vs, :split/:sp | Splits the pane right / down, as ctrl+b v / ctrl+b -. |
:layout [name] | Arranges the panes in the named preset (Layouts); Tab completes the names. Without one, the next preset. |
:wsnext/:wn, :wsprev/:wp | Next / previous workspace, as ctrl+b ) / ctrl+b (. |
:workspace name, :ws 2, :ws # | Switches to the workspace with that name, that number in workspace order, or the previous one (ctrl+^). Tab completes names. |
:workspace, :ws, :workspaces | Opens the workspace picker. |
:wa name, :wd [name] | :wsnew, :wsdelete (Workspaces as Vim buffers). |
:sidebar | Opens or closes the side panel, as ctrl+b b. |
:route, :route add, :route move | Workspace routing rules: list them, add one for this site, move this tab (Routing). |
:bookmarks | Opens or closes the bookmarks panel, as ctrl+b shift+b. |
:bookmark [path] | Bookmarks the page under path (work/docs/title); without one, opens the prompt, as ctrl+b a. |
:source | Reads config.toml now instead of within 2 seconds (see config.toml). |
:source path | Loads that TOML file instead of config.toml until config.toml changes or a plain :source. |
:config | Opens config.toml in a new tab (read-only view); creates it from a commented template when it is missing. |
:about, :vimma | Opens about:vimma in a new tab. |
:addons | Opens the add-on picker, as ctrl+b e. |
:addon name | Opens that add-on's popup; Tab completes the name (Add-ons). |
:bug | Opens about:vimma and copies its redacted report to the clipboard, for a bug report. |
A command that is not built yet says so for a moment, as its keys do.
Known limits
Vimma is pre-alpha. What does not work yet, or works with a catch, is listed on the known limits page:
The guide at the top is written for this site; the details are built from Vimma's docs/guide.md and bindings.md at 1050bcc (2026-10-10).