Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Plugins

mantis supports two kinds of plugins: process plugins (subprocess-based) and syntax plugins (syntax definitions loaded into the highlighter).

The bundled toml, css, ini, and sql process plugins provide folding for configuration sections, CSS-family rulesets, and SQL statements. TOML syntax highlighting remains available through the bundled toml-syntax syntax plugin.

Process plugins are standalone executables that hook into app events and issue actions back to the viewer. They run in separate processes; mantis talks to them over stdin/stdout using newline-delimited JSON, so a plugin can be any executable — a compiled binary, a Python script, or anything that can read stdin and write stdout.

Syntax plugins provide .sublime-syntax files that are loaded into the built-in syntect highlighter at startup. They add syntax highlighting for new file types without modifying the core binary.

Installing a plugin

Plugins live in the default plugin directory:

  • Linux / macOS: ~/.config/mantis/plugins/ (or $XDG_CONFIG_HOME/mantis/plugins/ if that variable is set)
  • Windows: %APPDATA%\mantis\plugins\

Process plugins

Drop the executable there and make it executable (chmod +x my-plugin.sh on Unix).

Syntax plugins

.sublime-syntax files placed in {plugin_dir}/syntaxes/ are auto-discovered at startup. They are installed automatically by mantis’s first-run setup.

Registering a plugin

Process plugins

Add a [plugins] section to your mantis.toml:

[plugins]
my-plugin = { path = "my-plugin.sh", enabled = true }
  • path — path to the executable. Relative paths are resolved against the default plugin directory above. Absolute paths are used as-is.
  • enabled — set to false to keep the entry without loading the plugin.

You can register as many plugins as you like:

[plugins]
git-stats   = { path = "git-stats.sh" }
file-logger = { path = "/usr/local/bin/mantis-file-logger" }
dev-tools   = { path = "dev-tools.py", enabled = false }

Syntax plugins

Syntax plugins can also be registered explicitly in mantis.toml with kind = "syntax":

[plugins]
terraform-syntax = { kind = "syntax", syntax_file = "syntaxes/terraform.sublime-syntax",
              extensions = ["tf", "tfvars"] }
toml-syntax = { kind = "syntax", syntax_file = "syntaxes/toml.sublime-syntax",
         extensions = ["toml"] }
typescript-syntax = { kind = "syntax", syntax_file = "syntaxes/typescript.sublime-syntax",
                      extensions = ["ts", "tsx", "mts", "cts", "jsx", "js", "mjs", "cjs"] }
dockerfile = { kind = "syntax", syntax_file = "syntaxes/dockerfile.sublime-syntax",
               extensions = ["dockerfile"] }
nginx = { kind = "syntax", syntax_file = "syntaxes/nginx.sublime-syntax" }
justfile = { kind = "syntax", syntax_file = "syntaxes/justfile.sublime-syntax" }
  • kind — "syntax" for syntax-definition plugins (default: "process").
  • syntax_file — path to the .sublime-syntax file. Relative paths are resolved against the plugin directory.
  • extensions — file extensions this syntax should match (optional; the syntax definition itself also declares its own extensions).

Syntax plugins are not spawned as subprocesses. Their syntax definitions are loaded into the highlighter alongside the built-in language set.

What plugins can do

Plugins receive lifecycle and hook events from mantis and can respond with actions:

| Action | Effect | |—|—|—| | show_message | Displays a message in the status bar | | open_file | Opens a file in the content panel | | set_content | Replaces content panel with ANSI-escaped lines | | set_content_chunk / set_content_end | Streams a large rendered document into the content panel | | set_icon_map | Sets file-type icon glyphs (requires Nerd Font) | | register_language_provider | Declares file extensions and capabilities | | set_fold_regions | Provides fold regions for a file | | set_status_facts | Provides a short status-bar summary for a file | | set_symbols | Provides a file’s outline symbols for navigation | | register_commands | Adds commands to the Ctrl-P command palette and Plugins menu | | register_context_items | Contributes items to context menus (tree, content, tabs, blame) | | register_status_segments | Contributes persistent segments to the status bar |

Each action has specific parameters; see Plugin Development for the full protocol reference. Plugin commands also appear under the Plugins dropdown in the menu bar.

Protocol version

mantis and plugins communicate over an IPC protocol identified by a version string. Each plugin declares its protocol version in plugin.toml via the tv_protocol field. At startup mantis validates that every discovered plugin matches the host protocol version — plugins with a mismatched version are silently skipped. The init event sent to each plugin includes the host protocol version so the plugin can verify compatibility dynamically.

Current protocol version: "3". Chunked content actions are an additive protocol-3 feature and do not require another version bump.

Plugins must declare mantis_protocol = "3" (or the legacy tv_protocol alias) to be discovered by the current host.

Lifecycle

  1. mantis starts, reads [plugins] from config, and spawns each enabled plugin.
  2. Each plugin receives an init event (with the active theme name and host protocol version).
  3. As you use mantis, plugins receive hook events (on_file_open,
  4. When you quit, each plugin receives on_quit then shutdown, and mantis waits for each subprocess to exit.

Plugin stderr is discarded (/dev/null). Write debug output to a log file instead.

Example: status-bar clock

A minimal shell plugin that shows the current time in the status bar on every file open:

#!/usr/bin/env bash
# ~/.config/mantis/plugins/clock.sh

while IFS= read -r line; do
    event=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin).get('event',''))")
    case "$event" in
        on_file_open|init)
            ts=$(date +"%H:%M:%S")
            printf '{"event":"action","action":"show_message","params":{"message":"%s"}}\n' "$ts"
            ;;
        shutdown) exit 0 ;;
    esac
done

Register it:

[plugins]
clock = { path = "clock.sh" }

Bundled plugins

mantis ships with several bundled Rust plugins. Each is a workspace member compiled alongside mantis and installed on first run.

PluginBinaryWhat it does
iconizeiconizeOn init, sends a set_icon_map action with Nerd Font glyphs for ~80 file extensions. Requires icons = true in mantis.toml and a Nerd Font terminal.
markdownmarkdownRenders .md files using pulldown-cmark, streaming ANSI-escaped lines into the content panel. Responds to theme changes and M keypress for raw/rendered toggle.
pythonpythonRegisters as a language provider for .py files with the fold capability. On file open, computes and registers collapsible indentation-based fold regions.
rustrustRegisters as a language provider for .rs files with fold and symbols capabilities. On file open, provides curly-brace folds and a symbol outline for functions, types, modules, and methods.
gogoRegisters as a language provider for .go files with the fold capability. On file open, computes and registers collapsible curly-brace fold regions.
jsonjsonRegisters as a language provider for .json files with the fold capability. On file open, computes fold regions for multi-line objects and arrays in the displayed JSON.
shshRegisters as a language provider for .sh, .bash, and .zsh files with the fold capability. On file open, computes fold regions for function bodies and compound blocks, aware of # comments, quoted strings, and heredocs.
yamlyamlRegisters as a language provider for .yaml/.yml files with the fold capability. On file open, computes and registers collapsible indentation-based fold regions. When enabled, its regions take precedence over the built-in YAML folding.
k8sk8sRegisters as a language provider for .yaml/.yml files with the status_facts capability — coexists with the yaml plugin’s fold registration on the same extensions since they declare different capabilities. On file open, reports the first Kubernetes resource’s identity (Kind/name (namespace)) plus per-kind counts across ----separated documents; after the debounced on_content_cursor_change event, it reports the resource containing the cursor. Files without both apiVersion and kind show no facts.
terraformterraformRegisters as a language provider for .tf, .tfvars, and .hcl files with the fold capability. Folds HCL blocks using the shared Terraform detector.
tomltomlRegisters as a language provider for .toml files with the fold capability. Folds TOML tables ([table]) and arrays of tables ([[table]]) through the next section or end of file.
csscssRegisters as a language provider for .css, .scss, and .less files with the fold capability. Folds nested rulesets, media queries, and keyframes while ignoring comments and quoted strings.
typescripttypescriptRegisters as a language provider for TypeScript, TSX, JavaScript, and JSX extensions with the fold capability. Disabled by default because the existing syntax pack owns these extensions; enable it explicitly to add folding.
templatetemplateRegisters as a language provider for Go-template, Helm, and Jinja2 extensions with the fold capability.
iniiniRegisters as a language provider for .ini, .service, .timer, .conf, .properties, .cfg, and .desktop files. Folds sections through their last meaningful line.
sqlsqlRegisters as a language provider for .sql files. Folds multiline statements and common BEGIN, CASE, IF, and LOOP blocks while ignoring comments and quoted strings.

Bundled syntax plugins

mantis also bundles syntax-only plugins that provide highlighting for additional file types without spawning a subprocess.

PluginExtensionsWhat it highlights
terraform-syntax.tf, .tfvarsHashiCorp Configuration Language (HCL) used by Terraform
toml-syntax.tomlTOML configuration files (Cargo.toml, mantis.toml, pyproject.toml, etc.)
typescript-syntax.ts, .tsx, .mts, .cts, .jsx, .js, .mjs, .cjsTypeScript, TSX, JavaScript, and JSX source files
template-syntax.tpl, .tmpl, .template, .j2, .jinja, .jinja2Go-template, Helm, and Jinja2 templates
dockerfileDockerfile, ContainerfileDockerfile instructions (matched by filename, no extension)
nginxnginx.confNginx server configuration (matched by filename, no extension claim)
justfilejustfileJust (justfile) task recipes (matched by filename, no extension)

All bundled plugins are compiled as workspace members and installed to the plugin directory the first time mantis creates its global config. They are enabled by default, except the TypeScript/JavaScript folding provider, which is opt-in to avoid changing existing syntax-plugin behavior. Set enabled = false or enabled = true explicitly in your mantis.toml as needed:

[plugins.rust]
enabled = false

Note: Git features are built into mantis natively — no plugin required. Git status colors, blame, file history (H, while the tree is focused), and working-tree diffs all work without any plugin enabled.

Auto-removal of retired plugins

When upgrading from a pre-0.8 install (which used shell-script plugins), superseded files (git-diff.sh, git-log.sh, iconize.sh) and their [plugins] config entries are silently removed on first launch. User-authored plugins are never touched.