Skip to content
BetaPrivate beta - free access.Join the waitlist
Pyvoid
Article· Updated April 26, 2026·9 min read

The Revit Ribbon Is Just One Surface. We Built Five.

How a command palette, dockable Studios, in-app docs, cross-linked modals, and global keybindings turn the Revit ribbon into a real workspace inside Pyvoid.

By Tyler Putnam|
opinionpyvoidproductivitycommand-hub

Most Revit add-ins are a folder of macros bolted onto a ribbon. You click a button, a window opens, you finish a task, the window closes. To do the next thing, you find the next button, in the next panel, on the next tab. Every tool is a stranger to every other tool.

Pyvoid runs on five surfaces, not one. The ribbon is still there for muscle memory. But a palette for fuzzy invocation, dockable Studios for ambient state, cross-linked modals for focused tasks, global keybindings for keyboard hands, and in-app docs for the moments you forget. Those five surfaces are what change how the product feels. This article walks through the design decisions behind each. For the broader landscape - what Pyvoid extensions are, the categories of tools, and how to evaluate one - see Pyvoid Extensions: The Complete Guide.

A Ribbon Is a Storefront, Not a Workspace

Pyvoid is a native C# Revit add-in that runs on five UI surfaces - ribbon, command palette, dockable Studios, cross-linked modals, and global keybindings - so a 200+ command suite stays navigable for BIM Managers without ribbon-hunting. The ribbon is good at one thing: showing you what exists. It is bad at almost everything else. It assumes a sequential flow - open, do, close, repeat - and treats every tool as a self-contained transaction. For a 200+ command suite, that pattern collapses on itself.

We tested two assumptions when we started designing Pyvoid:

  1. Modern software solved this problem. Raycast, Linear, VS Code, and the JetBrains family converged on the same answer: a global command palette, persistent side panes, keyboard shortcuts, and contextual help. The ribbon, where it survives, is one surface among several.
  2. The Revit user already runs other software that works this way. They press one hotkey to fuzzy-find anything. They expect a pane to stay open while they work. They expect a tool to link to its own documentation.

So we built five surfaces and gave the ribbon the smallest job: be the storefront. Show the user what exists, then hand them off to the surface that fits the task. Linear's design team writes that opinionated software "guides you toward a default process" instead of leaving you to assemble one. That framing is the difference between a folder of macros and a designed product.

The five patterns below are how that plays out in code.

Tools That Hand Off to Other Tools

In a typical Revit add-in, every modal is a dead end. You finish, you close it, and if your next step lives in another tool, you go back to the ribbon and start over. Pyvoid's modals know about each other.

The clearest example lives in Warning Center. When a triaged warning needs a different classification, the Warning Center modal opens the Suggest Classification window. That window is owned by a sibling tool, warning_visualizer, but it instantiates directly inside the parent context. When you finish over there, control returns to Warning Center, which re-runs analysis with the new data. The modal does not dead-end. It composes.

# Pyvoid.extension/lib/pyvoid/tools/warning_center/window.py
def _open_suggest_classifications(self):
    win = SuggestClassificationWindow(...)
    if win.ShowDialog() == True:
        self._reanalyze()

The cross-link goes deeper than tool-to-tool launches. Every WPF window in Pyvoid that inherits MetroWindowBase (121 of them as of writing) intercepts hyperlink clicks. Any link with a pyvoid://guide/{panel}/{tool} URI gets routed into the CommandHub Companion at the right anchor, not opened in a browser, not dropped into the ether. A help link inside Tool A opens Tool B's documentation in a pane next to Tool A.

This is what cross-linked modals get you: a network of tools that compose, not a directory of independent islands. Closing one window is no longer the end of a session. It is one hop in a chain that the product itself remembers.

Docs That Ship With the Code

Most Revit add-in documentation lives on a wiki, a PDF, or a "?" button that opens a browser. That is one click and one context switch away from where the user is. In practice, it is the click that does not happen. They guess instead.

Pyvoid's help system is a single line in every window class:

help_url = "pyvoid://guide/warnings/warning_center"

When the user clicks the "?" in any tool's chrome, the URI is resolved by DeepLinkResolver into a panel-and-anchor pair. The CommandHub Companion opens a WebView2-rendered guide right next to the tool. Same monitor, same window manager, same focus. The docs are not a separate site. They ship from the same repo as the code, render from the same manifest, and gate on coverage at release.

The coverage number matters here. As of the most recent CommandHub closure phase, help coverage sits at 100% across every tool that registers. That number is enforced by the build, not promised by a marketing page. A tool without a help_url does not pass.

The reason matters. Documentation is only useful if the user reaches it. The traditional wiki model assumes the user will go look. The in-app model assumes they will not, and brings the answer to where the question happens. The cost is that we own the docs forever. They live in the same repo, fail the same builds, and ship on the same release cadence as the code. The benefit is that they do not rot. A tool whose UI changes ships its docs in the same commit.

A Command Palette That Knows Your Shortcuts

Every modern editor has a command palette. Raycast built a billion-dollar company on the premise that one global hotkey to fuzzy-find any action was worth more than a thousand menus. VS Code's palette is the reason most of its features are discoverable at all.

Revit has had Search-the-Ribbon since 2017. It is not a command palette. It is a tooltip that points you at a button you still have to click.

CommandHub is Pyvoid's answer. One global hotkey (Ctrl+Shift+P, aliased to Ctrl+Shift+Space) opens a palette that fuzzy-finds across every Pyvoid tool, every keybinding, every help page. The matcher is a tiered cascade: exact match scores 1000, starts-with scores 500, acronym match scores 400, word-boundary 300, fuzzy 200, contains 100. Field multipliers stack on top. Name is 3x, shortcut is 2.5x, aliases are 2x. There is a frecency boost. The result is that typing wc lands on Warning Center on the first keystroke, and typing the keybind itself searches by keybind.

Keybindings are part of the same surface. Pyvoid ships a YAML catalog of keyboard shortcuts in two tiers. Tier 1 uses Ctrl+Shift+{key} for cross-cutting tools. Tier 2 uses panel-prefixed two-letter chords like BH or WC, modeled on Revit's native WA and VV. The shortcuts surface in CommandHub's search field with a 2.5x multiplier, on every tool's tooltip via ToolbarMixin, and in Revit's keyboard shortcut dialog where the actual binding lives.

The palette and the keybindings are the same product surface, not two. The palette teaches the keybindings. The keybindings let the user skip the palette. That is the loop.

Studios That Stay Open

A modal is a tax. It steals focus, blocks the document, and demands a verdict before it lets you go. For a few tasks - confirming a destructive action, filling a one-shot form - that tax is appropriate. For most tasks, it is not.

Modern editors solved this with persistent side panels. The file tree, the search results, the diagnostics pane - they stay open. They update as you work. They cost zero context switches because they never go away.

In Revit, the equivalent is a dockable pane: a window registered with IDockablePaneProvider that survives view changes, keeps its state, and lives where the user puts it. SelectionHub already ships this way. It owns a stable GUID, registers as a dockable pane, and stays where you docked it across sessions.

We are extending the same pattern across the product. A StudioPaneBase class in Pyvoid.Engine is the framework. Five upcoming Studios inherit it:

A StudioRegistry maps each tool to its Studio via a studio: flag in bundle.yaml. The PRDs are written, the framework code is in, and the panel implementations are next.

Not every tool gets this treatment. SheetForge stays ribbon-based. It is a destination workflow with its own UI, not an ambient activity. The choice is deliberate. A Studio is for things you watch while you work. A ribbon button is for things you do once and leave.

What This Costs

There are three reasonable objections to all of this.

"BIM users want familiar Revit-style ribbons." Some of them do. We did not remove the ribbon. Every Studio tool, every CommandHub action, every Studio pane is also a ribbon entry. The new surfaces are additive. A user who never opens CommandHub still gets the full product. The user who lives in CommandHub gets a faster one. The opt-in cost is zero.

"More surfaces means more cognitive load." This was the argument we worried about most. The bet is that one global palette plus a few persistent panes replaces dozens of ribbon hunts and tab switches. The data on knowledge worker context-switching is unkind to the alternative. Microsoft's Work Trend Index puts the average at 275 interruptions per day. Asana's research clocks roughly 1,200 app and website toggles per digital worker per day. Adding a unifying surface that subsumes the others is not the same as adding a new island. For a starting set that exercises every surface, see the ten Pyvoid tools to learn first.

"In-app docs go stale faster." In our experience the opposite is true, because they ship with the code that they document. The 100% coverage gate is enforced by the build. A tool that changes its UI without updating its help fails to release. A wiki has no such constraint.

The dual-home rule

Every new surface in Pyvoid - palette, Studio, keybinding - is additive to the ribbon, never a replacement. The ribbon user gets the same product as the palette user. The opt-in cost is zero, which is the only honest way to ship new UX into a tool people already know.

Frequently Asked Questions

How do I open Pyvoid's command palette?

Press Ctrl+Shift+P (or the Ctrl+Shift+Space alias) anywhere inside Revit. The palette opens with fuzzy-find across every Pyvoid tool, every keybinding, and every help page. Type three letters and press Enter to invoke.

Will Pyvoid replace the Revit ribbon?

Pyvoid does not replace the Revit ribbon. The ribbon stays for muscle memory and discoverability. Every Studio tool, CommandHub action, and Studio pane is also a ribbon entry. The new surfaces are additive - a user who never opens CommandHub still gets the full product.

What's the difference between a Studio and a ribbon button in Pyvoid?

A Studio is a dockable pane that stays open while you work, keeps its state, and lives where you put it. A ribbon button opens a modal that demands a verdict before letting you go. Studios are for ambient activities you watch. Ribbon buttons are for destination workflows you do once.

How does Pyvoid handle in-app documentation?

Every tool's window class declares a help_url. When the user clicks "?" in the tool chrome, the URI resolves into a panel-and-anchor pair, and the CommandHub Companion opens a WebView2-rendered guide next to the tool. Coverage is 100% across registered tools, enforced by the build.

What keybinding pattern does Pyvoid use?

Two tiers. Tier 1 is Ctrl+Shift+{key} for cross-cutting tools (Ctrl+Shift+P for the palette, Ctrl+Shift+H for ReViewer). Tier 2 is panel-prefixed two-letter chords like BH or WC, modeled on Revit's native WA and VV.

One Decision, Five Surfaces

The five surfaces are not five separate ideas. They are one decision applied five ways: the ribbon is not the product. The product is the network of palettes, panes, modals, hotkeys, and docs that the ribbon links into. Build that network well and the ribbon becomes a storefront, a place to discover, not a place to live.

That is the only design philosophy worth having for a 200-tool extension. Everything else is just buttons.

The Revit Ribbon Is Just One Surface. We Built Five. | Pyvoid