clarity-pattern-parser 11.3.9 → 11.3.11
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/.yarn/install-state.gz +0 -0
- package/dist/index.browser.js +205 -120
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +205 -120
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +205 -120
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +26 -8
- package/dist/intellisense/SuggestionOption.d.ts +18 -2
- package/dist/patterns/InfiniteRepeat.d.ts +1 -0
- package/jest.config.js +2 -0
- package/jest.coverage.config.js +2 -0
- package/package.json +7 -6
- package/src/generator/delete.ts +88 -0
- package/src/generator/generator.test.ts +1 -0
- package/src/generator/generator.ts +3 -0
- package/src/generator/ivisitor.ts +1 -0
- package/src/generator/typescriptVisitor.ts +24 -3
- package/src/grammar/Grammar.test.ts +1 -0
- package/src/grammar/Grammar.ts +2 -0
- package/src/grammar/patterns.test.ts +36 -0
- package/src/grammar/spec.md +233 -84
- package/src/intellisense/AutoComplete.test.ts +629 -156
- package/src/intellisense/AutoComplete.ts +232 -109
- package/src/intellisense/SuggestionOption.ts +25 -2
- package/src/patterns/Expression.ts +4 -2
- package/src/patterns/FiniteRepeat.ts +4 -6
- package/src/patterns/InfiniteRepeat.ts +7 -1
- package/src/patterns/Literal.test.ts +1 -1
- package/src/patterns/Options.test.ts +1 -1
- package/src/patterns/PrecedenceTree.ts +31 -7
- package/src/patterns/Reference.test.ts +1 -1
- package/src/patterns/Regex.test.ts +3 -3
- package/src/patterns/Sequence.test.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -1255,12 +1255,10 @@ class FiniteRepeat {
|
|
|
1255
1255
|
}
|
|
1256
1256
|
}
|
|
1257
1257
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
cursor.moveTo(node.firstIndex);
|
|
1263
|
-
}
|
|
1258
|
+
const endedOnDivider = this._hasDivider && nodes.length % modulo === 0;
|
|
1259
|
+
if (this._trimDivider && endedOnDivider) {
|
|
1260
|
+
const node = nodes.pop();
|
|
1261
|
+
cursor.moveTo(node.firstIndex);
|
|
1264
1262
|
}
|
|
1265
1263
|
if (matchCount < this._min) {
|
|
1266
1264
|
const lastIndex = cursor.index;
|
|
@@ -1396,6 +1394,7 @@ class InfiniteRepeat {
|
|
|
1396
1394
|
this._firstIndex = 0;
|
|
1397
1395
|
this._nodes = [];
|
|
1398
1396
|
this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
|
|
1397
|
+
this._patterns = [];
|
|
1399
1398
|
}
|
|
1400
1399
|
_assignChildrenToParent(children) {
|
|
1401
1400
|
for (const child of children) {
|
|
@@ -1411,6 +1410,7 @@ class InfiniteRepeat {
|
|
|
1411
1410
|
parse(cursor) {
|
|
1412
1411
|
this._firstIndex = cursor.index;
|
|
1413
1412
|
this._nodes = [];
|
|
1413
|
+
this._patterns = [];
|
|
1414
1414
|
const passed = this._tryToParse(cursor);
|
|
1415
1415
|
if (passed) {
|
|
1416
1416
|
cursor.resolveError();
|
|
@@ -1462,6 +1462,7 @@ class InfiniteRepeat {
|
|
|
1462
1462
|
}
|
|
1463
1463
|
if (repeatNode != null) {
|
|
1464
1464
|
this._nodes.push(repeatNode);
|
|
1465
|
+
this._patterns.push(this._pattern);
|
|
1465
1466
|
if (!cursor.hasNext()) {
|
|
1466
1467
|
passed = true;
|
|
1467
1468
|
break;
|
|
@@ -1486,6 +1487,7 @@ class InfiniteRepeat {
|
|
|
1486
1487
|
}
|
|
1487
1488
|
else {
|
|
1488
1489
|
this._nodes.push(dividerNode);
|
|
1490
|
+
this._patterns.push(this._divider);
|
|
1489
1491
|
if (!cursor.hasNext()) {
|
|
1490
1492
|
passed = true;
|
|
1491
1493
|
break;
|
|
@@ -1508,11 +1510,11 @@ class InfiniteRepeat {
|
|
|
1508
1510
|
return passed;
|
|
1509
1511
|
}
|
|
1510
1512
|
_createNode(cursor) {
|
|
1511
|
-
var _a;
|
|
1512
1513
|
const hasDivider = this._divider != null;
|
|
1514
|
+
const lastPattern = this._patterns[this._patterns.length - 1];
|
|
1513
1515
|
if (hasDivider &&
|
|
1514
1516
|
this._trimDivider &&
|
|
1515
|
-
|
|
1517
|
+
lastPattern === this._divider) {
|
|
1516
1518
|
const dividerNode = this._nodes.pop();
|
|
1517
1519
|
cursor.moveTo(dividerNode.firstIndex);
|
|
1518
1520
|
}
|
|
@@ -2719,13 +2721,36 @@ class PrecedenceTree {
|
|
|
2719
2721
|
}
|
|
2720
2722
|
_compileAtomNode() {
|
|
2721
2723
|
let node = this._atomNode;
|
|
2722
|
-
if (this._prefixNode != null && this._atomNode != null) {
|
|
2723
|
-
|
|
2724
|
-
this.
|
|
2724
|
+
if (this._prefixNode != null && this._postfixNode != null && this._atomNode != null) {
|
|
2725
|
+
let firstNode = this._prefixNode;
|
|
2726
|
+
let secondNode = this._postfixNode;
|
|
2727
|
+
let firstPlaceholder = this._prefixPlaceholder;
|
|
2728
|
+
let secondPlaceholder = this._postfixPlaceholder;
|
|
2729
|
+
const prefixName = this._prefixNode.name;
|
|
2730
|
+
const postfixName = this._postfixNode.name;
|
|
2731
|
+
const prefixPrecedence = this._getPrecedence(prefixName);
|
|
2732
|
+
const postfixPrecedence = this._getPrecedence(postfixName);
|
|
2733
|
+
// The Precedence is the index of the patterns, so its lower not higher :\
|
|
2734
|
+
if (prefixPrecedence > postfixPrecedence) {
|
|
2735
|
+
firstNode = this._postfixNode;
|
|
2736
|
+
secondNode = this._prefixNode;
|
|
2737
|
+
firstPlaceholder = this._postfixPlaceholder;
|
|
2738
|
+
secondPlaceholder = this._prefixPlaceholder;
|
|
2739
|
+
}
|
|
2740
|
+
node = firstNode.findRoot();
|
|
2741
|
+
firstPlaceholder.replaceWith(this._atomNode);
|
|
2742
|
+
secondPlaceholder.replaceWith(node);
|
|
2743
|
+
node = secondNode;
|
|
2725
2744
|
}
|
|
2726
|
-
|
|
2727
|
-
this.
|
|
2728
|
-
|
|
2745
|
+
else {
|
|
2746
|
+
if (this._prefixNode != null && this._atomNode != null) {
|
|
2747
|
+
node = this._prefixNode.findRoot();
|
|
2748
|
+
this._prefixPlaceholder.replaceWith(this._atomNode);
|
|
2749
|
+
}
|
|
2750
|
+
if (this._postfixNode != null && node != null) {
|
|
2751
|
+
this._postfixPlaceholder.replaceWith(node);
|
|
2752
|
+
node = this._postfixNode;
|
|
2753
|
+
}
|
|
2729
2754
|
}
|
|
2730
2755
|
this._prefixNode = null;
|
|
2731
2756
|
this._atomNode = null;
|
|
@@ -2833,7 +2858,7 @@ class Expression {
|
|
|
2833
2858
|
}
|
|
2834
2859
|
_organizePatterns(patterns) {
|
|
2835
2860
|
const finalPatterns = [];
|
|
2836
|
-
patterns.forEach((pattern) => {
|
|
2861
|
+
patterns.forEach((pattern, index) => {
|
|
2837
2862
|
if (this._isAtom(pattern)) {
|
|
2838
2863
|
const atom = pattern.clone();
|
|
2839
2864
|
atom.parent = this;
|
|
@@ -2844,6 +2869,7 @@ class Expression {
|
|
|
2844
2869
|
const name = this._extractName(pattern);
|
|
2845
2870
|
const prefix = this._extractPrefix(pattern);
|
|
2846
2871
|
prefix.parent = this;
|
|
2872
|
+
this._precedenceMap[name] = index;
|
|
2847
2873
|
this._prefixPatterns.push(prefix);
|
|
2848
2874
|
this._prefixNames.push(name);
|
|
2849
2875
|
finalPatterns.push(prefix);
|
|
@@ -2852,6 +2878,7 @@ class Expression {
|
|
|
2852
2878
|
const name = this._extractName(pattern);
|
|
2853
2879
|
const postfix = this._extractPostfix(pattern);
|
|
2854
2880
|
postfix.parent = this;
|
|
2881
|
+
this._precedenceMap[name] = index;
|
|
2855
2882
|
this._postfixPatterns.push(postfix);
|
|
2856
2883
|
this._postfixNames.push(name);
|
|
2857
2884
|
finalPatterns.push(postfix);
|
|
@@ -2860,7 +2887,7 @@ class Expression {
|
|
|
2860
2887
|
const name = this._extractName(pattern);
|
|
2861
2888
|
const binary = this._extractBinary(pattern);
|
|
2862
2889
|
binary.parent = this;
|
|
2863
|
-
this._precedenceMap[name] =
|
|
2890
|
+
this._precedenceMap[name] = index;
|
|
2864
2891
|
this._binaryPatterns.push(binary);
|
|
2865
2892
|
this._binaryNames.push(name);
|
|
2866
2893
|
if (pattern.type === "right-associated") {
|
|
@@ -3658,6 +3685,8 @@ class Grammar {
|
|
|
3658
3685
|
return this._isRecursivePattern(name, pattern);
|
|
3659
3686
|
}
|
|
3660
3687
|
_isRecursivePattern(name, pattern) {
|
|
3688
|
+
// Because we don't know if the pattern is a sequence with a reference we have to just assume it is.
|
|
3689
|
+
// The better solution here would be to not have options at all and just use expresssion pattern instead.
|
|
3661
3690
|
if (pattern.type === "reference") {
|
|
3662
3691
|
return true;
|
|
3663
3692
|
}
|
|
@@ -4009,26 +4038,30 @@ class AutoComplete {
|
|
|
4009
4038
|
this._options = options;
|
|
4010
4039
|
this._text = "";
|
|
4011
4040
|
}
|
|
4041
|
+
suggestFor(text) {
|
|
4042
|
+
return this.suggestForWithCursor(new Cursor(text));
|
|
4043
|
+
}
|
|
4012
4044
|
suggestForWithCursor(cursor) {
|
|
4013
4045
|
cursor.moveTo(0);
|
|
4014
4046
|
this._cursor = cursor;
|
|
4015
4047
|
this._text = cursor.text;
|
|
4016
4048
|
this._cursor.startRecording();
|
|
4017
4049
|
if (cursor.length === 0) {
|
|
4018
|
-
|
|
4050
|
+
const suggestion = {
|
|
4019
4051
|
isComplete: false,
|
|
4020
|
-
options: this.
|
|
4052
|
+
options: this._createSuggestionOptionsFromMatch(),
|
|
4021
4053
|
error: new ParseError(0, 0, this._pattern),
|
|
4022
4054
|
errorAtIndex: 0,
|
|
4023
4055
|
cursor,
|
|
4024
4056
|
ast: null
|
|
4025
4057
|
};
|
|
4058
|
+
return suggestion;
|
|
4026
4059
|
}
|
|
4027
4060
|
let errorAtIndex = null;
|
|
4028
4061
|
let error = null;
|
|
4029
4062
|
const ast = this._pattern.parse(this._cursor);
|
|
4030
4063
|
const isComplete = (ast === null || ast === void 0 ? void 0 : ast.value) === this._text;
|
|
4031
|
-
const options = this.
|
|
4064
|
+
const options = this._getAllSuggestionsOptions();
|
|
4032
4065
|
if (!isComplete && options.length > 0 && !this._cursor.hasError) {
|
|
4033
4066
|
const startIndex = options.reduce((lowestIndex, o) => {
|
|
4034
4067
|
return Math.min(lowestIndex, o.startIndex);
|
|
@@ -4075,14 +4108,11 @@ class AutoComplete {
|
|
|
4075
4108
|
}
|
|
4076
4109
|
return 0;
|
|
4077
4110
|
}
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
_getAllOptions() {
|
|
4082
|
-
const errorMatches = this._getOptionsFromErrors();
|
|
4083
|
-
const leafMatches = this._cursor.leafMatches.map((m) => this._createSuggestionsFromMatch(m)).flat();
|
|
4111
|
+
_getAllSuggestionsOptions() {
|
|
4112
|
+
const errorMatchOptions = this._createSuggestionOptionsFromErrors();
|
|
4113
|
+
const leafMatchOptions = this._cursor.leafMatches.map((m) => this._createSuggestionOptionsFromMatch(m)).flat();
|
|
4084
4114
|
const finalResults = [];
|
|
4085
|
-
[...
|
|
4115
|
+
[...leafMatchOptions, ...errorMatchOptions].forEach(m => {
|
|
4086
4116
|
const index = finalResults.findIndex(f => m.text === f.text);
|
|
4087
4117
|
if (index === -1) {
|
|
4088
4118
|
finalResults.push(m);
|
|
@@ -4090,135 +4120,190 @@ class AutoComplete {
|
|
|
4090
4120
|
});
|
|
4091
4121
|
return finalResults;
|
|
4092
4122
|
}
|
|
4093
|
-
|
|
4123
|
+
_createSuggestionOptionsFromErrors() {
|
|
4094
4124
|
// These errored because the length of the string.
|
|
4095
4125
|
const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length);
|
|
4096
|
-
const
|
|
4097
|
-
const
|
|
4098
|
-
const
|
|
4099
|
-
const
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
const suggestions = [];
|
|
4118
|
-
const tokens = [...this._pattern.getTokens(), ...this._getTokensForPattern(this._pattern)];
|
|
4119
|
-
for (const token of tokens) {
|
|
4120
|
-
if (suggestions.findIndex(s => s.text === token) === -1) {
|
|
4121
|
-
suggestions.push(this._createSuggestion("", token));
|
|
4122
|
-
}
|
|
4123
|
-
}
|
|
4124
|
-
return suggestions;
|
|
4125
|
-
}
|
|
4126
|
-
_createSuggestionsFromMatch(match) {
|
|
4127
|
-
if (match.pattern == null) {
|
|
4128
|
-
return this._createSuggestions(-1, this._getTokensForPattern(this._pattern));
|
|
4129
|
-
}
|
|
4130
|
-
if (match.node != null) {
|
|
4131
|
-
const textStartingMatch = this._text.slice(match.node.startIndex, match.node.endIndex);
|
|
4132
|
-
const currentPatternsTokens = this._getTokensForPattern(match.pattern);
|
|
4133
|
-
/**
|
|
4134
|
-
* Compares tokens to current text and extracts remainder tokens
|
|
4135
|
-
* - IE. **currentText:** *abc*, **baseToken:** *abcdef*, **trailingToken:** *def*
|
|
4136
|
-
*/
|
|
4137
|
-
const trailingTokens = currentPatternsTokens.reduce((acc, token) => {
|
|
4138
|
-
if (token.startsWith(textStartingMatch)) {
|
|
4139
|
-
const sliced = token.slice(textStartingMatch.length);
|
|
4140
|
-
if (sliced !== '') {
|
|
4141
|
-
acc.push(sliced);
|
|
4142
|
-
}
|
|
4143
|
-
}
|
|
4144
|
-
return acc;
|
|
4145
|
-
}, []);
|
|
4126
|
+
const errorSuggestionOptions = errors.map(parseError => {
|
|
4127
|
+
const currentText = this._cursor.getChars(parseError.startIndex, parseError.lastIndex);
|
|
4128
|
+
const compositeSuggestions = this._getCompositeSuggestionsForPattern(parseError.pattern);
|
|
4129
|
+
const trimmedErrorCompositeSuggestions = this._trimSuggestionsByExistingText(currentText, compositeSuggestions);
|
|
4130
|
+
return this._createSuggestions(parseError.lastIndex, trimmedErrorCompositeSuggestions);
|
|
4131
|
+
}).flat();
|
|
4132
|
+
const dedupedErrorSuggestionOptions = this._deDupeCompositeSuggestions(errorSuggestionOptions);
|
|
4133
|
+
return dedupedErrorSuggestionOptions;
|
|
4134
|
+
}
|
|
4135
|
+
_createSuggestionOptionsFromMatch(match) {
|
|
4136
|
+
if ((match === null || match === void 0 ? void 0 : match.pattern) == null) {
|
|
4137
|
+
const compositeSuggestions = this._getCompositeSuggestionsForPattern(this._pattern);
|
|
4138
|
+
return this._createSuggestions(-1, compositeSuggestions);
|
|
4139
|
+
}
|
|
4140
|
+
if ((match === null || match === void 0 ? void 0 : match.node) != null) {
|
|
4141
|
+
const currentText = this._text.slice(match.node.startIndex, match.node.endIndex);
|
|
4142
|
+
/**Captures suggestions for a "completed" match pattern that still has existing possible suggestions.
|
|
4143
|
+
* particularly relevant when working with set/custom tokens.
|
|
4144
|
+
*/
|
|
4145
|
+
const matchCompositeSuggestions = this._getCompositeSuggestionsForPattern(match.pattern);
|
|
4146
|
+
const trimmedMatchCompositeSuggestions = this._trimSuggestionsByExistingText(currentText, matchCompositeSuggestions);
|
|
4146
4147
|
const leafPatterns = match.pattern.getNextPatterns();
|
|
4147
|
-
const
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
const allTokens = [...trailingTokens, ...leafTokens];
|
|
4152
|
-
return this._createSuggestions(match.node.lastIndex, allTokens);
|
|
4148
|
+
const leafCompositeSuggestions = leafPatterns.flatMap(leafPattern => this._getCompositeSuggestionsForPattern(leafPattern));
|
|
4149
|
+
const allCompositeSuggestions = [...leafCompositeSuggestions, ...trimmedMatchCompositeSuggestions,];
|
|
4150
|
+
const dedupedCompositeSuggestions = this._deDupeCompositeSuggestions(allCompositeSuggestions);
|
|
4151
|
+
return this._createSuggestions(match.node.lastIndex, dedupedCompositeSuggestions);
|
|
4153
4152
|
}
|
|
4154
4153
|
else {
|
|
4155
4154
|
return [];
|
|
4156
4155
|
}
|
|
4157
4156
|
}
|
|
4158
|
-
|
|
4159
|
-
|
|
4157
|
+
/**
|
|
4158
|
+
* Compares suggestions with provided text and removes completed sub-sequences and preceding text
|
|
4159
|
+
* - IE. **currentText:** *abc*, **sequence:** *[{ab}{cd}{ef}*
|
|
4160
|
+
* - refines to {d}{ef}
|
|
4161
|
+
*/
|
|
4162
|
+
_trimSuggestionsByExistingText(currentText, compositeSuggestions) {
|
|
4163
|
+
const trimmedSuggestions = compositeSuggestions.reduce((acc, compositeSuggestion) => {
|
|
4164
|
+
if (compositeSuggestion.text.startsWith(currentText)) {
|
|
4165
|
+
const filteredSegments = this._filterCompletedSubSegments(currentText, compositeSuggestion);
|
|
4166
|
+
const slicedSuggestionText = compositeSuggestion.text.slice(currentText.length);
|
|
4167
|
+
if (slicedSuggestionText !== '') {
|
|
4168
|
+
const refinedCompositeSuggestion = {
|
|
4169
|
+
text: slicedSuggestionText,
|
|
4170
|
+
suggestionSequence: filteredSegments,
|
|
4171
|
+
};
|
|
4172
|
+
acc.push(refinedCompositeSuggestion);
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
return acc;
|
|
4176
|
+
}, []);
|
|
4177
|
+
return trimmedSuggestions;
|
|
4178
|
+
}
|
|
4179
|
+
/** Removed segments already accounted for in the existing text.
|
|
4180
|
+
* ie. sequence pattern segments ≈ [{look}, {an example}, {phrase}]
|
|
4181
|
+
* fullText = "look an"
|
|
4182
|
+
* remove {look} segment as its already been completed by the existing text.
|
|
4183
|
+
*/
|
|
4184
|
+
_filterCompletedSubSegments(currentText, compositeSuggestion) {
|
|
4185
|
+
let elementsToRemove = [];
|
|
4186
|
+
let workingText = currentText;
|
|
4187
|
+
compositeSuggestion.suggestionSequence.forEach(segment => {
|
|
4188
|
+
/**sub segment has been completed, remove it from the sequence */
|
|
4189
|
+
if (workingText.startsWith(segment.text)) {
|
|
4190
|
+
workingText = workingText.slice(segment.text.length);
|
|
4191
|
+
elementsToRemove.push(segment);
|
|
4192
|
+
}
|
|
4193
|
+
});
|
|
4194
|
+
const filteredSegments = compositeSuggestion.suggestionSequence.filter(segment => !elementsToRemove.includes(segment));
|
|
4195
|
+
return filteredSegments;
|
|
4196
|
+
}
|
|
4197
|
+
_getCompositeSuggestionsForPattern(pattern) {
|
|
4198
|
+
const suggestionsToReturn = [];
|
|
4199
|
+
const leafPatterns = pattern.getPatterns();
|
|
4200
|
+
// for when pattern has no leafPatterns and only returns itself
|
|
4201
|
+
if (leafPatterns.length === 1 && leafPatterns[0].id === pattern.id) {
|
|
4202
|
+
const currentCustomTokens = this._getCustomTokens(pattern);
|
|
4203
|
+
const currentTokens = pattern.getTokens();
|
|
4204
|
+
const allTokens = [...currentCustomTokens, ...currentTokens];
|
|
4205
|
+
const leafCompositeSuggestions = allTokens.map(token => {
|
|
4206
|
+
const segment = {
|
|
4207
|
+
text: token,
|
|
4208
|
+
pattern: pattern,
|
|
4209
|
+
};
|
|
4210
|
+
const compositeSuggestion = {
|
|
4211
|
+
text: token,
|
|
4212
|
+
suggestionSequence: [segment],
|
|
4213
|
+
};
|
|
4214
|
+
return compositeSuggestion;
|
|
4215
|
+
});
|
|
4216
|
+
suggestionsToReturn.push(...leafCompositeSuggestions);
|
|
4217
|
+
}
|
|
4218
|
+
else {
|
|
4219
|
+
const currentCustomTokens = this._getCustomTokens(pattern);
|
|
4220
|
+
const patternsSuggestionList = currentCustomTokens.map(token => {
|
|
4221
|
+
const segment = {
|
|
4222
|
+
text: token,
|
|
4223
|
+
pattern: pattern,
|
|
4224
|
+
};
|
|
4225
|
+
const patternSuggestion = {
|
|
4226
|
+
text: token,
|
|
4227
|
+
suggestionSequence: [segment],
|
|
4228
|
+
};
|
|
4229
|
+
return patternSuggestion;
|
|
4230
|
+
});
|
|
4231
|
+
const leafCompositeSuggestions = leafPatterns.map(lp => this._getCompositeSuggestionsForPattern(lp)).flat();
|
|
4232
|
+
suggestionsToReturn.push(...patternsSuggestionList, ...leafCompositeSuggestions);
|
|
4233
|
+
}
|
|
4160
4234
|
if (this._options.greedyPatternNames != null && this._options.greedyPatternNames.includes(pattern.name)) {
|
|
4161
4235
|
const nextPatterns = pattern.getNextPatterns();
|
|
4162
|
-
const
|
|
4163
|
-
|
|
4236
|
+
const nextPatternedTokensList = nextPatterns.reduce((acc, pattern) => {
|
|
4237
|
+
const patternedTokensList = this._getCompositeSuggestionsForPattern(pattern);
|
|
4238
|
+
acc.push(...patternedTokensList);
|
|
4164
4239
|
return acc;
|
|
4165
4240
|
}, []);
|
|
4166
|
-
|
|
4167
|
-
const
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4241
|
+
const compositeSuggestionList = [];
|
|
4242
|
+
for (const currentSuggestion of suggestionsToReturn) {
|
|
4243
|
+
for (const nextSuggestionWithSubElements of nextPatternedTokensList) {
|
|
4244
|
+
const augmentedTokenWithPattern = {
|
|
4245
|
+
text: currentSuggestion.text + nextSuggestionWithSubElements.text,
|
|
4246
|
+
suggestionSequence: [...currentSuggestion.suggestionSequence, ...nextSuggestionWithSubElements.suggestionSequence],
|
|
4247
|
+
};
|
|
4248
|
+
compositeSuggestionList.push(augmentedTokenWithPattern);
|
|
4171
4249
|
}
|
|
4172
4250
|
}
|
|
4173
|
-
return
|
|
4251
|
+
return compositeSuggestionList;
|
|
4174
4252
|
}
|
|
4175
4253
|
else {
|
|
4176
|
-
|
|
4254
|
+
const dedupedSuggestions = this._deDupeCompositeSuggestions(suggestionsToReturn);
|
|
4255
|
+
return dedupedSuggestions;
|
|
4177
4256
|
}
|
|
4178
4257
|
}
|
|
4179
|
-
|
|
4180
|
-
var _a
|
|
4258
|
+
_getCustomTokens(pattern) {
|
|
4259
|
+
var _a;
|
|
4181
4260
|
const customTokensMap = this._options.customTokens || {};
|
|
4182
|
-
const
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4261
|
+
const customTokens = (_a = customTokensMap[pattern.name]) !== null && _a !== void 0 ? _a : [];
|
|
4262
|
+
const allTokens = [...customTokens];
|
|
4263
|
+
return allTokens;
|
|
4264
|
+
}
|
|
4265
|
+
_deDupeCompositeSuggestions(suggestions) {
|
|
4266
|
+
if (this._options.disableDedupe) {
|
|
4267
|
+
return suggestions;
|
|
4268
|
+
}
|
|
4269
|
+
const seen = new Set();
|
|
4270
|
+
const unique = [];
|
|
4271
|
+
for (const suggestion of suggestions) {
|
|
4272
|
+
// Create a unique key based on text and subElements
|
|
4273
|
+
const subElementsKey = suggestion.suggestionSequence
|
|
4274
|
+
.map(sub => ` ${sub.pattern.name} - ${sub.text} `)
|
|
4275
|
+
.sort()
|
|
4276
|
+
.join('|');
|
|
4277
|
+
const key = `${suggestion.text}|${subElementsKey}`;
|
|
4278
|
+
if (!seen.has(key)) {
|
|
4279
|
+
seen.add(key);
|
|
4280
|
+
unique.push(suggestion);
|
|
4193
4281
|
}
|
|
4194
4282
|
}
|
|
4195
|
-
return
|
|
4283
|
+
return unique;
|
|
4196
4284
|
}
|
|
4197
|
-
_createSuggestions(lastIndex,
|
|
4285
|
+
_createSuggestions(lastIndex, compositeSuggestionList) {
|
|
4198
4286
|
let textToIndex = lastIndex === -1 ? "" : this._cursor.getChars(0, lastIndex);
|
|
4199
|
-
const suggestionStrings = [];
|
|
4200
4287
|
const options = [];
|
|
4201
|
-
for (const
|
|
4288
|
+
for (const compositeSuggestion of compositeSuggestionList) {
|
|
4202
4289
|
// concatenated for start index identification inside createSuggestion
|
|
4203
|
-
const
|
|
4204
|
-
|
|
4205
|
-
const
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
const suggestionOption = this._createSuggestion(this._cursor.text, suggestion);
|
|
4209
|
-
options.push(suggestionOption);
|
|
4210
|
-
}
|
|
4290
|
+
const existingTextWithSuggestion = textToIndex + compositeSuggestion.text;
|
|
4291
|
+
existingTextWithSuggestion === this._text;
|
|
4292
|
+
const suggestionOption = this._createSuggestionOption(this._cursor.text, existingTextWithSuggestion, compositeSuggestion.suggestionSequence);
|
|
4293
|
+
options.push(suggestionOption);
|
|
4294
|
+
// }
|
|
4211
4295
|
}
|
|
4212
4296
|
const reducedOptions = getFurthestOptions(options);
|
|
4213
4297
|
reducedOptions.sort((a, b) => a.text.localeCompare(b.text));
|
|
4214
4298
|
return reducedOptions;
|
|
4215
4299
|
}
|
|
4216
|
-
|
|
4300
|
+
_createSuggestionOption(fullText, suggestion, segments) {
|
|
4217
4301
|
const furthestMatch = findMatchIndex(suggestion, fullText);
|
|
4218
4302
|
const text = suggestion.slice(furthestMatch);
|
|
4219
4303
|
const option = {
|
|
4220
4304
|
text: text,
|
|
4221
4305
|
startIndex: furthestMatch,
|
|
4306
|
+
suggestionSequence: segments,
|
|
4222
4307
|
};
|
|
4223
4308
|
return option;
|
|
4224
4309
|
}
|