@citisen/litearea 0.1.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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +514 -0
  3. package/README.zh.md +362 -0
  4. package/dist/grammars.cjs +1228 -0
  5. package/dist/grammars.cjs.map +1 -0
  6. package/dist/grammars.js +1213 -0
  7. package/dist/grammars.js.map +1 -0
  8. package/dist/index.cjs +3103 -0
  9. package/dist/index.cjs.map +1 -0
  10. package/dist/index.js +3040 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/react.cjs +3032 -0
  13. package/dist/react.cjs.map +1 -0
  14. package/dist/react.js +3010 -0
  15. package/dist/react.js.map +1 -0
  16. package/dist/styles.cjs +453 -0
  17. package/dist/styles.cjs.map +1 -0
  18. package/dist/styles.css +432 -0
  19. package/dist/styles.js +447 -0
  20. package/dist/styles.js.map +1 -0
  21. package/dist/types/core/complete.d.ts +70 -0
  22. package/dist/types/core/complete.d.ts.map +1 -0
  23. package/dist/types/core/format.d.ts +34 -0
  24. package/dist/types/core/format.d.ts.map +1 -0
  25. package/dist/types/core/grammar.d.ts +14 -0
  26. package/dist/types/core/grammar.d.ts.map +1 -0
  27. package/dist/types/core/hover.d.ts +23 -0
  28. package/dist/types/core/hover.d.ts.map +1 -0
  29. package/dist/types/core/index.d.ts +12 -0
  30. package/dist/types/core/index.d.ts.map +1 -0
  31. package/dist/types/core/inspect.d.ts +34 -0
  32. package/dist/types/core/inspect.d.ts.map +1 -0
  33. package/dist/types/core/rank.d.ts +82 -0
  34. package/dist/types/core/rank.d.ts.map +1 -0
  35. package/dist/types/core/scan.d.ts +51 -0
  36. package/dist/types/core/scan.d.ts.map +1 -0
  37. package/dist/types/core/segments.d.ts +44 -0
  38. package/dist/types/core/segments.d.ts.map +1 -0
  39. package/dist/types/core/text.d.ts +113 -0
  40. package/dist/types/core/text.d.ts.map +1 -0
  41. package/dist/types/core/types.d.ts +604 -0
  42. package/dist/types/core/types.d.ts.map +1 -0
  43. package/dist/types/core/vocabulary.d.ts +82 -0
  44. package/dist/types/core/vocabulary.d.ts.map +1 -0
  45. package/dist/types/dom/create.d.ts +17 -0
  46. package/dist/types/dom/create.d.ts.map +1 -0
  47. package/dist/types/dom/editing.d.ts +89 -0
  48. package/dist/types/dom/editing.d.ts.map +1 -0
  49. package/dist/types/dom/editor.d.ts +366 -0
  50. package/dist/types/dom/editor.d.ts.map +1 -0
  51. package/dist/types/dom/index.d.ts +9 -0
  52. package/dist/types/dom/index.d.ts.map +1 -0
  53. package/dist/types/dom/mirror.d.ts +107 -0
  54. package/dist/types/dom/mirror.d.ts.map +1 -0
  55. package/dist/types/dom/overlay.d.ts +52 -0
  56. package/dist/types/dom/overlay.d.ts.map +1 -0
  57. package/dist/types/dom/popup.d.ts +95 -0
  58. package/dist/types/dom/popup.d.ts.map +1 -0
  59. package/dist/types/dom/support.d.ts +41 -0
  60. package/dist/types/dom/support.d.ts.map +1 -0
  61. package/dist/types/dom/tooltip.d.ts +39 -0
  62. package/dist/types/dom/tooltip.d.ts.map +1 -0
  63. package/dist/types/grammars/dshFont.d.ts +127 -0
  64. package/dist/types/grammars/dshFont.d.ts.map +1 -0
  65. package/dist/types/grammars/dshSentry.d.ts +84 -0
  66. package/dist/types/grammars/dshSentry.d.ts.map +1 -0
  67. package/dist/types/grammars/index.d.ts +3 -0
  68. package/dist/types/grammars/index.d.ts.map +1 -0
  69. package/dist/types/index.d.ts +15 -0
  70. package/dist/types/index.d.ts.map +1 -0
  71. package/dist/types/react/index.d.ts +91 -0
  72. package/dist/types/react/index.d.ts.map +1 -0
  73. package/dist/types/styles.d.ts +29 -0
  74. package/dist/types/styles.d.ts.map +1 -0
  75. package/docs/architecture.md +316 -0
  76. package/docs/completion.md +320 -0
  77. package/docs/grammar.md +823 -0
  78. package/package.json +105 -0
  79. package/scripts/browser-check.mjs +838 -0
  80. package/scripts/build-css.mjs +35 -0
  81. package/scripts/release.mjs +91 -0
  82. package/scripts/verify-package.mjs +253 -0
  83. package/src/core/complete.ts +286 -0
  84. package/src/core/format.ts +71 -0
  85. package/src/core/grammar.ts +40 -0
  86. package/src/core/hover.ts +129 -0
  87. package/src/core/index.ts +98 -0
  88. package/src/core/inspect.ts +198 -0
  89. package/src/core/rank.ts +317 -0
  90. package/src/core/scan.ts +720 -0
  91. package/src/core/segments.ts +185 -0
  92. package/src/core/text.ts +238 -0
  93. package/src/core/types.ts +681 -0
  94. package/src/core/vocabulary.ts +196 -0
  95. package/src/dom/create.ts +31 -0
  96. package/src/dom/editing.ts +213 -0
  97. package/src/dom/editor.ts +1143 -0
  98. package/src/dom/index.ts +46 -0
  99. package/src/dom/mirror.ts +305 -0
  100. package/src/dom/overlay.ts +106 -0
  101. package/src/dom/popup.ts +323 -0
  102. package/src/dom/support.ts +88 -0
  103. package/src/dom/tooltip.ts +112 -0
  104. package/src/grammars/dshFont.ts +1004 -0
  105. package/src/grammars/dshSentry.ts +742 -0
  106. package/src/grammars/index.ts +57 -0
  107. package/src/index.ts +122 -0
  108. package/src/react/index.tsx +248 -0
  109. package/src/styles.ts +529 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAMA,YAAY,EACV,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,UAAU,EACV,OAAO,EACP,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,KAAK,EACL,UAAU,EACV,kBAAkB,EAClB,IAAI,EACJ,WAAW,EACX,SAAS,EACT,KAAK,EACL,SAAS,EACT,QAAQ,EACR,cAAc,EACd,KAAK,EACL,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE/D,OAAO,EACL,KAAK,EACL,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,MAAM,EACN,WAAW,EACX,UAAU,EACV,OAAO,EACP,UAAU,EACV,OAAO,EACP,WAAW,EACX,YAAY,EACZ,UAAU,GACX,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,IAAI,EACJ,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAEnG,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAA;AAE7E,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,IAAI,EACJ,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,eAAe,EACf,QAAQ,EACR,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE1D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,34 @@
1
+ import type { Decoration, Diagnostic, Grammar, Token } from './types.js';
2
+ import { type ResolvedGrammar } from './scan.js';
3
+ /** Everything one pass over a document produced. */
4
+ export interface Inspection<State = unknown> {
5
+ /** The text this was computed from, kept so nothing has to guess its version. */
6
+ text: string;
7
+ tokens: Token[];
8
+ /** Lexical problems, the grammar's `checks`, and its `validate`, together. */
9
+ diagnostics: Diagnostic[];
10
+ /** Semantic ranges that are not tokens. */
11
+ decorations: Decoration[];
12
+ /** Whatever `Grammar.analyze` returned. */
13
+ state: State;
14
+ }
15
+ /**
16
+ * Inspect a document: paint, problems, decorations, and structure in one pass.
17
+ * @param source - the document.
18
+ * @param grammar - the language, as written or already resolved.
19
+ * @returns everything the editor needs for one text.
20
+ */
21
+ export declare function inspect<State>(source: string, grammar: Grammar<State> | ResolvedGrammar<State>): Inspection<State>;
22
+ /**
23
+ * Sort diagnostics by position and drop duplicates.
24
+ *
25
+ * Two rules can legitimately notice the same mistake — a vocabulary's own
26
+ * rejection and a grammar's validator both know that `nope` is not a colour —
27
+ * and drawing the underline twice makes it darker rather than more informative.
28
+ * Duplicates are compared on position, code, and message, so two genuinely
29
+ * different complaints about one word both survive.
30
+ * @param diagnostics - the collected diagnostics.
31
+ * @returns the deduplicated, ordered list.
32
+ */
33
+ export declare function normalizeDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[];
34
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../src/core/inspect.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAEV,UAAU,EAEV,UAAU,EACV,OAAO,EACP,KAAK,EACN,MAAM,YAAY,CAAA;AAEnB,OAAO,EAA2C,KAAK,eAAe,EAAE,MAAM,WAAW,CAAA;AAGzF,oDAAoD;AACpD,MAAM,WAAW,UAAU,CAAC,KAAK,GAAG,OAAO;IACzC,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,8EAA8E;IAC9E,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,2CAA2C;IAC3C,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,CAAA;CACb;AAuED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,GAC/C,UAAU,CAAC,KAAK,CAAC,CAqCnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE,CAUrF"}
@@ -0,0 +1,82 @@
1
+ /** A needle and the positions in the label it matched. */
2
+ export interface FuzzyMatch {
3
+ /** The ranking score. Higher is a better match. */
4
+ score: number;
5
+ /** The matched offsets into the label, ascending, for showing what matched. */
6
+ indices: number[];
7
+ /** The tier the match reached, for tests and for explaining a ranking. */
8
+ tier: number;
9
+ }
10
+ /**
11
+ * Whether a position in a label starts a word.
12
+ *
13
+ * Three things start one: the beginning, a separator, and a lower-to-upper
14
+ * transition. The third is what makes camelCase names searchable by their humps,
15
+ * and it is why `NotoSans` and `Noto Sans` behave the same way under a needle
16
+ * like `ns`.
17
+ * @param label - the text being searched.
18
+ * @param index - a position in it.
19
+ * @returns whether a word starts there.
20
+ */
21
+ export declare function isWordStart(label: string, index: number): boolean;
22
+ /**
23
+ * Match a needle against a label.
24
+ *
25
+ * Case follows the needle: a needle with an uppercase character is matched
26
+ * case-sensitively, so `Inter` does not quietly match `inter`, while an
27
+ * all-lowercase needle matches anything. That is the same "smart case" a
28
+ * terminal has used for decades and the one VSCode applies.
29
+ * @param needle - what the user has typed.
30
+ * @param label - what is being searched.
31
+ * @returns the score and matched offsets, or undefined when the needle does not match.
32
+ */
33
+ export declare function fuzzyMatch(needle: string, label: string): FuzzyMatch | undefined;
34
+ /** One row of a ranked list, with the evidence for its position. */
35
+ export interface Ranked<T> {
36
+ item: T;
37
+ score: number;
38
+ /** The offsets in the label that matched, for emphasising them in the list. */
39
+ indices: number[];
40
+ }
41
+ /** How to read a row while ranking it. */
42
+ export interface RankOptions<T> {
43
+ /** The text shown to the user. */
44
+ label(item: T): string;
45
+ /** The text matched against the needle, when it differs from the label. */
46
+ filterText?(item: T): string;
47
+ /**
48
+ * The primary sort key, as VSCode's `sortText` is: rows are ordered by it
49
+ * first and by match score only within an equal key. It is how a grammar puts
50
+ * a whole group on top — the value already in effect, say — without pretending
51
+ * its label starts with a `0`.
52
+ */
53
+ sortText?(item: T): string | undefined;
54
+ }
55
+ /**
56
+ * Filter and order rows for a needle.
57
+ *
58
+ * An empty needle keeps every row in the order the grammar declared, which is
59
+ * what Ctrl+Space should show: the whole vocabulary, grouped the way the grammar
60
+ * thinks about it, not alphabetised by a scorer that has nothing to go on.
61
+ * @param items - the candidate rows.
62
+ * @param needle - what the user has typed.
63
+ * @param options - how to read a row.
64
+ * @returns the matching rows, best first.
65
+ */
66
+ export declare function rank<T>(items: readonly T[], needle: string, options: RankOptions<T>): Ranked<T>[];
67
+ /**
68
+ * Split a label around the characters a needle matched, for the list to emphasise.
69
+ *
70
+ * Returned as segments rather than as a marked-up string because the caller is
71
+ * building DOM nodes, not HTML: a font family called `<b>` must be shown as
72
+ * `<b>`, and a completer that returns markup has to escape what it was given or
73
+ * it is wrong about a real font.
74
+ * @param label - the row's text.
75
+ * @param indices - the matched offsets, ascending.
76
+ * @returns alternating plain and matched segments, in order.
77
+ */
78
+ export declare function highlightSegments(label: string, indices: readonly number[]): Array<{
79
+ text: string;
80
+ matched: boolean;
81
+ }>;
82
+ //# sourceMappingURL=rank.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.d.ts","sourceRoot":"","sources":["../../../src/core/rank.ts"],"names":[],"mappings":"AAuDA,0DAA0D;AAC1D,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAMjE;AAkCD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAqEhF;AA0BD,oEAAoE;AACpE,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,CAAA;IACP,KAAK,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,0CAA0C;AAC1C,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,kCAAkC;IAClC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAA;IACtB,2EAA2E;IAC3E,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAAA;CACvC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CA6BjG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAe3C"}
@@ -0,0 +1,51 @@
1
+ import type { Diagnostic, Grammar, Rule, Scope, Token } from './types.js';
2
+ /** A grammar with its defaults filled in and its patterns made safe to reuse. */
3
+ export interface ResolvedGrammar<State = unknown> {
4
+ /**
5
+ * Marks this value as already resolved.
6
+ *
7
+ * Present so the two shapes can be told apart without guessing. The obvious test
8
+ * — "does it have a `fallbackScope`?" — is wrong, because a plain grammar is
9
+ * allowed to declare one, and the mistake surfaces as the engine reading `.grammar`
10
+ * off a value that has no such field and crashing at the first keystroke.
11
+ */
12
+ readonly __resolved: true;
13
+ grammar: Grammar<State>;
14
+ rules: readonly Rule<State>[];
15
+ /** The scope a character no rule claimed is painted with. */
16
+ fallbackScope: Scope;
17
+ /** The single-character test that decides where words begin and end. */
18
+ wordChars: RegExp;
19
+ }
20
+ /**
21
+ * Whether a value is a resolved grammar rather than one as written.
22
+ * @param value - the grammar, either shape.
23
+ * @returns whether it is already resolved.
24
+ */
25
+ export declare function isResolvedGrammar<State>(value: Grammar<State> | ResolvedGrammar<State>): value is ResolvedGrammar<State>;
26
+ /** The whole result of one scan: the paint, what the scan noticed, and the analysis. */
27
+ export interface ScanResult<State = unknown> {
28
+ tokens: Token[];
29
+ /**
30
+ * What the lexical pass itself found: a word a vocabulary rejected, a region
31
+ * that never closed. A grammar's own `checks` and `validate` are added by
32
+ * `diagnose`, which builds on this.
33
+ */
34
+ diagnostics: Diagnostic[];
35
+ /** Whatever `Grammar.analyze` returned, or `initialState`. */
36
+ state: State;
37
+ }
38
+ /**
39
+ * Fill in a grammar's defaults and make its patterns safe.
40
+ * @param grammar - the grammar as written.
41
+ * @returns the grammar the scanner runs.
42
+ */
43
+ export declare function resolveGrammar<State>(grammar: Grammar<State>): ResolvedGrammar<State>;
44
+ /**
45
+ * Scan a document into tokens.
46
+ * @param source - the document.
47
+ * @param grammar - the language, as written or already resolved.
48
+ * @returns the tokens, the lexical diagnostics, and the analysis.
49
+ */
50
+ export declare function scan<State>(source: string, grammar: Grammar<State> | ResolvedGrammar<State>): ScanResult<State>;
51
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/core/scan.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,UAAU,EACV,OAAO,EAGP,IAAI,EAGJ,KAAK,EAEL,KAAK,EAIN,MAAM,YAAY,CAAA;AAKnB,iFAAiF;AACjF,MAAM,WAAW,eAAe,CAAC,KAAK,GAAG,OAAO;IAC9C;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;IACzB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IACvB,KAAK,EAAE,SAAS,IAAI,CAAC,KAAK,CAAC,EAAE,CAAA;IAC7B,6DAA6D;IAC7D,aAAa,EAAE,KAAK,CAAA;IACpB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EACrC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,GAC7C,KAAK,IAAI,eAAe,CAAC,KAAK,CAAC,CAEjC;AAED,wFAAwF;AACxF,MAAM,WAAW,UAAU,CAAC,KAAK,GAAG,OAAO;IACzC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf;;;;OAIG;IACH,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,8DAA8D;IAC9D,KAAK,EAAE,KAAK,CAAA;CACb;AAoDD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAQrF;AAeD;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,KAAK,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,GAC/C,UAAU,CAAC,KAAK,CAAC,CA0gBnB"}
@@ -0,0 +1,44 @@
1
+ import type { Decoration, Diagnostic, Severity, Token } from './types.js';
2
+ /** One run of characters that all share the same presentation. */
3
+ export interface PaintSegment {
4
+ from: number;
5
+ to: number;
6
+ /** The characters themselves, so the painter never re-slices. */
7
+ text: string;
8
+ /** The scope that colours them. */
9
+ scope: string;
10
+ /** The decoration kinds that mark them, in declaration order. */
11
+ decorations: string[];
12
+ /** The loudest diagnostic covering them, when one does. */
13
+ severity: Severity | undefined;
14
+ /** A hover title donated by a decoration, when it has one. */
15
+ title: string | undefined;
16
+ }
17
+ /** What a segment builder needs: the three range lists and nothing else. */
18
+ export interface SegmentInput {
19
+ tokens: readonly Token[];
20
+ decorations: readonly Decoration[];
21
+ diagnostics: readonly Diagnostic[];
22
+ }
23
+ /**
24
+ * Merge a scope, a decoration, and a diagnostic into adjacent segments.
25
+ *
26
+ * @param text - the document the ranges refer to.
27
+ * @param input - the three range lists.
28
+ * @param fallbackScope - the scope for characters no token covers.
29
+ * @returns the segments, in order, covering the whole document.
30
+ */
31
+ export declare function buildSegments(text: string, input: SegmentInput, fallbackScope?: string): PaintSegment[];
32
+ /**
33
+ * The class attribute for a segment.
34
+ *
35
+ * Order matters for a stylesheet author's sanity rather than for the cascade: the
36
+ * scope comes first so a rule can target `scope + mark` if it ever needs to.
37
+ * @param segment - the segment.
38
+ * @param scopeClass - how a scope becomes a class.
39
+ * @param decorationClass - how a decoration kind becomes a class.
40
+ * @param severityClass - how a severity becomes a class.
41
+ * @returns the class list.
42
+ */
43
+ export declare function segmentClasses(segment: PaintSegment, scopeClass: (scope: string) => string, decorationClass: (kind: string) => string, severityClass: (severity: string) => string): string[];
44
+ //# sourceMappingURL=segments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../../src/core/segments.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEzE,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,2DAA2D;IAC3D,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC9B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;IACxB,WAAW,EAAE,SAAS,UAAU,EAAE,CAAA;IAClC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAA;CACnC;AAWD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,YAAY,EACnB,aAAa,SAAS,GACrB,YAAY,EAAE,CAoDhB;AA6CD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACrC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EACzC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAC1C,MAAM,EAAE,CAKV"}
@@ -0,0 +1,113 @@
1
+ import type { LineInfo, Range, Token, WordInfo } from './types.js';
2
+ /** Keeps a number inside a range, which every caller here needs and none should repeat. */
3
+ export declare function clamp(value: number, low: number, high: number): number;
4
+ /** Whether a value is a usable offset: a finite, non-negative integer. */
5
+ export declare function isOffset(value: unknown): value is number;
6
+ /**
7
+ * The offset each line starts at, in order. The first entry is always `0`.
8
+ *
9
+ * `\r\n`, `\n`, and a lone `\r` all end a line, because this text is typed by
10
+ * hand into a textarea and a paste from a Windows editor must not read as one
11
+ * long line. The terminator itself belongs to no line: a line's text excludes it
12
+ * so that column arithmetic never has to reason about a stray carriage return.
13
+ * @param source - the document.
14
+ * @returns one offset per line, ascending.
15
+ */
16
+ export declare function lineStarts(source: string): number[];
17
+ /**
18
+ * The index of the line an offset falls on.
19
+ * @param starts - the result of {@link lineStarts}.
20
+ * @param offset - a character offset.
21
+ * @returns a zero-based line index.
22
+ */
23
+ export declare function lineIndexAt(starts: readonly number[], offset: number): number;
24
+ /**
25
+ * The line an offset falls on, with the offset expressed inside it.
26
+ *
27
+ * `before` and `after` are the line's own text split at the caret, which is what
28
+ * completion and the indentation rules actually want; handing them out here
29
+ * means neither has to re-derive the split and get it subtly different.
30
+ * @param source - the document.
31
+ * @param offset - a character offset; clamped into the document.
32
+ * @param starts - the result of {@link lineStarts}, when the caller already has it.
33
+ * @returns the line, its bounds, and the caret's place in it.
34
+ */
35
+ export declare function lineAt(source: string, offset: number, starts?: readonly number[]): LineInfo;
36
+ /**
37
+ * Whether a character is part of a word.
38
+ *
39
+ * The predicate is supplied by the grammar because it decides three things at
40
+ * once — what a completion replaces, what a diagnostic underlines, and where a
41
+ * double click puts the selection — and a language whose names contain a hyphen
42
+ * must say so or every completion will replace one segment of a name instead of
43
+ * the name.
44
+ * @param char - one character, or the empty string at the end of the document.
45
+ * @param wordChars - a single-character test.
46
+ * @returns whether the character continues a word.
47
+ */
48
+ export declare function isWordChar(char: string, wordChars: RegExp): boolean;
49
+ /**
50
+ * The word at an offset.
51
+ *
52
+ * The word is found by expanding in BOTH directions from the offset rather than
53
+ * by requiring the offset to be strictly inside a word. Completion needs the
54
+ * second reading: a caret sitting at `Geist|` is at the end of the word, and the
55
+ * word it is completing is still `Geist` — a lookup that insisted the offset be
56
+ * interior would find nothing at exactly the moment the user wants a list.
57
+ * @param source - the document.
58
+ * @param offset - a character offset; clamped into the document.
59
+ * @param wordChars - a single-character test.
60
+ * @returns the word, its range, and the text either side of the caret.
61
+ */
62
+ export declare function wordInfoAt(source: string, offset: number, wordChars: RegExp): WordInfo;
63
+ /** Whether a range is empty. */
64
+ export declare function isEmptyRange(range: Range): boolean;
65
+ /** Whether an offset lies inside a range, with `to` exclusive. */
66
+ export declare function containsOffset(range: Range, offset: number): boolean;
67
+ /**
68
+ * The token covering an offset.
69
+ *
70
+ * Zero-length tokens are skipped, so a caret at a boundary resolves to the token
71
+ * it is *inside* rather than to an empty marker sitting on the seam.
72
+ * @param tokens - the scanned tokens, ascending.
73
+ * @param offset - a character offset.
74
+ * @returns the covering token, or undefined in whitespace.
75
+ */
76
+ export declare function tokenAt(tokens: readonly Token[], offset: number): Token | undefined;
77
+ /**
78
+ * The scope painted at an offset, when there is one.
79
+ * @param tokens - the scanned tokens, ascending.
80
+ * @param offset - a character offset.
81
+ * @returns the scope, or undefined in whitespace.
82
+ */
83
+ export declare function scopeAt(tokens: readonly Token[], offset: number): string | undefined;
84
+ /**
85
+ * The nearest token that ends at or before an offset, skipping whitespace.
86
+ *
87
+ * Whitespace is skipped because every caller is asking a question about
88
+ * structure — "which slot is this word in?" — and a space is never an answer.
89
+ * @param tokens - the scanned tokens, ascending.
90
+ * @param offset - a character offset.
91
+ * @returns the token, or undefined at the start of the document.
92
+ */
93
+ export declare function tokenBefore(tokens: readonly Token[], offset: number): Token | undefined;
94
+ /**
95
+ * The nearest token that starts at or after an offset, skipping whitespace.
96
+ * @param tokens - the scanned tokens, ascending.
97
+ * @param offset - a character offset.
98
+ * @returns the token, or undefined at the end of the document.
99
+ */
100
+ export declare function tokenAfter(tokens: readonly Token[], offset: number): Token | undefined;
101
+ /**
102
+ * The non-whitespace tokens on one line, in order.
103
+ *
104
+ * Completion and diagnostics both ask "what is on this line so far", and both
105
+ * must ignore the indentation and the gaps between words. Returning the tokens
106
+ * rather than the words means a grammar can ask what they *were* (their scopes)
107
+ * and not only what they said.
108
+ * @param tokens - the scanned tokens, ascending.
109
+ * @param line - a line number, or a line record.
110
+ * @returns the tokens on that line.
111
+ */
112
+ export declare function tokensOnLine(tokens: readonly Token[], line: number | LineInfo): Token[];
113
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/core/text.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAElE,2FAA2F;AAC3F,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAYnD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAS7E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAyB3F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,CAetF;AAED,gCAAgC;AAChC,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAElD;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpE;AAID;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAMnF;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAOvF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAMtF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,IAAI,EAAE,MAAM,GAAG,QAAQ,GACtB,KAAK,EAAE,CAGT"}