Skip to content

Conversation

@dingyi222666
Copy link
Contributor

@dingyi222666 dingyi222666 commented Nov 12, 2025

This PR adds experimental bracket pair colorization support to sora-editor, providing visual distinction for nested brackets through configurable colors.

Maybe it will be merged in 0.25.0, haha.

Screenshot (TextMate | Tree Sitter)

textmate textmate

New Features

  • Bracket pair colorization support for both language-textmate and language-treesitter modules
  • Support for customizing colors for 1-6 levels of bracket nesting
  • Rainbow brackets display in both sticky scroll and main editor interface
  • Enable/disable bracket pair colorization dynamically via setBracketPairColorization() API

Known Issues

This is an experimental feature with several areas needing improvement. Suggestions and contributions are welcome.

editor

  • Current bracket rendering implementation is rough and may contain bugs. Should migrate to style patch or a decorations-like API
  • Need to explore better data synchronization mechanisms for async processing (fetch from ui thread)

language-textmate

  • Achieves incremental updates for 30k lines within 50ms (thanks to VSCode's algorithm)
  • Need to test whether bracket nesting levels remain correct under repeated editing

language-treesitter

Usage

Enable bracket pair colorization in your language:

// For Editor
editor.getProps().bracketPairColorization = true;

// For TextMate
TextMateLanguage language = TextMateLanguage.create("source.java", true);
language.setBracketPairColorization(true);

// For Tree-sitter
TsLanguage language = new TsLanguage(...);
language.setBracketPairColorization(true);

Add level field to PairedBracket class to support rainbow bracket coloring
based on nesting depth. Extend BracketsProvider interface with new method
to query brackets within a range for efficient bracket highlighting.

Changes:
- Add level parameter to PairedBracket constructors
- Add queryPairedBracketsForRange() method to BracketsProvider interface
- Maintain backward compatibility with existing constructors
…-based parsing

Add comprehensive bracket matching system for TextMate languages using AST-based parsing and efficient incremental updates. This enables rainbow bracket highlighting and fast bracket pair queries.

Key changes:
- Implement TextMateBracketsProvider with dual AST architecture for bracket matching
- Add BracketLexer for token-aware bracket scanning with native skip support
- Create AST parser and balancer for efficient bracket tree construction
- Support incremental AST updates on content edits with anchor-based tracking
- Add bracket pair metadata extraction from language configurations
- Implement span change notifications for bracket analysis synchronization
- Add comprehensive unit tests for bracket matching functionality

The implementation supports both colorized bracket pairs and regular bracket pairs from language configurations, with automatic fallback to legacy OnlineBracketsMatcher for simple single-character brackets.

Editor core changes provide hooks for bracket providers to receive content and span updates, enabling efficient incremental analysis.
- Add bracketPairColorization property to DirectAccessProps for rainbow brackets
- Introduce CachedBracketsProvider base class with shared query caching logic
- Refactor TextMateBracketsProvider to extend CachedBracketsProvider
- Remove duplicate QueryCache implementation in TextMateBracketsProvider
- Clean up debug logging in AsyncIncrementalAnalyzeManager

This change enables bracket pair colorization (rainbow brackets) as an
experimental feature and improves code organization by extracting common
caching functionality into a reusable base class.
Add visual bracket pair colorization to improve code readability by
assigning distinct colors to nested bracket pairs based on their depth level.

Changes:
- Add bracketPairColorization property to editor props
- Implement patchBracketPairColorization rendering in EditorRenderer
- Add 6 configurable bracket highlighting color slots (BRACKET_HIGHLIGHTING_FOREGROUND_1-6)
- Compute and cache bracket pair colors in EditorStyleDelegate
- Fix CachedBracketsProvider to use line/column coordinates instead of char indices
- Refactor patchTextRegionWithColor to support both bold and regular styles
- Remove debug println statements from bracket providers
- Enable bracket pair colorization in MainActivity demo

The implementation uses modulo arithmetic to cycle through available colors
for deeply nested brackets, with a maximum depth of 30 levels tracked.
…e query

Implement basic bracket pair colorization using range-based queries:
- Add computePairedBracketsForRange in TsBracketPairs for batch computation
- Add simple depth tracking for rainbow bracket levels
- Set 4000*300 character limit to prevent performance issues
- Simplify Java bracket queries with direct symbol matching
- Update cache management in CachedBracketsProvider
- Remove separate rainbow-delimiters.scm file
Add simple bracket colorization support for stuck/pinned lines:
- Add drawSingleTextLineWithStuck method for stuck line rendering
- Implement patchBracketPairColorizationForStuckLine for stuck line colorization
- Disable hardware acceleration when brackets need colorization
- Remove debug print statement from BracketMatcherAST
Optimize bracket pair computation and caching:
- Compute and cache all bracket pairs when TsBracketPairs is created
- Store UTF16String reference for predicate evaluation
- Filter cached pairs by range instead of re-querying tree-sitter
- Cache paired brackets using both leftIndex and rightIndex as keys
- Update bracket provider before setting styles to ensure data availability
- Remove unused imports and debug print statements
- Set colorization limit to 6000 * 300 characters

This improves rendering performance by avoiding repeated tree-sitter queries
and ensures bracket pairs can be quickly retrieved from either end.
…h vscode-source integration

Implement dynamic bracket pair colorization control in TextMate language support by:
- Adding isBracketPairColorization property to TextMateLanguage with runtime toggle support
- Refactoring TextMateAnalyzer bracket provider lifecycle to support switching between legacy and AST-based providers
- Modifying onSpansChanged to pass Styles parameter for bracket provider initialization
- Updating copyright headers for vscode-sourced files (comparators.kt, filters.kt, AST implementation)
- Configuring IntelliJ scope and copyright profile for vscode-source module
- Enabling bracket colorization in MainActivity demo for both TextMate and TreeSitter languages
- Adding LeakCanary to debug dependencies

The implementation allows runtime toggling between simple bracket matching and advanced AST-based
bracket pair colorization, properly managing provider lifecycle and ensuring bracket providers are
published to receivers at appropriate times.
…etsProvider

Remove auto-generated IntelliJ IDEA configuration files (deviceManager.xml, markdown.xml)
and add JavaDoc documentation to queryPairedBracketsForRange method in BracketsProvider
interface to clarify parameter usage and return value.
Remove kotlinx-coroutines dependency from language-textmate module as it is not
used in the current implementation.
…mand computation

Replace cached bracket pair computation with on-demand querying to improve
performance and reduce memory usage. The changes include:

- Remove CachedBracketsProvider inheritance in favor of direct BracketsProvider
- Implement on-demand bracket pair queries with tree cursor navigation
- Add depth calculation using tree cursor for proper nesting visualization
- Move bracket provider update before span generation in TsAnalyzeManager
- Remove unnecessary text parameter from TsBracketPairs constructor
- Increase colorization limit to 60000 * 300 for larger files

This approach eliminates the need to pre-compute all bracket pairs, instead
computing only the visible brackets within the requested range, resulting in
better performance for large files.
…aching

Revert to using CachedBracketsProvider instead of direct BracketsProvider
implementation to enable proper caching of bracket pair queries. This change:

- Restores CachedBracketsProvider inheritance for performance optimization
- Reverts method names to computePairedBracketAt and computePairedBracketsForRange
- Maintains the on-demand query implementation with tree cursor navigation

The caching layer is necessary to avoid redundant bracket pair computations
for the same text ranges during rendering.
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