Contact
Draftv0.5.0 · beta

Settings & customization

settings.json, keybindings.json, the settings surface, themes, and the plugin API — all built on the rule that bindings, aliases, layout and themes are data rather than code.

Bindings, aliases, ribbon layout and themes are data, not code. That is a deliberate architectural commitment, and it is what makes a workspace profile a config file rather than a code change — and what lets the classic sysvar names stay alive as command-line aliases over modern named settings without polluting the engine.

The command registry#

Every executable action has a unique string id, in the form drafting.command.move. This is the spine of the whole customization story:

  • a keybinding maps an input to a command id;
  • the ribbon and the menu are generated from the registry;
  • a tool palette holds command ids;
  • a plugin contributes command ids;
  • anything driving Draft programmatically dispatches command ids.

An action with no id can be neither typed, nor rebound, nor driven. The drafting toggles are therefore commands in their own right — GRID, SNAP, ORTHO, POLAR, OSNAP, LWDISPLAY and AXES, each taking ON/OFF or toggling on Enter — and the status bar and the F-keys both route through them rather than writing the store directly.

The two files#

FileHolds
settings.jsonNamed variables — the modern form of the sysvars
keybindings.jsonInput → command id

Both live in the OS configuration directory. SETTINGSRELOAD re-reads them and tells you where they are.

Only the keys you specify are overridden. Your file is merged over the shipped defaults rather than replacing them, and the merge is deep — turning one object snap type off does not silently turn the others off with it. This is what lets a default changed in a later build reach somebody who has already opened Draft.

The same principle shows up in how the ribbon stores customization: it records what is hidden, not what is shown, so a command added in a later build appears for everyone rather than only for new users.

The settings surface#

SETTINGS opens a grouped, searchable surface over those variables, in four groups: Drafting, Drawing, Interface and 3D. It is reachable from the command line, from File ▸ Settings ▸ All Settings, and from the status bar's gear.

Two design rules are worth knowing:

Every control writes the same store the owning command writes. There are not two implementations of one concern that can disagree — no DDOSNAP versus -OSNAP split. Each row names the command that owns it beside the label, so the relationship is visible rather than asserted.

Changes apply immediately, and there is no Cancel. The drawing behind the panel already shows the change. A Cancel would have to snapshot and restore several dozen fields, and silently reverting a change a drafter has already watched take effect is worse than not offering one. The way back is the same control, or the command. Undo is the drawing's stack and does not cover settings.

Classic sysvar names still work. Typing PDMODE finds the point style; typing LTSCALE finds the linetype scale. The name survives as an alias over a documented, named setting — you never have to learn a numeric code to change a point style.

Five things are tables rather than fields — keybindings, hidden ribbon tools, workspaces, tool palettes, and the alias list — and a table needs an editor rather than a control. They appear as buttons under Customise that close the panel and run their command.

Keybindings#

keybindings.json maps an input to a command id, with an optional when clause. The when clause is what lets one key mean two things:

{
  "key": "Delete",
  "command": "drafting.command.erase",
  "when": "selection && !commandActive && !typing"
}

That binding erases the selection — and still deletes a character when you are typing in the command line.

Remember that bare printable keys are never bound: they go to the command line, where L matches LINE's alias. The keys a binding can own are modifier chords, function keys, Esc, Delete, and the mouse.

Themes#

A theme is data. It defines the canvas, chrome, grid, axis, selection, grip, snap-marker and accent colours, and everything on the canvas resolves its appearance through it. The shipped set covers dark and light.

The one theme-related rule with consequences on paper is ByBackground — see Layers, blocks & references.

Plugins#

Deferred Plugin API past 1.0

Deferred past 1.0 by decision. The manifest, lifecycle and sandbox are specified and those specifications stand; there is no plugin host in the product.

Read the contract below as what a plugin will be written against.

  • Manifest. Each plugin declares its metadata plus the command ids and default keybindings it contributes, readable before its code runs. What a plugin adds is knowable without executing it.
  • Lifecycle. activate(context) and deactivate().
  • Registration. During activation, the plugin binds callbacks to its declared ids.
  • Sandboxed API. Plugins receive a context object exposing public APIs, not raw access to engine internals.
  • Namespacing. Ids are namespaced by publisher and plugin, so a third party cannot shadow a core command or another plugin's.
  • Crash isolation. An unhandled exception in a plugin command is caught, the application survives, and the user is told which plugin failed.
  • Teardown. Disabling a plugin runs deactivate() and sweeps its commands and keybindings out of the registry.
  • Startup. Plugin loading must not delay startup or block the canvas.

A tool palette that holds a plugin's command keeps the entry when the plugin is disabled, and the tool comes back when the plugin does — a disabled plugin must not silently edit somebody's palette.