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