~/vimma $ less docs/routing.md

page 2/5 · docs/routing

Routing links to workspaces

Routing puts each link where it belongs without you thinking about it. Send GitHub to your work workspace, or every link Slack opens, and it arrives there with that workspace's logins, wherever you clicked it.

Write your first rule

  1. Go to a site that belongs in a workspace, such as github.com.
  2. Type :route add work and press Enter. Vimma appends a rule for the site to config.toml.
  3. From now on, an address you type, a bookmark or a link from another app on that site opens in work.

Or write the rules yourself in config.toml. The first rule that matches, top to bottom, wins:

schema = 2

[[routes]]
domain = "github.com"   # the site and its subdomains
workspace = "work"

[[routes]]
app = "slack"           # every link Slack opens
workspace = "work"

Commands

ToType
See every rule, and which one matches this tab:route
Send this site to this workspace, or to work:route add, :route add work
Move this tab to the workspace its rule names:route move

Good to know

  • Rules apply to what you open: an address you type, :open, a bookmark, a link from another app. A link a page opens stays in that page's workspace, so no site can open another with your other logins; the status bar names the workspace its rule would choose, and :route move takes it there.
  • Routing by app works through vimma-open, which Vimma's packages set up as the browser's command. A link from an app Vimma cannot name (a Flatpak, say) follows the domain and url rules only.
  • Private windows are never routed.

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.

[[routes]] rules in config.toml send a site, or every link an app opens, to a workspace (and its container), as Zen's Space Routing does. Each rule names a workspace and what it matches; the first rule that matches, top to bottom, wins.

schema = 2

[[routes]]
domain = "github.com"         # github.com and its subdomains (gist.github.com), any port
workspace = "work"

[[routes]]
domain = "*.corp.example"     # only subdomains: jira.corp.example, not corp.example
workspace = "work"

[[routes]]
app = "slack"                 # every link Slack opens
workspace = "work"

[[routes]]
app = "discord"
domain = "youtube.com"        # both must match: YouTube links from Discord
workspace = "personal"

[[routes]]
url = "file:///home/me/notes/"  # a URL prefix: the way to route file:, about: and the like
workspace = "notes"
  • **domain** matches http and https pages only, on whole labels (github.com is not notgithub.com), whatever the port; Unicode names work written either way (bücher.example or xn--bcher-kva.example), and an IP address matches only itself.
  • **app** is the name of the program that opened the link, as vimma-open sees it (below).
  • Order is the precedence. Put the rule that matters most first: with app = "slack" above domain = "youtube.com", a YouTube link from Slack goes to work.
  • A rule naming a workspace that does not exist is skipped (:route says so).

Where rules apply: an address you type in the URL bar or with :open / :tabnew, a bookmark, a link from another app and a new window opened on a URL: what you or Vimma open. A link a page opens (a click, middle-click, F hints, target=_blank, a pop-up) stays in that page's workspace, because a page could otherwise open any site with another workspace's logins; when you look at such a tab, the status bar names the workspace its rule would choose and :route move moves it. Opened in front, the tab takes you to its workspace; opened in the background, it waits there and the status bar says opened in "work". If you typed the address on an empty new tab, that tab is closed.

Where they do not: a page that navigates in its own tab (a click, a redirect, a sign-in bounce) is never moved, because moving reopens the page and would break the load. The status bar says github.com goes to "work" (route 1): :route move instead; :route move moves the tab there (it loses its back/forward history, as any move does). A container you chose yourself ("Open Link in New Container Tab") is kept. Private windows are never routed.

By application. Vimma's packages install vimma-open and make it the desktop entry's command, so when Slack, Discord, a terminal or Neovim opens a link, vimma-open looks up which program asked (through /proc, skipping xdg-open, gio and shells) and tells Vimma. A link you open from a shell counts as the terminal's. Apps in Flatpak (they go through the desktop portal), apps started through systemd (uwsm app) and links opened while the asking program has already exited have no app: only domain and url rules apply to them. To see what an app is called, run vimma-open https://example.com from it, or look at its process name (ps -o comm), lower-cased.

Commands.

CommandWhat it does
:routeOpens about:vimma's Routing section: every rule in force, and which one matches the tab you were on.
:route add, :route add workAdds a domain rule for this site (its host without www.) to the end of config.toml, for this or the named workspace.
:route moveMoves this tab to the workspace its rule names.

:route add refuses a site an earlier rule already routes (it names the rule), a config.toml that has errors, and a file without schema = 2. It only ever appends to the file.

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).

Keys on this site

Keyboard shortcuts for this website
j kscroll down, up
d uhalf a page down, up
gg Gtop, bottom
/search the docs, or filter the keys
] [next, previous docs page
g hgo home
g dgo to the docs
g kgo to keys
g igo to install
g ago to about
?this help; Esc closes it

In Vimma, ctrl+b ? lists every binding.