Skip to content

feat: gate language grammars behind SwiftPM package traits#7

Merged
gtokman merged 2 commits into
mainfrom
feat/package-traits-per-language
Jun 20, 2026
Merged

feat: gate language grammars behind SwiftPM package traits#7
gtokman merged 2 commits into
mainfrom
feat/package-traits-per-language

Conversation

@gtokman

@gtokman gtokman commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

What

Makes each tree-sitter language grammar an opt-in SwiftPM package trait instead of an unconditional dependency. Consumers who only render a handful of languages can disable the rest, pruning those grammar packages from resolution and compilation entirely.

Implements the approach from Swift package traits (SE-0450).

Why

Today every consumer of MarkdownView fetches, compiles, and links all 18 tree-sitter grammar packages even if they only ever highlight, say, Swift and JSON. Traits let consumers pay only for the languages they use.

Changes

Package.swift

  • Bump swift-tools-version to 6.1 (required for traits).
  • Add 18 traits — one per grammar package — with a .default set enabling all of them, so existing consumers are unaffected.
  • Gate each tree-sitter .product(...) with condition: .when(traits: [...]).
  • Pin swiftLanguageModes: [.v5] so the tools-version bump doesn't also migrate the package into the Swift 6 language mode (which would turn pre-existing Litext concurrency warnings into hard errors — out of scope here).

CodeHighlighter.swift

  • Wrap each import TreeSitterX and its register(...) block in #if <Trait>. Disabled languages are simply never registered; the existing languageConfiguration(for:) nil path already degrades unknown languages to plain text, so no call sites change.

Consumer usage

// Full set — unchanged behavior:
.package(url: "...", from: "x.y.z")

// Only what you need — the rest is never fetched or compiled:
.package(url: "...", from: "x.y.z", traits: ["Swift", "JSON"])

Reviewer notes

  • TreeSitterTSX is not a separate product — it ships inside the TreeSitterTypeScript product, so TypeScript + TSX share one TypeScript trait.
  • Traits are SwiftPM-only. A consumer adding the package via Xcode's GUI always gets the default (all-languages) set — there is no per-language toggle in the IDE.
  • Breaking-ish: minimum build toolchain rises from Swift 5.9 → 6.1.

Verification

  • Default build (all languages): Build complete ✓, full test suite passes ✓
  • swift build --disable-default-traits --traits Swift,JSON: Build complete ✓, and show-dependencies confirms only tree-sitter-swift + tree-sitter-json remain — the other 16 grammar packages are pruned from the graph.

🤖 Generated with Claude Code

Each tree-sitter grammar is now an opt-in package trait instead of an
unconditional dependency. Consumers who only render a few languages can
disable the rest, pruning those grammar packages from resolution and
compilation entirely.

- Bump swift-tools-version to 6.1 (required for traits).
- Add 18 traits (one per grammar package) with a default set enabling all
  of them, so existing consumers see no change.
- Gate each tree-sitter product with `condition: .when(traits: [...])` and
  wrap the matching imports/registrations in CodeHighlighter with `#if`.
  Unregistered languages fall through to plain text via the existing
  `languageConfiguration(for:)` nil path.
- Pin `swiftLanguageModes: [.v5]` so the tools bump doesn't also flip the
  package into the Swift 6 language mode.

Verified: default build + full test suite pass; a `--traits Swift,JSON`
build succeeds and prunes the other 16 grammar packages from the graph.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
markdown-view Ready Ready Preview, Comment, Open in v0 Jun 20, 2026 10:04pm

Request Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed41be8376

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Package.swift
@@ -1,4 +1,4 @@
// swift-tools-version: 5.9
// swift-tools-version: 6.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update the advertised Swift requirement

Because this tools-version line makes SwiftPM 6.1 the minimum, the README Requirements section still saying Swift 5.9+ is now wrong; users on Swift 5.9 or 5.10 following the published install docs will fail while loading the manifest before they can build. Update the documented minimum/toolchain compatibility along with this manifest change.

Useful? React with 👍 / 👎.

The package now requires Swift tools 6.1 (for traits); the README still
advertised 5.9+, which would fail at manifest load for users on 5.9/5.10.
Also document how to select languages via package traits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gtokman gtokman merged commit c4f1b7d into main Jun 20, 2026
6 checks passed
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