Skip to content

feat(tui): load custom tree-sitter languages from config and plugins - #56182

Open
tombusby wants to merge 1 commit into
anomalyco:devfrom
tombusby:custom-languages
Open

tombusby wants to merge 1 commit into
anomalyco:devfrom
tombusby:custom-languages

Conversation

@tombusby

@tombusby tombusby commented Oct 16, 2026 •

Copy link
Copy Markdown

Issue for this PR

No open issue. This is the feature requested in #18587, which was closed as stale.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

TUI languages are hardcoded in parsers-config.ts and util/filetype.ts, so each new language needs its own PR (#42902, #6406 and #17386 were all auto-closed), and in-house or niche languages can't be added at all. This lets users add tree-sitter languages themselves:

  • languages in cli.json (paths relative to the file) and context.languages.register() for TUI plugins.
  • Both feed util/languages.ts. It maps extensions for filetype(), then hands parsers to OpenTUI with
    addDefaultParsers, or addFiletypeParser when the worker is already running. cli.json wins over plugins.
    Removing an override of a built-in restores the built-in.
  • The language ID is also the Markdown fence name, because OpenTUI falls back to the raw info string.
  • filetype.ts gets the registry through a small setter, so @opencode/tui/mini/tool (used by run and ACP) does
    not start importing OpenTUI. Mini's toolFiletype now reuses filetype() instead of a copy of it.

How did you verify your code works?

  • New tests: registry precedence and fallback, source resolution, plugin registration and validation, config
    decoding, and a real highlight through the shared worker using OpenTUI's bundled zig grammar (no network).
  • Built tree-sitter-elm v5.9.4 to wasm and registered it with the nvim-treesitter Elm query. Elm files, diffs and
    ```elm fences are highlighted in bun dev, through both cli.json and a .opencode/plugins/elm plugin.
  • bun run check (lint and typecheck of every package) passes.

Screenshots / recordings

Screenshots to follow.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

🤖 Generated with Claude Code


Added by the opencode bot (AI-generated).

Public API: adds languages to cli.json and context.languages.register() / LanguageDefinition to the TUI plugin API (backwards compatible)

Languages were hardcoded in filetype.ts and parsers-config.ts. Add a
`languages` map to cli.json and `context.languages.register()` for TUI
plugins, both feeding one registry that maps extensions and registers
the grammar wasm and highlight queries with OpenTUI. cli.json overrides
plugins, and an override of a built-in falls back to it when removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. With a cli.json languages entry pointing at OpenTUI's bundled zig grammar, a fence using the custom ID is plain text on the base and highlighted with this PR (screenshots below). The new tests and the tui and plugin type checks pass. I also checked that OpenTUI's addFiletypeParser replaces an existing parser while the worker is running, so overriding a built-in works, and that toolFiletype behaves the same as before for run and ACP.

Public API (all additive, backwards compatible):

  • Plugin API: new context.languages.register(definition) => unregister and an exported LanguageDefinition type in @opencode/plugin/tui/context.
  • Config: new optional languages key in cli.json (record of { extensions?, wasm, highlights, injections? }).

No blocking concerns.

Before

After

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant