@singapore-editor/find 0.1.1
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.
- package/README.md +28 -0
- package/dist/findController.d.ts +175 -0
- package/dist/findController.d.ts.map +1 -0
- package/dist/findController.js +681 -0
- package/dist/findController.js.map +1 -0
- package/dist/findIcons.d.ts +49 -0
- package/dist/findIcons.d.ts.map +1 -0
- package/dist/findIcons.js +65 -0
- package/dist/findIcons.js.map +1 -0
- package/dist/findWidget.d.ts +45 -0
- package/dist/findWidget.d.ts.map +1 -0
- package/dist/findWidget.js +194 -0
- package/dist/findWidget.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/plugin.d.ts +14 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +408 -0
- package/dist/plugin.js.map +1 -0
- package/dist/replacePattern.d.ts +18 -0
- package/dist/replacePattern.d.ts.map +1 -0
- package/dist/replacePattern.js +212 -0
- package/dist/replacePattern.js.map +1 -0
- package/dist/search.d.ts +83 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +470 -0
- package/dist/search.js.map +1 -0
- package/dist/style.css +198 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
//#region src/replacePattern.ts
|
|
2
|
+
var ReplacePattern = class ReplacePattern {
|
|
3
|
+
pieces;
|
|
4
|
+
static fromStaticValue(value) {
|
|
5
|
+
return new ReplacePattern([{
|
|
6
|
+
kind: "static",
|
|
7
|
+
value
|
|
8
|
+
}]);
|
|
9
|
+
}
|
|
10
|
+
hasReplacementPatterns;
|
|
11
|
+
constructor(pieces) {
|
|
12
|
+
this.pieces = pieces;
|
|
13
|
+
this.hasReplacementPatterns = pieces.some((piece) => piece.kind !== "static");
|
|
14
|
+
}
|
|
15
|
+
buildReplaceString(matches, preserveCase = false) {
|
|
16
|
+
if (!this.hasReplacementPatterns) {
|
|
17
|
+
const value = this.pieces[0]?.kind === "static" ? this.pieces[0].value : "";
|
|
18
|
+
return preserveCase ? buildReplaceStringWithCasePreserved(matches, value) : value;
|
|
19
|
+
}
|
|
20
|
+
let result = "";
|
|
21
|
+
for (const piece of this.pieces) result += replacePieceValue(piece, matches);
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function parseReplaceString(replaceString) {
|
|
26
|
+
if (replaceString.length === 0) return new ReplacePattern([]);
|
|
27
|
+
const builder = new ReplacePieceBuilder(replaceString);
|
|
28
|
+
const caseOps = [];
|
|
29
|
+
for (let index = 0; index < replaceString.length; index += 1) {
|
|
30
|
+
const nextIndex = consumeReplaceEscape(replaceString, index, builder, caseOps);
|
|
31
|
+
if (nextIndex !== index) {
|
|
32
|
+
index = nextIndex;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
index = consumeReplaceDollar(replaceString, index, builder, caseOps);
|
|
36
|
+
}
|
|
37
|
+
return builder.finalize();
|
|
38
|
+
}
|
|
39
|
+
function buildReplaceStringWithCasePreserved(matches, pattern) {
|
|
40
|
+
const match = matches?.[0];
|
|
41
|
+
if (!match) return pattern;
|
|
42
|
+
const hyphenated = validateSpecificSpecialCharacter(match, pattern, "-");
|
|
43
|
+
const underscored = validateSpecificSpecialCharacter(match, pattern, "_");
|
|
44
|
+
if (hyphenated && !underscored) return buildReplaceStringForSpecialCharacter(match, pattern, "-");
|
|
45
|
+
if (!hyphenated && underscored) return buildReplaceStringForSpecialCharacter(match, pattern, "_");
|
|
46
|
+
if (match.toLocaleUpperCase() === match) return pattern.toLocaleUpperCase();
|
|
47
|
+
if (match.toLocaleLowerCase() === match) return pattern.toLocaleLowerCase();
|
|
48
|
+
if (startsWithUppercase(match) && pattern.length > 0) return upperFirst(pattern);
|
|
49
|
+
if (!startsWithUppercase(match) && pattern.length > 0) return lowerFirst(pattern);
|
|
50
|
+
return pattern;
|
|
51
|
+
}
|
|
52
|
+
var ReplacePieceBuilder = class {
|
|
53
|
+
source;
|
|
54
|
+
pieces = [];
|
|
55
|
+
lastIndex = 0;
|
|
56
|
+
staticValue = "";
|
|
57
|
+
constructor(source) {
|
|
58
|
+
this.source = source;
|
|
59
|
+
}
|
|
60
|
+
emitUnchanged(toIndex) {
|
|
61
|
+
this.appendStatic(this.source.slice(this.lastIndex, toIndex));
|
|
62
|
+
this.lastIndex = toIndex;
|
|
63
|
+
}
|
|
64
|
+
emitStatic(value, toIndex) {
|
|
65
|
+
this.appendStatic(value);
|
|
66
|
+
this.lastIndex = toIndex;
|
|
67
|
+
}
|
|
68
|
+
emitMatch(index, toIndex, caseOps) {
|
|
69
|
+
this.flushStatic();
|
|
70
|
+
this.pieces.push({
|
|
71
|
+
kind: "match",
|
|
72
|
+
index,
|
|
73
|
+
caseOps: [...caseOps]
|
|
74
|
+
});
|
|
75
|
+
this.lastIndex = toIndex;
|
|
76
|
+
}
|
|
77
|
+
finalize() {
|
|
78
|
+
this.emitUnchanged(this.source.length);
|
|
79
|
+
this.flushStatic();
|
|
80
|
+
return new ReplacePattern(this.pieces);
|
|
81
|
+
}
|
|
82
|
+
appendStatic(value) {
|
|
83
|
+
if (value.length === 0) return;
|
|
84
|
+
this.staticValue += value;
|
|
85
|
+
}
|
|
86
|
+
flushStatic() {
|
|
87
|
+
if (this.staticValue.length === 0) return;
|
|
88
|
+
this.pieces.push({
|
|
89
|
+
kind: "static",
|
|
90
|
+
value: this.staticValue
|
|
91
|
+
});
|
|
92
|
+
this.staticValue = "";
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
function consumeReplaceEscape(source, index, builder, caseOps) {
|
|
96
|
+
if (source[index] !== "\\") return index;
|
|
97
|
+
if (index + 1 >= source.length) return index;
|
|
98
|
+
const next = source[index + 1];
|
|
99
|
+
const staticValue = escapeStaticValue(next);
|
|
100
|
+
if (staticValue !== null) {
|
|
101
|
+
builder.emitUnchanged(index);
|
|
102
|
+
builder.emitStatic(staticValue, index + 2);
|
|
103
|
+
return index + 1;
|
|
104
|
+
}
|
|
105
|
+
if (!isCaseOperation(next)) return index + 1;
|
|
106
|
+
builder.emitUnchanged(index);
|
|
107
|
+
builder.emitStatic("", index + 2);
|
|
108
|
+
caseOps.push(next);
|
|
109
|
+
return index + 1;
|
|
110
|
+
}
|
|
111
|
+
function consumeReplaceDollar(source, index, builder, caseOps) {
|
|
112
|
+
if (source[index] !== "$") return index;
|
|
113
|
+
if (index + 1 >= source.length) return index;
|
|
114
|
+
const next = source[index + 1];
|
|
115
|
+
if (next === "$") {
|
|
116
|
+
builder.emitUnchanged(index);
|
|
117
|
+
builder.emitStatic("$", index + 2);
|
|
118
|
+
return index + 1;
|
|
119
|
+
}
|
|
120
|
+
if (next === "&" || next === "0") {
|
|
121
|
+
builder.emitUnchanged(index);
|
|
122
|
+
builder.emitMatch(0, index + 2, caseOps);
|
|
123
|
+
caseOps.length = 0;
|
|
124
|
+
return index + 1;
|
|
125
|
+
}
|
|
126
|
+
return consumeReplaceCapture(source, index, builder, caseOps);
|
|
127
|
+
}
|
|
128
|
+
function consumeReplaceCapture(source, index, builder, caseOps) {
|
|
129
|
+
const first = source[index + 1];
|
|
130
|
+
if (!isNonZeroDigit(first)) return index;
|
|
131
|
+
const second = source[index + 2];
|
|
132
|
+
const hasSecondDigit = second !== void 0 && isDigit(second);
|
|
133
|
+
const capture = hasSecondDigit ? Number(`${first}${second}`) : Number(first);
|
|
134
|
+
const end = hasSecondDigit ? index + 3 : index + 2;
|
|
135
|
+
builder.emitUnchanged(index);
|
|
136
|
+
builder.emitMatch(capture, end, caseOps);
|
|
137
|
+
caseOps.length = 0;
|
|
138
|
+
return end - 1;
|
|
139
|
+
}
|
|
140
|
+
function replacePieceValue(piece, matches) {
|
|
141
|
+
if (piece.kind === "static") return piece.value;
|
|
142
|
+
return applyCaseOperations(substituteMatch(piece.index, matches), piece.caseOps);
|
|
143
|
+
}
|
|
144
|
+
function substituteMatch(index, matches) {
|
|
145
|
+
if (!matches) return "";
|
|
146
|
+
if (index === 0) return matches[0] ?? "";
|
|
147
|
+
let captureIndex = index;
|
|
148
|
+
let remainder = "";
|
|
149
|
+
while (captureIndex > 0) {
|
|
150
|
+
if (captureIndex < matches.length) return `${matches[captureIndex] ?? ""}${remainder}`;
|
|
151
|
+
remainder = `${captureIndex % 10}${remainder}`;
|
|
152
|
+
captureIndex = Math.floor(captureIndex / 10);
|
|
153
|
+
}
|
|
154
|
+
return `$${remainder}`;
|
|
155
|
+
}
|
|
156
|
+
function applyCaseOperations(value, caseOps) {
|
|
157
|
+
if (caseOps.length === 0) return value;
|
|
158
|
+
let opIndex = 0;
|
|
159
|
+
let result = "";
|
|
160
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
161
|
+
const op = caseOps[opIndex];
|
|
162
|
+
if (!op) {
|
|
163
|
+
result += value.slice(index);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
result += applyCaseOperation(value[index], op);
|
|
167
|
+
if (op === "u" || op === "l") opIndex += 1;
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
function escapeStaticValue(value) {
|
|
172
|
+
if (value === "\\") return "\\";
|
|
173
|
+
if (value === "n") return "\n";
|
|
174
|
+
if (value === "t") return " ";
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
function isCaseOperation(value) {
|
|
178
|
+
return value === "u" || value === "U" || value === "l" || value === "L";
|
|
179
|
+
}
|
|
180
|
+
function applyCaseOperation(value, operation) {
|
|
181
|
+
if (operation === "u" || operation === "U") return value.toLocaleUpperCase();
|
|
182
|
+
if (operation === "l" || operation === "L") return value.toLocaleLowerCase();
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
function validateSpecificSpecialCharacter(match, pattern, separator) {
|
|
186
|
+
if (!match.includes(separator) || !pattern.includes(separator)) return false;
|
|
187
|
+
return match.split(separator).length === pattern.split(separator).length;
|
|
188
|
+
}
|
|
189
|
+
function buildReplaceStringForSpecialCharacter(match, pattern, separator) {
|
|
190
|
+
const matchParts = match.split(separator);
|
|
191
|
+
return pattern.split(separator).map((part, index) => buildReplaceStringWithCasePreserved([matchParts[index] ?? ""], part)).join(separator);
|
|
192
|
+
}
|
|
193
|
+
function startsWithUppercase(value) {
|
|
194
|
+
const first = value[0];
|
|
195
|
+
return first !== void 0 && first.toLocaleUpperCase() === first;
|
|
196
|
+
}
|
|
197
|
+
function upperFirst(value) {
|
|
198
|
+
return `${value[0].toLocaleUpperCase()}${value.slice(1)}`;
|
|
199
|
+
}
|
|
200
|
+
function lowerFirst(value) {
|
|
201
|
+
return `${value[0].toLocaleLowerCase()}${value.slice(1)}`;
|
|
202
|
+
}
|
|
203
|
+
function isDigit(value) {
|
|
204
|
+
return value >= "0" && value <= "9";
|
|
205
|
+
}
|
|
206
|
+
function isNonZeroDigit(value) {
|
|
207
|
+
return value >= "1" && value <= "9";
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
export { ReplacePattern, parseReplaceString };
|
|
211
|
+
|
|
212
|
+
//# sourceMappingURL=replacePattern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replacePattern.js","names":[],"sources":["../src/replacePattern.ts"],"sourcesContent":["export class ReplacePattern {\n public static fromStaticValue(value: string): ReplacePattern {\n return new ReplacePattern([{ kind: 'static', value }])\n }\n\n public readonly hasReplacementPatterns: boolean\n\n public constructor(private readonly pieces: readonly ReplacePiece[]) {\n this.hasReplacementPatterns = pieces.some((piece) => piece.kind !== 'static')\n }\n\n public buildReplaceString(matches: readonly string[] | null, preserveCase = false): string {\n if (!this.hasReplacementPatterns) {\n const value = this.pieces[0]?.kind === 'static' ? this.pieces[0].value : ''\n return preserveCase ? buildReplaceStringWithCasePreserved(matches, value) : value\n }\n\n let result = ''\n for (const piece of this.pieces) {\n result += replacePieceValue(piece, matches)\n }\n return result\n }\n}\n\ntype ReplacePiece =\n | { readonly kind: 'static'; readonly value: string }\n | { readonly kind: 'match'; readonly index: number; readonly caseOps: readonly string[] }\n\nexport function parseReplaceString(replaceString: string): ReplacePattern {\n if (replaceString.length === 0) return new ReplacePattern([])\n\n const builder = new ReplacePieceBuilder(replaceString)\n const caseOps: string[] = []\n for (let index = 0; index < replaceString.length; index += 1) {\n const nextIndex = consumeReplaceEscape(replaceString, index, builder, caseOps)\n if (nextIndex !== index) {\n index = nextIndex\n continue\n }\n\n index = consumeReplaceDollar(replaceString, index, builder, caseOps)\n }\n\n return builder.finalize()\n}\n\nfunction buildReplaceStringWithCasePreserved(\n matches: readonly string[] | null,\n pattern: string,\n): string {\n const match = matches?.[0]\n if (!match) return pattern\n\n const hyphenated = validateSpecificSpecialCharacter(match, pattern, '-')\n const underscored = validateSpecificSpecialCharacter(match, pattern, '_')\n if (hyphenated && !underscored) return buildReplaceStringForSpecialCharacter(match, pattern, '-')\n if (!hyphenated && underscored) return buildReplaceStringForSpecialCharacter(match, pattern, '_')\n if (match.toLocaleUpperCase() === match) return pattern.toLocaleUpperCase()\n if (match.toLocaleLowerCase() === match) return pattern.toLocaleLowerCase()\n if (startsWithUppercase(match) && pattern.length > 0) return upperFirst(pattern)\n if (!startsWithUppercase(match) && pattern.length > 0) return lowerFirst(pattern)\n return pattern\n}\n\nclass ReplacePieceBuilder {\n private readonly pieces: ReplacePiece[] = []\n private lastIndex = 0\n private staticValue = ''\n\n public constructor(private readonly source: string) {}\n\n public emitUnchanged(toIndex: number): void {\n this.appendStatic(this.source.slice(this.lastIndex, toIndex))\n this.lastIndex = toIndex\n }\n\n public emitStatic(value: string, toIndex: number): void {\n this.appendStatic(value)\n this.lastIndex = toIndex\n }\n\n public emitMatch(index: number, toIndex: number, caseOps: readonly string[]): void {\n this.flushStatic()\n this.pieces.push({ kind: 'match', index, caseOps: [...caseOps] })\n this.lastIndex = toIndex\n }\n\n public finalize(): ReplacePattern {\n this.emitUnchanged(this.source.length)\n this.flushStatic()\n return new ReplacePattern(this.pieces)\n }\n\n private appendStatic(value: string): void {\n if (value.length === 0) return\n this.staticValue += value\n }\n\n private flushStatic(): void {\n if (this.staticValue.length === 0) return\n\n this.pieces.push({ kind: 'static', value: this.staticValue })\n this.staticValue = ''\n }\n}\n\nfunction consumeReplaceEscape(\n source: string,\n index: number,\n builder: ReplacePieceBuilder,\n caseOps: string[],\n): number {\n if (source[index] !== '\\\\') return index\n if (index + 1 >= source.length) return index\n\n const next = source[index + 1]!\n const staticValue = escapeStaticValue(next)\n if (staticValue !== null) {\n builder.emitUnchanged(index)\n builder.emitStatic(staticValue, index + 2)\n return index + 1\n }\n\n // An unrecognized escape still swallows the escaped character, so `\\$1` stays literal\n // instead of the '$' being re-read as a capture reference by consumeReplaceDollar.\n if (!isCaseOperation(next)) return index + 1\n\n builder.emitUnchanged(index)\n builder.emitStatic('', index + 2)\n caseOps.push(next)\n return index + 1\n}\n\nfunction consumeReplaceDollar(\n source: string,\n index: number,\n builder: ReplacePieceBuilder,\n caseOps: string[],\n): number {\n if (source[index] !== '$') return index\n if (index + 1 >= source.length) return index\n\n const next = source[index + 1]!\n if (next === '$') {\n builder.emitUnchanged(index)\n builder.emitStatic('$', index + 2)\n return index + 1\n }\n\n if (next === '&' || next === '0') {\n builder.emitUnchanged(index)\n builder.emitMatch(0, index + 2, caseOps)\n caseOps.length = 0\n return index + 1\n }\n\n return consumeReplaceCapture(source, index, builder, caseOps)\n}\n\nfunction consumeReplaceCapture(\n source: string,\n index: number,\n builder: ReplacePieceBuilder,\n caseOps: string[],\n): number {\n const first = source[index + 1]!\n if (!isNonZeroDigit(first)) return index\n\n const second = source[index + 2]\n const hasSecondDigit = second !== undefined && isDigit(second)\n const capture = hasSecondDigit ? Number(`${first}${second}`) : Number(first)\n const end = hasSecondDigit ? index + 3 : index + 2\n builder.emitUnchanged(index)\n builder.emitMatch(capture, end, caseOps)\n caseOps.length = 0\n return end - 1\n}\n\nfunction replacePieceValue(piece: ReplacePiece, matches: readonly string[] | null): string {\n if (piece.kind === 'static') return piece.value\n\n const value = substituteMatch(piece.index, matches)\n return applyCaseOperations(value, piece.caseOps)\n}\n\nfunction substituteMatch(index: number, matches: readonly string[] | null): string {\n if (!matches) return ''\n if (index === 0) return matches[0] ?? ''\n\n // An out-of-range index degrades digit by digit, the way JavaScript's own String.replace\n // does: with a single capture group `$12` is group 1 followed by a literal '2', and only a\n // first digit that is also out of range falls back to the literal `$…`.\n let captureIndex = index\n let remainder = ''\n while (captureIndex > 0) {\n if (captureIndex < matches.length) return `${matches[captureIndex] ?? ''}${remainder}`\n\n remainder = `${captureIndex % 10}${remainder}`\n captureIndex = Math.floor(captureIndex / 10)\n }\n return `$${remainder}`\n}\n\nfunction applyCaseOperations(value: string, caseOps: readonly string[]): string {\n if (caseOps.length === 0) return value\n\n let opIndex = 0\n let result = ''\n for (let index = 0; index < value.length; index += 1) {\n const op = caseOps[opIndex]\n if (!op) {\n result += value.slice(index)\n break\n }\n\n result += applyCaseOperation(value[index]!, op)\n if (op === 'u' || op === 'l') opIndex += 1\n }\n return result\n}\n\nfunction escapeStaticValue(value: string): string | null {\n if (value === '\\\\') return '\\\\'\n if (value === 'n') return '\\n'\n if (value === 't') return '\\t'\n return null\n}\n\nfunction isCaseOperation(value: string): boolean {\n return value === 'u' || value === 'U' || value === 'l' || value === 'L'\n}\n\nfunction applyCaseOperation(value: string, operation: string): string {\n if (operation === 'u' || operation === 'U') return value.toLocaleUpperCase()\n if (operation === 'l' || operation === 'L') return value.toLocaleLowerCase()\n return value\n}\n\nfunction validateSpecificSpecialCharacter(\n match: string,\n pattern: string,\n separator: string,\n): boolean {\n if (!match.includes(separator) || !pattern.includes(separator)) return false\n return match.split(separator).length === pattern.split(separator).length\n}\n\nfunction buildReplaceStringForSpecialCharacter(\n match: string,\n pattern: string,\n separator: string,\n): string {\n const matchParts = match.split(separator)\n return pattern\n .split(separator)\n .map((part, index) => buildReplaceStringWithCasePreserved([matchParts[index] ?? ''], part))\n .join(separator)\n}\n\nfunction startsWithUppercase(value: string): boolean {\n const first = value[0]\n return first !== undefined && first.toLocaleUpperCase() === first\n}\n\nfunction upperFirst(value: string): string {\n return `${value[0]!.toLocaleUpperCase()}${value.slice(1)}`\n}\n\nfunction lowerFirst(value: string): string {\n return `${value[0]!.toLocaleLowerCase()}${value.slice(1)}`\n}\n\nfunction isDigit(value: string): boolean {\n return value >= '0' && value <= '9'\n}\n\nfunction isNonZeroDigit(value: string): boolean {\n return value >= '1' && value <= '9'\n}\n"],"mappings":"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"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { type TextOffsetRange, type TextReadSnapshot } from '@singapore-editor/core/document';
|
|
2
|
+
export declare const FIND_MATCHES_LIMIT = 19999;
|
|
3
|
+
export declare const FIND_REPLACE_ALL_LIMIT = 1073741824;
|
|
4
|
+
export declare const FIND_WINDOW_UNITS = 65536;
|
|
5
|
+
export type FindRange = TextOffsetRange;
|
|
6
|
+
export type FindLineStartsView = {
|
|
7
|
+
readonly length: number;
|
|
8
|
+
at(index: number): number | undefined;
|
|
9
|
+
indexForOffset(offset: number): number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The text a search reads, in ranges rather than as one string.
|
|
13
|
+
*
|
|
14
|
+
* A query that cannot match a line break is answered a line at a time, so a
|
|
15
|
+
* keystroke in the find box costs the lines examined instead of a copy of the
|
|
16
|
+
* whole document — and a chunked buffer gets searched where it lies.
|
|
17
|
+
*/
|
|
18
|
+
export type FindTextSource = {
|
|
19
|
+
readonly length: number;
|
|
20
|
+
readRange(start: number, end: number): string;
|
|
21
|
+
readonly lineStartsView: FindLineStartsView;
|
|
22
|
+
};
|
|
23
|
+
export declare function findTextSourceFromSnapshot(snapshot: TextReadSnapshot): FindTextSource;
|
|
24
|
+
export type FindQuery = {
|
|
25
|
+
readonly searchString: string;
|
|
26
|
+
readonly isRegex: boolean;
|
|
27
|
+
readonly matchCase: boolean;
|
|
28
|
+
readonly wholeWord: boolean;
|
|
29
|
+
};
|
|
30
|
+
export type FindMatch = FindRange & {
|
|
31
|
+
readonly matches: readonly string[] | null;
|
|
32
|
+
};
|
|
33
|
+
export type FindMatchFromOptions = {
|
|
34
|
+
readonly captureMatches?: boolean;
|
|
35
|
+
readonly loop?: boolean;
|
|
36
|
+
readonly escapeEmptyMatchAtOffset?: boolean;
|
|
37
|
+
};
|
|
38
|
+
/** What the two directions have in common, so one caller can hold either. */
|
|
39
|
+
export type FindMatchFromSearcher = (source: FindTextSource, query: FindQuery, offset: number, ranges: readonly FindRange[] | null, options: FindMatchFromOptions) => FindMatch | null;
|
|
40
|
+
/**
|
|
41
|
+
* How much text one match can depend on, which is what decides how it is read.
|
|
42
|
+
*
|
|
43
|
+
* `lines` and `anchored-lines` cannot match a break, so they are read in windows
|
|
44
|
+
* of whole lines. `literal-lines` is a literal holding breaks: it spans a known
|
|
45
|
+
* number of lines, so it is windowed too. `range` is every pattern nothing here
|
|
46
|
+
* can bound, read as one window because that is the only reading always correct.
|
|
47
|
+
*/
|
|
48
|
+
export type FindQueryPlan = {
|
|
49
|
+
readonly kind: 'lines';
|
|
50
|
+
} | {
|
|
51
|
+
readonly kind: 'anchored-lines';
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: 'literal-lines';
|
|
54
|
+
readonly lineBreaks: number;
|
|
55
|
+
} | {
|
|
56
|
+
readonly kind: 'range';
|
|
57
|
+
readonly reason: 'pattern-may-match-line-break';
|
|
58
|
+
};
|
|
59
|
+
export declare function findMatches(source: FindTextSource, query: FindQuery, ranges?: readonly FindRange[] | null, captureMatches?: boolean, limit?: number): readonly FindMatch[];
|
|
60
|
+
/**
|
|
61
|
+
* Every match counted, none kept: a total costs no record per match.
|
|
62
|
+
*
|
|
63
|
+
* With `before`, only the matches starting in front of that offset, which is the
|
|
64
|
+
* position of a match the listing stopped short of.
|
|
65
|
+
*/
|
|
66
|
+
export declare function countMatches(source: FindTextSource, query: FindQuery, ranges?: readonly FindRange[] | null, before?: number): number;
|
|
67
|
+
/** Null for a query that cannot be compiled, which is one that finds nothing. */
|
|
68
|
+
export declare function findQueryPlan(query: FindQuery): FindQueryPlan | null;
|
|
69
|
+
/** The line holding `offset`, break excluded. */
|
|
70
|
+
export declare function findLineRange(source: FindTextSource, offset: number): FindRange;
|
|
71
|
+
/**
|
|
72
|
+
* One match, scanned for from an offset instead of picked out of a list.
|
|
73
|
+
*
|
|
74
|
+
* A listing stops at FIND_MATCHES_LIMIT, and past that every entry in it sits
|
|
75
|
+
* behind the cursor: picking from it answers each press with the top of the
|
|
76
|
+
* document. Scanning outward stops at the first match it reaches, so how far
|
|
77
|
+
* navigation can go is not what a paint budget allowed.
|
|
78
|
+
*/
|
|
79
|
+
export declare function findNextMatchFrom(source: FindTextSource, query: FindQuery, offset: number, ranges?: readonly FindRange[] | null, options?: FindMatchFromOptions): FindMatch | null;
|
|
80
|
+
export declare function findPreviousMatchFrom(source: FindTextSource, query: FindQuery, offset: number, ranges?: readonly FindRange[] | null, options?: FindMatchFromOptions): FindMatch | null;
|
|
81
|
+
export declare function findMatchIndex(matches: readonly FindMatch[], range: FindRange): number;
|
|
82
|
+
export declare function escapeRegExpCharacters(value: string): string;
|
|
83
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
|