crabcode

Editor

Configure one file opener for paths, image placeholders, and binary links, with ordered filename overrides.

Open files from the TUI

editor controls all file-opening actions: clicked paths and line numbers, "open in editor" actions, image placeholders such as [Image #1], and binary-file links. They all use the same opener selection; images and binaries do not have a separate opening setting.

With no editor configuration, crabcode uses the detected Zed, VS Code, or Cursor integrated editor, preserving line and column jumps. If no integrated editor is detected, it opens the file in the system's default application. Standalone terminals such as WezTerm and Ghostty use that system default.

Configuration

A command string is shorthand for an object with open set to that command and suspend set to false:

crabcode.jsonc
{
  "editor": "my-file-opener {location}",
}

Use an object to control suspension or route selected filenames to another opener:

crabcode.jsonc
{
  "editor": {
    "open": "my-file-opener {location}",
    "suspend": false,
    "overrides": {
      "*.md": "my-markdown-preview {pathname}",
      "*.pdf": {
        "open": "my-pdf-viewer {pathname}",
        "suspend": false,
      },
    },
  },
}
FieldTypeBehavior
editorCommand string or objectA string is shorthand for { "open": "..." }.
editor.openCommand string or "system"Default opener for every file not matched by an override. "system" selects the OS default application.
editor.suspendBooleanDefaults to false; suspend the TUI while the selected default opener runs.
editor.overridesOrdered objectMap basename glob patterns to opener strings or objects with open and optional suspend. The first match wins.

To always use the OS default application, set editor.open to "system". This invokes open on macOS, xdg-open on Linux, or start on Windows rather than treating system as a shell command.

An explicit command is authoritative. If it fails, crabcode reports the error; it does not fall back to another editor, a system application, or copying the path.

Filename overrides

Overrides match the file's basename, not its full directory path, and matching is case-insensitive. For example, *.pdf matches both report.pdf and REPORT.PDF, regardless of their directory. Brace groups are supported: *.{md,mdx} matches either extension.

Rules are checked in object order. Put specific patterns before broader ones; the first matching override wins, with no merging of matching rules. If none matches, crabcode uses editor.open for the file, including images and binaries.

Each override is either an opener string or an object with open and optional suspend. Its suspend defaults to false independently of editor.suspend:

crabcode.jsonc
{
  "editor": {
    "open": "my-terminal-editor {location}",
    "suspend": true,
    "overrides": {
      "README.md": "my-markdown-preview {pathname}",
      "*.pdf": "system",
      "*.md": {
        "open": "my-other-terminal-editor {location}",
        "suspend": true,
      },
    },
  },
}

Here, README.md uses the preview command rather than the broader *.md rule. The preview and system PDF opener do not suspend crabcode, even though the default opener does.

Command templates and placeholders

Command templates are generic shell commands, not an editor-specific API. Both the default opener and override commands are expanded, then passed to sh -c (or cmd /C on Windows). Use any executable or script that accepts the file arguments you need.

TokenValue
{pathname}, {path}, {filename}Shell-quoted file path
{pathname_raw}, {path_raw}Unquoted file path
{line}Line number, 1 if unknown
{column}, {col}Column number, 1 if unknown
{location}Shell-quoted path:line:column

{pathname} is quoted so paths with spaces stay one argument when concatenated as {pathname}:{line}:{column}. Use {pathname_raw} when the path sits inside quotes you already wrote.

If the template has no path token, crabcode appends the quoted path. The reserved "system" opener needs no placeholders.

Suspend

suspend: true leaves the TUI, runs the selected opener with the real terminal, waits for it to exit, then restores crabcode. Use it for an editor running directly in the same terminal.

Leave suspension off for GUI applications and commands that launch editors in another multiplexer tab or terminal window. Set it explicitly on any override that needs the real terminal; overrides do not inherit the default opener's suspension setting.

For practical Helix, Neovim, Herdr, tmux, Zellij, WezTerm, Ghostty, Zed, VS Code, and Cursor recipes, see Editor Integration.