antares 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +206 -82
- data/lib/antares/compatibility.rb +72 -72
- data/lib/antares/grammar.rb +274 -0
- data/lib/antares/highlighter.rb +93 -13
- data/lib/antares/structure.rb +430 -0
- data/lib/antares/tm_language_lexer.rb +193 -0
- data/lib/antares/tm_language_plist.rb +146 -0
- data/lib/antares/version.rb +1 -1
- data/lib/antares.rb +7 -0
- data/sig/antares.rbs +63 -0
- metadata +26 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0243ed5a88d91e34cf4654f9e3437d590e9079caea1976fde034213dbf28ab8c
|
|
4
|
+
data.tar.gz: 77b2751092cc3f1fb5dd9aaf7dc0615c724512d958f1bfe7a198bc7cad70b463
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b24e5c58ad94c655378e327344a9404a73a5bf57185d44854f84ab831bd29857381c5117ee3de4ac00a5de044e2c23560c564cf0a16bd7aa62a369546dc805f1
|
|
7
|
+
data.tar.gz: b988ef69cdf0395af22403e427677ebef54b1fe84cbbeae4b4a2127e0b4c78a243ce8fde131acf6cd0fc79aa3828c078b7dcb6057cb376bde3abcd1ee646c907
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 — 2026-09-15
|
|
4
|
+
|
|
5
|
+
- Add edit-aware bracket matching and depth information.
|
|
6
|
+
- Add fold regions for brackets, indentation, consecutive comments, and region markers.
|
|
7
|
+
- Add sticky contexts and expanding selection ranges.
|
|
8
|
+
- Add language-specific structure provider registration without a parser dependency.
|
|
9
|
+
- Add bounded JSON and XML plist tmLanguage loading with Rouge-compatible output.
|
|
10
|
+
|
|
3
11
|
## 0.1.0 — 2026-09-10
|
|
4
12
|
|
|
5
13
|
- Initial release.
|
data/README.md
CHANGED
|
@@ -1,8 +1,69 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">Antares</h1>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Incremental syntax highlighting for Rouge, with measured per-lexer compatibility</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://rubygems.org/gems/antares"><img src="https://img.shields.io/gem/v/antares.svg?colorB=319e8c" alt="Gem Version"></a>
|
|
9
|
+
<a href="https://rubygems.org/gems/antares"><img src="https://img.shields.io/gem/dt/antares.svg" alt="Downloads"></a>
|
|
10
|
+
<img src="https://img.shields.io/badge/ruby-%3E%3D%203.1-ruby.svg" alt="Ruby Version">
|
|
11
|
+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="#features">Features</a> ·
|
|
16
|
+
<a href="#installation">Installation</a> ·
|
|
17
|
+
<a href="#quick-start">Quick Start</a> ·
|
|
18
|
+
<a href="#configuration">Configuration</a> ·
|
|
19
|
+
<a href="#how-it-works">How It Works</a> ·
|
|
20
|
+
<a href="#compatibility">Compatibility</a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Antares adds edit-aware, line-oriented syntax highlighting to [Rouge](https://github.com/rouge-ruby/rouge). It reuses lexer state where compatibility tests show that incremental highlighting is safe, and falls back to bounded re-highlighting for other lexers. Document storage and colors remain with the caller.
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
<a name="features"></a>
|
|
30
|
+
|
|
31
|
+
- Lazy tokenization for individual lines or ranges
|
|
32
|
+
- Incremental re-highlighting with sparse state checkpoints
|
|
33
|
+
- Cached suffix reuse after edits converge
|
|
34
|
+
- Measured compatibility for every Rouge lexer
|
|
35
|
+
- Windowed and full-document fallback strategies
|
|
36
|
+
- Configurable time and memory limits
|
|
37
|
+
- Bracket pairs, fold regions, sticky contexts, and expanding selections
|
|
38
|
+
- JSON and XML plist tmLanguage grammars for languages Rouge does not cover
|
|
39
|
+
- Rouge and REXML are the only runtime dependencies
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
<a name="installation"></a>
|
|
44
|
+
|
|
45
|
+
Add to your Gemfile:
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
gem "antares"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then install:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bundle install
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Requirements
|
|
58
|
+
|
|
59
|
+
<a name="requirements"></a>
|
|
60
|
+
|
|
61
|
+
- Ruby 3.1+
|
|
62
|
+
- Rouge 5.x
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
<a name="quick-start"></a>
|
|
6
67
|
|
|
7
68
|
```ruby
|
|
8
69
|
require "antares"
|
|
@@ -15,97 +76,160 @@ highlighter = Antares::Highlighter.new(
|
|
|
15
76
|
)
|
|
16
77
|
|
|
17
78
|
highlighter.tokens_for(0) # [[Rouge token class, UTF-8 text], ...]
|
|
79
|
+
|
|
18
80
|
lines[0] = "value = 2\n"
|
|
19
81
|
highlighter.edit(from_line: 0, removed: 1, inserted: 1)
|
|
20
82
|
highlighter.tokens_in(0..1) # one token array per line
|
|
83
|
+
|
|
84
|
+
structure = highlighter.structure # built lazily from the same Rouge tokens
|
|
85
|
+
structure.bracket_at(0, 7) # matching Antares::Bracket, or nil
|
|
86
|
+
structure.fold_regions # bracket, indentation, comment, and #region folds
|
|
87
|
+
structure.context_at(1) # outer-to-inner regions for sticky scroll
|
|
88
|
+
structure.selection_ranges(1, 3) # inner-to-outer Antares::Region values
|
|
21
89
|
```
|
|
22
90
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
from building and is not performed by tests or CI.
|
|
91
|
+
Update the provider before calling `edit`. Line indices are zero based;
|
|
92
|
+
`removed` is the old line count and `inserted` is the new line count.
|
|
26
93
|
|
|
27
|
-
|
|
94
|
+
The `lines` provider returns one valid UTF-8 logical line for each index,
|
|
95
|
+
preferably including its newline. Tokens contain text rather than offsets: sum
|
|
96
|
+
`text.bytesize` for byte offsets or `text.length` for character offsets.
|
|
97
|
+
Returned rows, token pairs, and text are frozen.
|
|
28
98
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
99
|
+
Bracket and selection columns are zero-based character offsets. A selection
|
|
100
|
+
region's `end_column` is exclusive. Fold regions use inclusive, zero-based line
|
|
101
|
+
indices; their column fields are `nil`. Brackets inside string and comment
|
|
102
|
+
tokens are ignored. `Highlighter#edit` updates the existing `Structure`
|
|
103
|
+
instance and reuses unchanged line data after token state converges.
|
|
34
104
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`
|
|
38
|
-
`last_scanned_lines` reports actual lexical work, and `checkpoint_bytes` reports
|
|
105
|
+
`frontier` is the first line not yet proven current.
|
|
106
|
+
`advance(until_line: 200)` lets an event loop schedule incremental work.
|
|
107
|
+
`last_scanned_lines` reports lexical work and `checkpoint_bytes` reports
|
|
39
108
|
normalized checkpoint payload bytes. Highlighter instances are not thread safe.
|
|
40
109
|
|
|
110
|
+
Language-specific structure providers can replace the generic derivation for
|
|
111
|
+
future highlighters with the matching Rouge lexer tag:
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
Antares::Structure.register(:ruby, RubyStructureProvider)
|
|
115
|
+
# RubyStructureProvider.new receives the same five callbacks as Structure.new.
|
|
116
|
+
Antares::Structure.unregister(:ruby)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
A provider returns an object implementing `fold_regions`, `brackets`,
|
|
120
|
+
`bracket_at`, `context_at`, `selection_ranges`, and `edit`. Registration is
|
|
121
|
+
thread safe, case insensitive, and affects only structures built afterwards.
|
|
122
|
+
Providers must reflect line changes before `Highlighter#edit`, just like the
|
|
123
|
+
line provider. Antares does not depend on Prism.
|
|
124
|
+
|
|
125
|
+
Load a UTF-8 JSON or XML plist tmLanguage file when Rouge has no lexer for the
|
|
126
|
+
language, then pass the result to `Highlighter` normally:
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
lexer = Antares::Grammar.load_tmlanguage("syntaxes/example.tmLanguage.json")
|
|
130
|
+
highlighter = Antares::Highlighter.new(lexer: lexer, lines: lines, line_count: count)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The loader supports repository references, `$self`/`$base`, `match`, nested
|
|
134
|
+
patterns, `begin`/`end` (including `applyEndPatternLast`) with numeric
|
|
135
|
+
begin-capture references, and named captures. TextMate comment, string,
|
|
136
|
+
numeric, keyword, storage, name, variable,
|
|
137
|
+
punctuation, markup, and invalid scopes map to their nearest Rouge token types.
|
|
138
|
+
Files are limited to 2 MiB, 64 levels, 10,000 rules, and 16 KiB per regular
|
|
139
|
+
expression; lexing also has byte and time bounds. External grammar includes,
|
|
140
|
+
`while`, nested repositories, capture subgrammars, and injection grammars raise
|
|
141
|
+
`Antares::GrammarError` instead of being partially interpreted.
|
|
142
|
+
The fixed Apple plist 1.0 document type is accepted without external lookup;
|
|
143
|
+
custom document types and entity declarations are rejected.
|
|
144
|
+
|
|
145
|
+
## Configuration
|
|
146
|
+
|
|
147
|
+
<a name="configuration"></a>
|
|
148
|
+
|
|
149
|
+
Pass options to `Antares::Highlighter.new`:
|
|
150
|
+
|
|
151
|
+
| Option | Type | Default | Description |
|
|
152
|
+
|--------|------|---------|-------------|
|
|
153
|
+
| `strategy` | Symbol | `:auto` | Highlighting strategy |
|
|
154
|
+
| `checkpoint_interval` | Integer | `64` | Completed lines between checkpoints |
|
|
155
|
+
| `window_context` | Integer | `200` | Lines of context for window mode |
|
|
156
|
+
| `max_lines` | Integer | `100_000` | Maximum document lines |
|
|
157
|
+
| `max_bytes` | Integer | `8 MiB` | Maximum source snapshot |
|
|
158
|
+
| `max_line_bytes` | Integer | `16 KiB` | Maximum bytes per line |
|
|
159
|
+
| `max_checkpoint_bytes` | Integer | `256 KiB` | Maximum checkpoint payload |
|
|
160
|
+
| `max_seconds` | Numeric | `0.25` | Maximum time per scan |
|
|
161
|
+
|
|
162
|
+
### Strategies
|
|
163
|
+
|
|
41
164
|
| Strategy | Behavior |
|
|
42
|
-
|
|
43
|
-
| `:auto` | Uses the bundled
|
|
44
|
-
| `:incremental` | Forces state snapshots and convergence. Use for certified lexers
|
|
45
|
-
| `:window` | Restarts from root up to
|
|
46
|
-
| `:full` | Runs
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
165
|
+
|----------|----------|
|
|
166
|
+
| `:auto` | Uses the verdict bundled for the exact Rouge version. Unknown versions and lexers use `:window`. |
|
|
167
|
+
| `:incremental` | Forces state snapshots and convergence. Use only for certified lexers. |
|
|
168
|
+
| `:window` | Restarts from the root state up to `window_context` lines before the requested range. |
|
|
169
|
+
| `:full` | Runs Rouge over the complete bounded document after every edit. |
|
|
170
|
+
|
|
171
|
+
Exceeding a source limit switches to window mode. Oversized lines and timed-out
|
|
172
|
+
ranges return complete plain-text tokens. `fallback_reason` explains the
|
|
173
|
+
transition. These limits also apply to `:full`.
|
|
174
|
+
|
|
175
|
+
## How It Works
|
|
176
|
+
|
|
177
|
+
<a name="how-it-works"></a>
|
|
178
|
+
|
|
179
|
+
1. Source Materialization builds a bounded source string from the line provider
|
|
180
|
+
2. Checkpoint Restore resumes the nearest reusable lexer state
|
|
181
|
+
3. Incremental Lexing records tokens and sparse state checkpoints
|
|
182
|
+
4. State Convergence reuses the untouched cached suffix after an edit
|
|
183
|
+
5. Fallback Selection uses window mode when incremental lexing is not certified
|
|
184
|
+
|
|
185
|
+
Antares copies persistent Rouge lexer state, including nested collections,
|
|
186
|
+
delegate lexers, and heredoc queues. Checkpoints are created after complete rule
|
|
187
|
+
callbacks because Rouge expressions can consume multiple lines or inspect
|
|
188
|
+
surrounding text.
|
|
189
|
+
|
|
190
|
+
Some grammars are inherently nonlocal. For example, adding a distant `=end` can
|
|
191
|
+
change how Rouge classifies an earlier unmatched Ruby `=begin`. Such lexers use
|
|
192
|
+
window mode instead of unsafe incremental highlighting.
|
|
193
|
+
|
|
194
|
+
## Compatibility
|
|
195
|
+
|
|
196
|
+
<a name="compatibility"></a>
|
|
197
|
+
|
|
198
|
+
`Antares.compatible?(Rouge::Lexers::Python)` returns `:incremental` or
|
|
199
|
+
`:window`. Every registered lexer has a bundled verdict; see the
|
|
200
|
+
[complete compatibility table](docs/compatibility.md).
|
|
201
|
+
|
|
202
|
+
The matrix uses three source variants from Rouge's bundled MIT-licensed demos,
|
|
203
|
+
applies 50 deterministic edits to each, and compares every line against a fresh
|
|
204
|
+
full lex. Three distant-closure probes detect backward reclassification. The
|
|
205
|
+
result is an empirical corpus guarantee, not a proof for every input or
|
|
206
|
+
non-default lexer option.
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
<a name="development"></a>
|
|
211
|
+
|
|
212
|
+
```bash
|
|
87
213
|
bundle install
|
|
88
214
|
bundle exec rake test
|
|
89
215
|
bundle exec ruby script/compatibility --write
|
|
90
|
-
BUDGET=1 bundle exec
|
|
216
|
+
BUDGET=1 bundle exec rake bench
|
|
91
217
|
```
|
|
92
218
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Released under the [MIT license](LICENSE.txt).
|
|
219
|
+
Use `MUTATIONS=5 ruby script/compatibility python rust` for a short compatibility
|
|
220
|
+
run. Only full runs with at least 50 mutations may replace the bundled matrix.
|
|
221
|
+
CI tests Ruby 3.1 through 4.0 on Linux, macOS, and Windows.
|
|
222
|
+
|
|
223
|
+
See the [changelog](CHANGELOG.md) for release history.
|
|
224
|
+
|
|
225
|
+
## Contributing
|
|
226
|
+
|
|
227
|
+
<a name="contributing"></a>
|
|
228
|
+
|
|
229
|
+
Bug reports and pull requests are welcome at https://github.com/noxdea/antares.
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
<a name="license"></a>
|
|
234
|
+
|
|
235
|
+
Released under the [MIT License](LICENSE.txt).
|