Skip to content

feat(web-ui): highlight Cangjie sources in the editor and chat - #3441

Merged
GCWing merged 5 commits into
GCWing:mainfrom
EthanCheung-gh:openbitfun/cangjie-syntax-highlighting
Oct 18, 2026
Merged

GCWing merged 5 commits into
GCWing:mainfrom
EthanCheung-gh:openbitfun/cangjie-syntax-highlighting

Conversation

@EthanCheung-gh

@EthanCheung-gh EthanCheung-gh commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add a Cangjie (.cj) language definition to the code editor: a Monarch tokenizer derived from the TextMate grammar shipped with the CodeArts Agent Cangjie extension (source.cj), because Monaco's standalone build cannot load TextMate grammars without an Oniguruma runtime.
  • Register the language end to end: Monaco registration, language detection for .cj, status bar name, language picker entry, code icon, drop-preview kind and code-snippet label.
  • Highlight cangjie fences in chat by registering a Prism grammar on the async highlighter, and label the fence "Cangjie".
  • Give the function token a color in the default dark preset (the light preset and five other builtin presets already define it), so declared function names and call sites are visible.

Fixes #

Type and Areas

Type: Feature

Areas: web UI (editor, markdown, appearance)

Motivation / Impact

Cangjie sources currently render as plain text in the editor and in chat code blocks, which makes .cj files hard to read in OpenBitFun. After this change:

  • .cj files open with syntax highlighting plus the correct comment, bracket and word configuration.
  • Chat code fences tagged cangjie or cj are highlighted instead of losing their colors.

Scope is highlighting plus language configuration only; no language server (completion, diagnostics, build integration) is included.

Verification

  • pnpm --dir src/web-ui exec vitest run src/tools/editor/languages/cangjie.language.test.ts src/infrastructure/markdown/cangjiePrismLanguage.test.ts src/infrastructure/language-detection/utils/helpers.test.ts src/infrastructure/appearance/builtins/appearancePresetOutput.test.ts src/shared/context-system/core/types/CodeSnippetContextImpl.test.ts src/infrastructure/markdown/MarkdownRenderer.test.tsx — passed (91 tests)
  • npx tsc --noEmit in src/web-ui — passed (no errors)
  • npx eslint on every changed source file — passed
  • node scripts/check-git-object-sizes.mjs --base origin/main --head HEAD — passed
  • pnpm run i18n:audit — passed with 0 warnings (the language definition and detection entry carry no CJK source text)
  • Manual: pnpm run desktop:preview:debug, opened a .cj sample; the status bar reports Cangjie, and highlighting is correct in both the dark and light appearance.
  • Chat fences are covered at the grammar level (Prism tokenization) and have not yet been checked inside a live conversation.

Reviewer Notes

  • AI-assisted: yes. Testing level: fully tested for the editor path, lightly tested for chat fences.
  • The Monarch rewrite documents where it intentionally diverges from the reference TextMate grammar: builtin types use a type token, free identifiers stay uncolored, quote(...) bodies are not string-colored, and raw-string hash counts are not enforced when closing.
  • Nested block comments, raw/hash strings, triple-quoted strings and ${...} interpolation are covered by tests; an unterminated single-line string no longer colors the following lines.
  • The builtin appearance snapshot changes for the dark preset only, because its Monaco rules list is no longer empty.
  • No new dependencies.

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable. (Language names follow the existing plain-string label maps; no new i18n keys.)

Generated with OpenBitFun

EthanCheung-gh and others added 3 commits October 17, 2026 19:47
Add a Monarch tokenizer for Cangjie derived from the TextMate grammar of the
CodeArts Agent Cangjie extension (scope `source.cj`); Monaco's standalone build
has no Oniguruma runtime, so the same lexical rules are expressed as Monarch.

- nested block comments, declarations, parameters, builtin types, macros
- raw, byte, J and triple-quoted strings with `${...}` interpolation
- `.cj` detection, status bar language name, language picker entry, code icon,
  drop preview kind and snippet label

Single-line strings end at end of line, so an unterminated quote no longer leaks
into the following lines.

Co-authored-by: OpenBitFun <318544290+bitfun-ai@users.noreply.github.com>
Chat code blocks render through `react-syntax-highlighter`'s `prism-async-light`,
which only knows its own refractor language map and silently falls back to plain
text for everything else. Register the Cangjie grammar (the same keyword tables
the editor uses) on the loaded highlighter instance, so ```cangjie fences are
highlighted instead of losing their colors.

Also label the fence "Cangjie" in the code block toolbar and treat `.cj` links in
markdown as editor-openable.

Co-authored-by: OpenBitFun <318544290+bitfun-ai@users.noreply.github.com>
`vs-dark` ships no rule for the `function` token, so any grammar that marks
declared function names and call sites with it falls back to the default
foreground. The light preset and five other builtin presets already define this
token; add the matching rule to the dark preset.

The builtin preset output snapshot changes accordingly (dark only).

Co-authored-by: OpenBitFun <318544290+bitfun-ai@users.noreply.github.com>
@EthanCheung-gh

Copy link
Copy Markdown
Contributor Author
openbitfun-cangjie-dark openbitfun-cangjie-light Examples of the final effect of Cangjie syntax highlighting in dark and light theme modes

@EthanCheung-gh
EthanCheung-gh marked this pull request as ready for review October 17, 2026 12:05
EthanCheung-gh and others added 2 commits October 17, 2026 20:06
The web UI i18n audit enforces a zero budget for CJK characters in source
files outside the locale catalogs, and the language definition carried three:
the file header comment, the Monaco alias list and the detection alias entry.

Replace the CJK alias spellings with the ASCII ones; the language picker still
lists the language through its `Cangjie`/`cangjie`/`cj` names.

`pnpm run i18n:audit` — passed with 0 warnings.

Co-authored-by: OpenBitFun <318544290+bitfun-ai@users.noreply.github.com>
Wrap the Prism grammar in a Refractor language registration function. Register it in the shared loader after engine preload and before exposing the cached highlighter, including CodePreview-first rendering.

Cover real async highlighter output, cached Markdown rendering, and concurrent preload ordering. Validation: 97 focused tests, check:web, and production-file ESLint passed. Tests run in Node and jsdom; live remote scenarios were not exercised.
@GCWing
GCWing merged commit 23cf086 into GCWing:main Oct 18, 2026
9 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.

2 participants