@witchcraft/expressit 0.0.2
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 +86 -0
- package/dist/ast/builders/array.d.ts +8 -0
- package/dist/ast/builders/array.d.ts.map +1 -0
- package/dist/ast/builders/array.js +31 -0
- package/dist/ast/builders/condition.d.ts +20 -0
- package/dist/ast/builders/condition.d.ts.map +1 -0
- package/dist/ast/builders/condition.js +28 -0
- package/dist/ast/builders/delim.d.ts +11 -0
- package/dist/ast/builders/delim.d.ts.map +1 -0
- package/dist/ast/builders/delim.js +20 -0
- package/dist/ast/builders/error.d.ts +9 -0
- package/dist/ast/builders/error.d.ts.map +1 -0
- package/dist/ast/builders/error.js +16 -0
- package/dist/ast/builders/expression.d.ts +12 -0
- package/dist/ast/builders/expression.d.ts.map +1 -0
- package/dist/ast/builders/expression.js +31 -0
- package/dist/ast/builders/group.d.ts +20 -0
- package/dist/ast/builders/group.d.ts.map +1 -0
- package/dist/ast/builders/group.js +47 -0
- package/dist/ast/builders/index.d.ts +12 -0
- package/dist/ast/builders/index.d.ts.map +1 -0
- package/dist/ast/builders/index.js +24 -0
- package/dist/ast/builders/isFullPos.d.ts +6 -0
- package/dist/ast/builders/isFullPos.d.ts.map +1 -0
- package/dist/ast/builders/isFullPos.js +6 -0
- package/dist/ast/builders/pos.d.ts +21 -0
- package/dist/ast/builders/pos.d.ts.map +1 -0
- package/dist/ast/builders/pos.js +28 -0
- package/dist/ast/builders/token.d.ts +12 -0
- package/dist/ast/builders/token.d.ts.map +1 -0
- package/dist/ast/builders/token.js +26 -0
- package/dist/ast/builders/type.d.ts +6 -0
- package/dist/ast/builders/type.d.ts.map +1 -0
- package/dist/ast/builders/type.js +37 -0
- package/dist/ast/builders/variable.d.ts +17 -0
- package/dist/ast/builders/variable.d.ts.map +1 -0
- package/dist/ast/builders/variable.js +62 -0
- package/dist/ast/classes/ArrayNode.d.ts +18 -0
- package/dist/ast/classes/ArrayNode.d.ts.map +1 -0
- package/dist/ast/classes/ArrayNode.js +55 -0
- package/dist/ast/classes/Condition.d.ts +13 -0
- package/dist/ast/classes/Condition.d.ts.map +1 -0
- package/dist/ast/classes/Condition.js +21 -0
- package/dist/ast/classes/ConditionNode.d.ts +73 -0
- package/dist/ast/classes/ConditionNode.d.ts.map +1 -0
- package/dist/ast/classes/ConditionNode.js +101 -0
- package/dist/ast/classes/ErrorToken.d.ts +27 -0
- package/dist/ast/classes/ErrorToken.d.ts.map +1 -0
- package/dist/ast/classes/ErrorToken.js +47 -0
- package/dist/ast/classes/Expression.d.ts +13 -0
- package/dist/ast/classes/Expression.d.ts.map +1 -0
- package/dist/ast/classes/Expression.js +19 -0
- package/dist/ast/classes/ExpressionNode.d.ts +21 -0
- package/dist/ast/classes/ExpressionNode.d.ts.map +1 -0
- package/dist/ast/classes/ExpressionNode.js +57 -0
- package/dist/ast/classes/GroupNode.d.ts +64 -0
- package/dist/ast/classes/GroupNode.d.ts.map +1 -0
- package/dist/ast/classes/GroupNode.js +69 -0
- package/dist/ast/classes/Node.d.ts +22 -0
- package/dist/ast/classes/Node.d.ts.map +1 -0
- package/dist/ast/classes/Node.js +28 -0
- package/dist/ast/classes/Token.d.ts +27 -0
- package/dist/ast/classes/Token.d.ts.map +1 -0
- package/dist/ast/classes/Token.js +28 -0
- package/dist/ast/classes/ValidToken.d.ts +26 -0
- package/dist/ast/classes/ValidToken.d.ts.map +1 -0
- package/dist/ast/classes/ValidToken.js +49 -0
- package/dist/ast/classes/VariableNode.d.ts +33 -0
- package/dist/ast/classes/VariableNode.d.ts.map +1 -0
- package/dist/ast/classes/VariableNode.js +58 -0
- package/dist/ast/classes/index.d.ts +12 -0
- package/dist/ast/classes/index.d.ts.map +1 -0
- package/dist/ast/classes/index.js +24 -0
- package/dist/ast/handlers.d.ts +42 -0
- package/dist/ast/handlers.d.ts.map +1 -0
- package/dist/ast/handlers.js +150 -0
- package/dist/ast/index.d.ts +4 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +8 -0
- package/dist/examples/advancedValueComparer.d.ts +3 -0
- package/dist/examples/advancedValueComparer.d.ts.map +1 -0
- package/dist/examples/advancedValueComparer.js +28 -0
- package/dist/examples/shortcutContextParser.d.ts +22 -0
- package/dist/examples/shortcutContextParser.d.ts.map +1 -0
- package/dist/examples/shortcutContextParser.js +126 -0
- package/dist/global.d.js +1 -0
- package/dist/grammar/ParserBase.d.ts +51 -0
- package/dist/grammar/ParserBase.d.ts.map +1 -0
- package/dist/grammar/ParserBase.js +516 -0
- package/dist/grammar/createTokens.d.ts +56 -0
- package/dist/grammar/createTokens.d.ts.map +1 -0
- package/dist/grammar/createTokens.js +843 -0
- package/dist/grammar/index.d.ts +3 -0
- package/dist/grammar/index.d.ts.map +1 -0
- package/dist/grammar/index.js +6 -0
- package/dist/helpers/errors.d.ts +9 -0
- package/dist/helpers/errors.d.ts.map +1 -0
- package/dist/helpers/errors.js +41 -0
- package/dist/helpers/general/applyBoolean.d.ts +3 -0
- package/dist/helpers/general/applyBoolean.d.ts.map +1 -0
- package/dist/helpers/general/applyBoolean.js +17 -0
- package/dist/helpers/general/applyPrefix.d.ts +4 -0
- package/dist/helpers/general/applyPrefix.d.ts.map +1 -0
- package/dist/helpers/general/applyPrefix.js +9 -0
- package/dist/helpers/general/defaultConditionNormalizer.d.ts +3 -0
- package/dist/helpers/general/defaultConditionNormalizer.d.ts.map +1 -0
- package/dist/helpers/general/defaultConditionNormalizer.js +6 -0
- package/dist/helpers/general/defaultKeyParser.d.ts +3 -0
- package/dist/helpers/general/defaultKeyParser.d.ts.map +1 -0
- package/dist/helpers/general/defaultKeyParser.js +8 -0
- package/dist/helpers/general/defaultPrefixApplier.d.ts +3 -0
- package/dist/helpers/general/defaultPrefixApplier.d.ts.map +1 -0
- package/dist/helpers/general/defaultPrefixApplier.js +6 -0
- package/dist/helpers/general/defaultValueComparer.d.ts +3 -0
- package/dist/helpers/general/defaultValueComparer.d.ts.map +1 -0
- package/dist/helpers/general/defaultValueComparer.js +6 -0
- package/dist/helpers/general/index.d.ts +7 -0
- package/dist/helpers/general/index.d.ts.map +1 -0
- package/dist/helpers/general/index.js +14 -0
- package/dist/helpers/index.d.ts +4 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +8 -0
- package/dist/helpers/parser/assignParents.d.ts +4 -0
- package/dist/helpers/parser/assignParents.d.ts.map +1 -0
- package/dist/helpers/parser/assignParents.js +71 -0
- package/dist/helpers/parser/checkParserOpts.d.ts +3 -0
- package/dist/helpers/parser/checkParserOpts.d.ts.map +1 -0
- package/dist/helpers/parser/checkParserOpts.js +126 -0
- package/dist/helpers/parser/extractPosition.d.ts +9 -0
- package/dist/helpers/parser/extractPosition.d.ts.map +1 -0
- package/dist/helpers/parser/extractPosition.js +9 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.d.ts +5 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.d.ts.map +1 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.js +20 -0
- package/dist/helpers/parser/index.d.ts +9 -0
- package/dist/helpers/parser/index.d.ts.map +1 -0
- package/dist/helpers/parser/index.js +18 -0
- package/dist/helpers/parser/parseParserOptions.d.ts +4 -0
- package/dist/helpers/parser/parseParserOptions.d.ts.map +1 -0
- package/dist/helpers/parser/parseParserOptions.js +45 -0
- package/dist/helpers/parser/seal.d.ts +8 -0
- package/dist/helpers/parser/seal.d.ts.map +1 -0
- package/dist/helpers/parser/seal.js +10 -0
- package/dist/helpers/parser/setParent.d.ts +6 -0
- package/dist/helpers/parser/setParent.d.ts.map +1 -0
- package/dist/helpers/parser/setParent.js +4 -0
- package/dist/helpers/parser/unescape.d.ts +3 -0
- package/dist/helpers/parser/unescape.d.ts.map +1 -0
- package/dist/helpers/parser/unescape.js +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/methods/autocomplete.d.ts +18 -0
- package/dist/methods/autocomplete.d.ts.map +1 -0
- package/dist/methods/autocomplete.js +109 -0
- package/dist/methods/autoreplace.d.ts +13 -0
- package/dist/methods/autoreplace.d.ts.map +1 -0
- package/dist/methods/autoreplace.js +36 -0
- package/dist/methods/autosuggest.d.ts +28 -0
- package/dist/methods/autosuggest.d.ts.map +1 -0
- package/dist/methods/autosuggest.js +371 -0
- package/dist/methods/evaluate.d.ts +11 -0
- package/dist/methods/evaluate.d.ts.map +1 -0
- package/dist/methods/evaluate.js +30 -0
- package/dist/methods/getBestIndex.d.ts +19 -0
- package/dist/methods/getBestIndex.d.ts.map +1 -0
- package/dist/methods/getBestIndex.js +53 -0
- package/dist/methods/getIndexes.d.ts +17 -0
- package/dist/methods/getIndexes.d.ts.map +1 -0
- package/dist/methods/getIndexes.js +97 -0
- package/dist/methods/index.d.ts +9 -0
- package/dist/methods/index.d.ts.map +1 -0
- package/dist/methods/index.js +18 -0
- package/dist/methods/normalize.d.ts +12 -0
- package/dist/methods/normalize.d.ts.map +1 -0
- package/dist/methods/normalize.js +99 -0
- package/dist/methods/validate.d.ts +11 -0
- package/dist/methods/validate.d.ts.map +1 -0
- package/dist/methods/validate.js +111 -0
- package/dist/package.js +7 -0
- package/dist/package.json.js +193 -0
- package/dist/parser.d.ts +58 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +136 -0
- package/dist/types/ast.d.ts +70 -0
- package/dist/types/ast.d.ts.map +1 -0
- package/dist/types/ast.js +29 -0
- package/dist/types/autocomplete.d.ts +143 -0
- package/dist/types/autocomplete.d.ts.map +1 -0
- package/dist/types/autocomplete.js +24 -0
- package/dist/types/errors.d.ts +34 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +10 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/parser.d.ts +451 -0
- package/dist/types/parser.d.ts.map +1 -0
- package/dist/types/parser.js +1 -0
- package/dist/utils/extractTokens.d.ts +8 -0
- package/dist/utils/extractTokens.d.ts.map +1 -0
- package/dist/utils/extractTokens.js +50 -0
- package/dist/utils/getCursorInfo.d.ts +7 -0
- package/dist/utils/getCursorInfo.d.ts.map +1 -0
- package/dist/utils/getCursorInfo.js +86 -0
- package/dist/utils/getOppositeDelimiter.d.ts +6 -0
- package/dist/utils/getOppositeDelimiter.d.ts.map +1 -0
- package/dist/utils/getOppositeDelimiter.js +35 -0
- package/dist/utils/getSurroundingErrors.d.ts +25 -0
- package/dist/utils/getSurroundingErrors.d.ts.map +1 -0
- package/dist/utils/getSurroundingErrors.js +37 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/isBracket.d.ts +3 -0
- package/dist/utils/isBracket.d.ts.map +1 -0
- package/dist/utils/isBracket.js +7 -0
- package/dist/utils/isDelimiter.d.ts +6 -0
- package/dist/utils/isDelimiter.d.ts.map +1 -0
- package/dist/utils/isDelimiter.js +17 -0
- package/dist/utils/isParen.d.ts +3 -0
- package/dist/utils/isParen.d.ts.map +1 -0
- package/dist/utils/isParen.js +7 -0
- package/dist/utils/isQuote.d.ts +4 -0
- package/dist/utils/isQuote.d.ts.map +1 -0
- package/dist/utils/isQuote.js +7 -0
- package/dist/utils/prettyAst.d.ts +35 -0
- package/dist/utils/prettyAst.d.ts.map +1 -0
- package/dist/utils/prettyAst.js +112 -0
- package/package.json +152 -0
- package/src/ast/builders/array.ts +45 -0
- package/src/ast/builders/condition.ts +56 -0
- package/src/ast/builders/delim.ts +39 -0
- package/src/ast/builders/error.ts +22 -0
- package/src/ast/builders/expression.ts +66 -0
- package/src/ast/builders/group.ts +79 -0
- package/src/ast/builders/index.ts +13 -0
- package/src/ast/builders/isFullPos.ts +10 -0
- package/src/ast/builders/pos.ts +57 -0
- package/src/ast/builders/token.ts +46 -0
- package/src/ast/builders/type.ts +32 -0
- package/src/ast/builders/variable.ts +89 -0
- package/src/ast/classes/ArrayNode.ts +46 -0
- package/src/ast/classes/Condition.ts +22 -0
- package/src/ast/classes/ConditionNode.ts +141 -0
- package/src/ast/classes/ErrorToken.ts +49 -0
- package/src/ast/classes/Expression.ts +26 -0
- package/src/ast/classes/ExpressionNode.ts +62 -0
- package/src/ast/classes/GroupNode.ts +127 -0
- package/src/ast/classes/Node.ts +47 -0
- package/src/ast/classes/Token.ts +59 -0
- package/src/ast/classes/ValidToken.ts +56 -0
- package/src/ast/classes/VariableNode.ts +67 -0
- package/src/ast/classes/index.ts +13 -0
- package/src/ast/handlers.ts +190 -0
- package/src/ast/index.ts +5 -0
- package/src/examples/advancedValueComparer.ts +31 -0
- package/src/examples/shortcutContextParser.ts +140 -0
- package/src/global.d.ts +4 -0
- package/src/grammar/ParserBase.ts +715 -0
- package/src/grammar/createTokens.ts +512 -0
- package/src/grammar/index.ts +4 -0
- package/src/helpers/errors.ts +45 -0
- package/src/helpers/general/applyBoolean.ts +9 -0
- package/src/helpers/general/applyPrefix.ts +7 -0
- package/src/helpers/general/defaultConditionNormalizer.ts +9 -0
- package/src/helpers/general/defaultKeyParser.ts +8 -0
- package/src/helpers/general/defaultPrefixApplier.ts +7 -0
- package/src/helpers/general/defaultValueComparer.ts +7 -0
- package/src/helpers/general/index.ts +8 -0
- package/src/helpers/index.ts +5 -0
- package/src/helpers/parser/assignParents.ts +51 -0
- package/src/helpers/parser/checkParserOpts.ts +143 -0
- package/src/helpers/parser/extractPosition.ts +15 -0
- package/src/helpers/parser/getUnclosedRightParenCount.ts +22 -0
- package/src/helpers/parser/index.ts +10 -0
- package/src/helpers/parser/parseParserOptions.ts +54 -0
- package/src/helpers/parser/seal.ts +14 -0
- package/src/helpers/parser/setParent.ts +5 -0
- package/src/helpers/parser/unescape.ts +4 -0
- package/src/index.ts +7 -0
- package/src/methods/autocomplete.ts +128 -0
- package/src/methods/autoreplace.ts +46 -0
- package/src/methods/autosuggest.ts +543 -0
- package/src/methods/evaluate.ts +37 -0
- package/src/methods/getBestIndex.ts +53 -0
- package/src/methods/getIndexes.ts +99 -0
- package/src/methods/index.ts +10 -0
- package/src/methods/normalize.ts +138 -0
- package/src/methods/validate.ts +141 -0
- package/src/package.js +11 -0
- package/src/parser.ts +183 -0
- package/src/types/ast.ts +148 -0
- package/src/types/autocomplete.ts +152 -0
- package/src/types/errors.ts +40 -0
- package/src/types/index.ts +6 -0
- package/src/types/parser.ts +479 -0
- package/src/utils/extractTokens.ts +67 -0
- package/src/utils/getCursorInfo.ts +106 -0
- package/src/utils/getOppositeDelimiter.ts +36 -0
- package/src/utils/getSurroundingErrors.ts +57 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/isBracket.ts +6 -0
- package/src/utils/isDelimiter.ts +18 -0
- package/src/utils/isParen.ts +6 -0
- package/src/utils/isQuote.ts +6 -0
- package/src/utils/prettyAst.ts +152 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setParent.d.ts","sourceRoot":"","sources":["../../../src/helpers/parser/setParent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,OAAO,MAAyC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unescape.d.ts","sourceRoot":"","sources":["../../../src/helpers/parser/unescape.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5C"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,wBAAwB,CAAA;AAC7C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as index from "./ast/classes/index.js";
|
|
2
|
+
import * as index$1 from "./grammar/index.js";
|
|
3
|
+
import { Parser } from "./parser.js";
|
|
4
|
+
import { AST_TYPE, TOKEN_TYPE } from "./types/ast.js";
|
|
5
|
+
import { SUGGESTION_TYPE } from "./types/autocomplete.js";
|
|
6
|
+
import { ERROR_CODES } from "./types/errors.js";
|
|
7
|
+
import * as index$2 from "./utils/index.js";
|
|
8
|
+
export {
|
|
9
|
+
AST_TYPE,
|
|
10
|
+
ERROR_CODES,
|
|
11
|
+
Parser,
|
|
12
|
+
SUGGESTION_TYPE,
|
|
13
|
+
TOKEN_TYPE,
|
|
14
|
+
index as ast,
|
|
15
|
+
index$1 as grammar,
|
|
16
|
+
index$2 as utils
|
|
17
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Completion, type Suggestion } from "../types/autocomplete.js";
|
|
2
|
+
import type { FullParserOptions } from "../types/parser.js";
|
|
3
|
+
export declare class AutocompleteMixin<T extends {}> {
|
|
4
|
+
/**
|
|
5
|
+
* Given a list of @see Suggestion entries, the parser options, and a list of variables, prefixes, operators, etc, and the preferred quote type, returns a list of @see Completion entries.
|
|
6
|
+
*
|
|
7
|
+
* It takes care of suggesting the correct delimiters for fixes, quoting variables/prefixes if it would not be possible to parse them unquoted, and separating symbol from non-symbol (word) operators.
|
|
8
|
+
*
|
|
9
|
+
* Does not add whitespace or group requirements. The suggestion information is still in the completion if you wish to show these. But they should not be added to the completion value if using @see autoreplace which will take care of it.
|
|
10
|
+
*
|
|
11
|
+
* Is not aware of existing values. You will have to use @see getCursorInfo to understand the context in which the suggestion was made, so that, for example, you could filter out used regex flags.
|
|
12
|
+
*/
|
|
13
|
+
autocomplete(suggestions: Suggestion[], { values, arrayValues, variables, prefixes, properties, expandedPropertyOperators, customPropertyOperators, keywords, regexFlags, quote, }?: Partial<Record<"variables" | "values" | "arrayValues" | "prefixes" | "properties" | "regexFlags" | "expandedPropertyOperators" | "customPropertyOperators", string[]>> & {
|
|
14
|
+
quote?: string;
|
|
15
|
+
keywords?: FullParserOptions<T>["keywords"];
|
|
16
|
+
}): Completion[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../src/methods/autocomplete.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAmB,MAAM,0BAA0B,CAAA;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,qBAAa,iBAAiB,CAAC,CAAC,SAAS,EAAE;IAC1C;;;;;;;;OAQG;IACH,YAAY,CACX,WAAW,EAAE,UAAU,EAAE,EACzB,EACC,MAAW,EAAE,WAAgB,EAAE,SAAc,EAAE,QAAa,EAAE,UAAe,EAAE,yBAA8B,EAAE,uBAA0F,EAAE,QAAsD,EAAE,UAA4B,EAAE,KAAY,GAC7S,GAAE,OAAO,CAAC,MAAM,CAChB,WAAW,GACX,QAAQ,GACR,aAAa,GACb,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,2BAA2B,GAC3B,yBAAyB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG;QACxC,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,QAAQ,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;KACtC,GACJ,UAAU,EAAE;CA4Ff"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { unreachable } from "@alanscodelog/utils";
|
|
2
|
+
import { ConditionNode } from "../ast/classes/ConditionNode.js";
|
|
3
|
+
import { VariableNode } from "../ast/classes/VariableNode.js";
|
|
4
|
+
import { SUGGESTION_TYPE } from "../types/autocomplete.js";
|
|
5
|
+
class AutocompleteMixin {
|
|
6
|
+
/**
|
|
7
|
+
* Given a list of @see Suggestion entries, the parser options, and a list of variables, prefixes, operators, etc, and the preferred quote type, returns a list of @see Completion entries.
|
|
8
|
+
*
|
|
9
|
+
* It takes care of suggesting the correct delimiters for fixes, quoting variables/prefixes if it would not be possible to parse them unquoted, and separating symbol from non-symbol (word) operators.
|
|
10
|
+
*
|
|
11
|
+
* Does not add whitespace or group requirements. The suggestion information is still in the completion if you wish to show these. But they should not be added to the completion value if using @see autoreplace which will take care of it.
|
|
12
|
+
*
|
|
13
|
+
* Is not aware of existing values. You will have to use @see getCursorInfo to understand the context in which the suggestion was made, so that, for example, you could filter out used regex flags.
|
|
14
|
+
*/
|
|
15
|
+
autocomplete(suggestions, {
|
|
16
|
+
values = [],
|
|
17
|
+
arrayValues = [],
|
|
18
|
+
variables = [],
|
|
19
|
+
prefixes = [],
|
|
20
|
+
properties = [],
|
|
21
|
+
expandedPropertyOperators = [],
|
|
22
|
+
customPropertyOperators = this.options.customPropertyOperators ?? [],
|
|
23
|
+
keywords = this.options.keywords,
|
|
24
|
+
regexFlags = ["i", "m", "u"],
|
|
25
|
+
quote = '"'
|
|
26
|
+
} = {}) {
|
|
27
|
+
const self = this;
|
|
28
|
+
return suggestions.map((suggestion) => {
|
|
29
|
+
const type = suggestion.type;
|
|
30
|
+
switch (type) {
|
|
31
|
+
case SUGGESTION_TYPE.BACKTICK:
|
|
32
|
+
return [{ suggestion, value: "`" }];
|
|
33
|
+
case SUGGESTION_TYPE.DOUBLEQUOTE:
|
|
34
|
+
return [{ suggestion, value: '"' }];
|
|
35
|
+
case SUGGESTION_TYPE.SINGLEQUOTE:
|
|
36
|
+
return [{ suggestion, value: "'" }];
|
|
37
|
+
case SUGGESTION_TYPE.PARENL:
|
|
38
|
+
return [{ suggestion, value: "(" }];
|
|
39
|
+
case SUGGESTION_TYPE.PARENR:
|
|
40
|
+
return [{ suggestion, value: ")" }];
|
|
41
|
+
case SUGGESTION_TYPE.BRAKCETR:
|
|
42
|
+
return [{ suggestion, value: "]" }];
|
|
43
|
+
case SUGGESTION_TYPE.REGEX:
|
|
44
|
+
return [{ suggestion, value: "/" }];
|
|
45
|
+
case SUGGESTION_TYPE.REGEX_FLAGS:
|
|
46
|
+
return regexFlags.map((value) => ({ suggestion, value })).filter((completion) => {
|
|
47
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
48
|
+
const { suggestion: suggestion2, value } = completion;
|
|
49
|
+
if (suggestion2.type !== SUGGESTION_TYPE.REGEX_FLAGS) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
const token = suggestion2.cursorInfo;
|
|
53
|
+
const flags = token.at && ((_b = (_a = token.at.parent) == null ? void 0 : _a.quote) == null ? void 0 : _b.flags) === suggestion2.cursorInfo.at ? token.at : token.next && ((_d = (_c = token.next.parent) == null ? void 0 : _c.quote) == null ? void 0 : _d.flags) === suggestion2.cursorInfo.next ? token.next : token.prev && ((_f = (_e = token.prev.parent) == null ? void 0 : _e.quote) == null ? void 0 : _f.flags) === suggestion2.cursorInfo.prev ? token.prev : void 0;
|
|
54
|
+
if ((_g = flags == null ? void 0 : flags.value) == null ? void 0 : _g.includes(value)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
});
|
|
59
|
+
case SUGGESTION_TYPE.PROPERTY: {
|
|
60
|
+
return properties.map((value) => ({ suggestion, value }));
|
|
61
|
+
}
|
|
62
|
+
case SUGGESTION_TYPE.PROPERTY_SEP: {
|
|
63
|
+
return [{ suggestion, value: self.options.expandedPropertySeparator }];
|
|
64
|
+
}
|
|
65
|
+
case SUGGESTION_TYPE.EXPANDED_PROPERTY_OPERATOR: {
|
|
66
|
+
return expandedPropertyOperators.map((value) => ({ suggestion, value }));
|
|
67
|
+
}
|
|
68
|
+
case SUGGESTION_TYPE.CUSTOM_PROPERTY_OPERATOR: {
|
|
69
|
+
return customPropertyOperators.map((value) => ({ suggestion, value }));
|
|
70
|
+
}
|
|
71
|
+
case SUGGESTION_TYPE.BOOLEAN_SYMBOL_OP: {
|
|
72
|
+
const keywordsList = [...keywords.and, ...keywords.or];
|
|
73
|
+
const symOpts = keywordsList.filter((_) => _.isSymbol);
|
|
74
|
+
return symOpts.map(({ value }) => ({ suggestion, value }));
|
|
75
|
+
}
|
|
76
|
+
case SUGGESTION_TYPE.BOOLEAN_WORD_OP: {
|
|
77
|
+
const keywordsList = [...keywords.and, ...keywords.or];
|
|
78
|
+
const wordOpts = keywordsList.filter((_) => !_.isSymbol);
|
|
79
|
+
return wordOpts.map(({ value }) => ({ suggestion, value }));
|
|
80
|
+
}
|
|
81
|
+
case SUGGESTION_TYPE.VALUE:
|
|
82
|
+
case SUGGESTION_TYPE.ARRAY_VALUE:
|
|
83
|
+
case SUGGESTION_TYPE.VARIABLE: {
|
|
84
|
+
const arr = type === SUGGESTION_TYPE.VARIABLE ? variables : type === SUGGESTION_TYPE.ARRAY_VALUE ? arrayValues : type === SUGGESTION_TYPE.VALUE ? values : unreachable();
|
|
85
|
+
return arr.map((variable) => {
|
|
86
|
+
const res = self.parse(variable);
|
|
87
|
+
if (res instanceof ConditionNode && res.operator === void 0 && res.value instanceof VariableNode && res.value.quote === void 0) {
|
|
88
|
+
return { suggestion, value: res.value.value.value };
|
|
89
|
+
} else {
|
|
90
|
+
return { suggestion, value: quote + variable.replace(new RegExp(quote, "g"), `\\${quote}`) + quote };
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
case SUGGESTION_TYPE.PREFIX:
|
|
95
|
+
return prefixes.map((prefix) => {
|
|
96
|
+
const res = self.parse(prefix);
|
|
97
|
+
if (res instanceof ConditionNode && res.operator === void 0 && res.value instanceof VariableNode && res.value.quote === void 0) {
|
|
98
|
+
return { suggestion, value: res.value.value.value };
|
|
99
|
+
} else {
|
|
100
|
+
return { suggestion, value: quote + prefix.replace(new RegExp(quote, "g"), `\\${quote}`) + quote };
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}).flat();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
AutocompleteMixin
|
|
109
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Completion } from "../types/autocomplete.js";
|
|
2
|
+
export declare class AutoreplaceMixin {
|
|
3
|
+
/**
|
|
4
|
+
* Given the input string and a @see Completion consisting of the value of the replacement and a @see Suggestion entry, returns the replacement string and the new position of the cursor.
|
|
5
|
+
*
|
|
6
|
+
* The value passed should be escaped if it's needed (or quoted). @see autocomplete already takes care of quoting variables if you're using it.
|
|
7
|
+
*/
|
|
8
|
+
autoreplace(input: string, { value, suggestion }: Completion): {
|
|
9
|
+
replacement: string;
|
|
10
|
+
cursor: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=autoreplace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoreplace.d.ts","sourceRoot":"","sources":["../../src/methods/autoreplace.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAG1D,qBAAa,gBAAgB;IAC5B;;;;OAIG;IACH,WAAW,CACV,KAAK,EAAE,MAAM,EACb,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,UAAU,GAC/B;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CA+B1C"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { insert } from "@alanscodelog/utils";
|
|
2
|
+
class AutoreplaceMixin {
|
|
3
|
+
/**
|
|
4
|
+
* Given the input string and a @see Completion consisting of the value of the replacement and a @see Suggestion entry, returns the replacement string and the new position of the cursor.
|
|
5
|
+
*
|
|
6
|
+
* The value passed should be escaped if it's needed (or quoted). @see autocomplete already takes care of quoting variables if you're using it.
|
|
7
|
+
*/
|
|
8
|
+
autoreplace(input, { value, suggestion }) {
|
|
9
|
+
const isQuotedLeft = ['"', "'", "`"].includes(value[0]);
|
|
10
|
+
const isQuotedRight = ['"', "'", "`"].includes(value[value.length - 1]);
|
|
11
|
+
if (isQuotedLeft && !isQuotedRight || !isQuotedLeft && isQuotedRight) {
|
|
12
|
+
throw new Error(`Completion value must either be entirely quoted or entirely unquoted. But the left side is ${isQuotedLeft ? "quoted" : "unquoted"} and the right side is ${isQuotedRight ? "quoted" : "unquoted"}.`);
|
|
13
|
+
}
|
|
14
|
+
let cursor = suggestion.range.start + value.length;
|
|
15
|
+
if (suggestion.requires.prefix) {
|
|
16
|
+
value = suggestion.requires.prefix + (isQuotedLeft ? "" : '"') + value + (isQuotedRight ? "" : '"');
|
|
17
|
+
cursor += suggestion.requires.prefix.length + Number(!isQuotedLeft) + Number(!isQuotedRight);
|
|
18
|
+
}
|
|
19
|
+
if (suggestion.requires.group) {
|
|
20
|
+
value += "()";
|
|
21
|
+
cursor++;
|
|
22
|
+
}
|
|
23
|
+
if (suggestion.requires.whitespace.before) {
|
|
24
|
+
value = ` ${value}`;
|
|
25
|
+
cursor++;
|
|
26
|
+
}
|
|
27
|
+
if (suggestion.requires.whitespace.after) {
|
|
28
|
+
value = `${value} `;
|
|
29
|
+
}
|
|
30
|
+
const replacement = insert(value, input, [suggestion.range.start, suggestion.range.end]);
|
|
31
|
+
return { replacement, cursor };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
AutoreplaceMixin
|
|
36
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ParserResults } from "../types/ast.js";
|
|
2
|
+
import { type Suggestion } from "../types/autocomplete.js";
|
|
3
|
+
export declare class Autosuggest<T extends {}> {
|
|
4
|
+
/**
|
|
5
|
+
* Returns a list of suggestions ( @see Suggestion ). These are not a list of autocomplete entries (with values), but more a list of entries describing possible suggestions. This list can then be passed to @see Parser["autocomplete"] to build a list to show users, from which you can then pick an entry to pass to @see Parser["autoreplace"] .
|
|
6
|
+
*
|
|
7
|
+
* The list returned is "unsorted", but there is still some logic to the order. Fixes for errors are suggested first, in the order returned by @see getSurroundingErrors. Regular suggestions come after in the following order: prefixes if enabled, variables, boolean symbol operators, then boolean word operators.
|
|
8
|
+
*
|
|
9
|
+
* When the cursor is between two tokens that have possible suggestions, only suggestion types for the token before are returned. For example:
|
|
10
|
+
*
|
|
11
|
+
* ```js
|
|
12
|
+
* prop="val"
|
|
13
|
+
* prop|="val" //returns a property suggestions to replace `prop`
|
|
14
|
+
* prop=|"val" //returns a custom operator suggestion to replace `=`
|
|
15
|
+
* prop="|val" //returns a value suggestion
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* And if there are no suggestions for the previous token but there are for the next ones, they are suggested:
|
|
19
|
+
* ```js
|
|
20
|
+
* prop:op:"val"
|
|
21
|
+
* prop:op|:"val" // returns an operator suggestion
|
|
22
|
+
* prop:op:|"val" // returns a value suggestion
|
|
23
|
+
* prop:op|"val" // returns a suggestion for the missing separator
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
autosuggest(input: string, ast: ParserResults, index: number): Suggestion[];
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=autosuggest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autosuggest.d.ts","sourceRoot":"","sources":["../../src/methods/autosuggest.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,aAAa,EAAc,MAAM,iBAAiB,CAAA;AAChE,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,0BAA0B,CAAA;AA+B3E,qBAAa,WAAW,CAAC,CAAC,SAAS,EAAE;IACpC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE;CA4d3E"}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { unreachable } from "@alanscodelog/utils";
|
|
2
|
+
import { pos } from "../ast/builders/pos.js";
|
|
3
|
+
import { ArrayNode } from "../ast/classes/ArrayNode.js";
|
|
4
|
+
import { ConditionNode } from "../ast/classes/ConditionNode.js";
|
|
5
|
+
import { ErrorToken } from "../ast/classes/ErrorToken.js";
|
|
6
|
+
import { GroupNode } from "../ast/classes/GroupNode.js";
|
|
7
|
+
import { VariableNode } from "../ast/classes/VariableNode.js";
|
|
8
|
+
import { TOKEN_TYPE } from "../types/ast.js";
|
|
9
|
+
import { SUGGESTION_TYPE } from "../types/autocomplete.js";
|
|
10
|
+
import { extractTokens } from "../utils/extractTokens.js";
|
|
11
|
+
import { getCursorInfo } from "../utils/getCursorInfo.js";
|
|
12
|
+
import { getSurroundingErrors } from "../utils/getSurroundingErrors.js";
|
|
13
|
+
const defaultNodeDirs = {
|
|
14
|
+
before: false,
|
|
15
|
+
after: false
|
|
16
|
+
};
|
|
17
|
+
const createDefaultRequires = (partial = {}) => ({
|
|
18
|
+
whitespace: {
|
|
19
|
+
...defaultNodeDirs,
|
|
20
|
+
...partial.whitespace ? partial.whitespace : {}
|
|
21
|
+
},
|
|
22
|
+
group: partial.group ?? false,
|
|
23
|
+
prefix: partial.prefix ?? false
|
|
24
|
+
});
|
|
25
|
+
const tokenRequiresWhitespace = (validToken, whitespace, wordOps) => {
|
|
26
|
+
if (whitespace || validToken === void 0)
|
|
27
|
+
return false;
|
|
28
|
+
return validToken.type === TOKEN_TYPE.VALUE || [TOKEN_TYPE.AND, TOKEN_TYPE.OR, TOKEN_TYPE.NOT].includes(validToken.type) && wordOps.find((_) => _.value === validToken.value) !== void 0;
|
|
29
|
+
};
|
|
30
|
+
const tokenVariable = [TOKEN_TYPE.BACKTICK, TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.SINGLEQUOTE, TOKEN_TYPE.VALUE, TOKEN_TYPE.REGEX];
|
|
31
|
+
class Autosuggest {
|
|
32
|
+
/**
|
|
33
|
+
* Returns a list of suggestions ( @see Suggestion ). These are not a list of autocomplete entries (with values), but more a list of entries describing possible suggestions. This list can then be passed to @see Parser["autocomplete"] to build a list to show users, from which you can then pick an entry to pass to @see Parser["autoreplace"] .
|
|
34
|
+
*
|
|
35
|
+
* The list returned is "unsorted", but there is still some logic to the order. Fixes for errors are suggested first, in the order returned by @see getSurroundingErrors. Regular suggestions come after in the following order: prefixes if enabled, variables, boolean symbol operators, then boolean word operators.
|
|
36
|
+
*
|
|
37
|
+
* When the cursor is between two tokens that have possible suggestions, only suggestion types for the token before are returned. For example:
|
|
38
|
+
*
|
|
39
|
+
* ```js
|
|
40
|
+
* prop="val"
|
|
41
|
+
* prop|="val" //returns a property suggestions to replace `prop`
|
|
42
|
+
* prop=|"val" //returns a custom operator suggestion to replace `=`
|
|
43
|
+
* prop="|val" //returns a value suggestion
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* And if there are no suggestions for the previous token but there are for the next ones, they are suggested:
|
|
47
|
+
* ```js
|
|
48
|
+
* prop:op:"val"
|
|
49
|
+
* prop:op|:"val" // returns an operator suggestion
|
|
50
|
+
* prop:op:|"val" // returns a value suggestion
|
|
51
|
+
* prop:op|"val" // returns a suggestion for the missing separator
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
autosuggest(input, ast, index) {
|
|
55
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L;
|
|
56
|
+
const opts = this.options;
|
|
57
|
+
const tokens = extractTokens(ast);
|
|
58
|
+
const token = getCursorInfo(input, tokens, index);
|
|
59
|
+
const wordOps = [...opts.keywords.and, ...opts.keywords.or, ...opts.keywords.not].filter((op) => !op.isSymbol);
|
|
60
|
+
const canSuggestOpAfterPrev = token.valid.prev && tokenVariable.includes((_a = token.valid.prev) == null ? void 0 : _a.type) && (token.whitespace.prev || token.valid.prev.type === TOKEN_TYPE.PARENR) && !token.at && token.valid.next === void 0;
|
|
61
|
+
const canSuggestOpBeforeNext = token.valid.next && tokenVariable.includes((_b = token.valid.next) == null ? void 0 : _b.type) && token.whitespace.next && // no parenL allowed since check since there will already be prefix suggestions
|
|
62
|
+
!token.at && token.valid.prev === void 0;
|
|
63
|
+
const requiresWhitespacePrev = tokenRequiresWhitespace(token.valid.prev, token.whitespace.prev, wordOps);
|
|
64
|
+
const requiresWhitespaceNext = tokenRequiresWhitespace(token.valid.next, token.whitespace.next, wordOps);
|
|
65
|
+
const requiresWhitespacePrevOp = canSuggestOpAfterPrev ? false : requiresWhitespacePrev;
|
|
66
|
+
const requireWhitespaceNextOp = !canSuggestOpAfterPrev && canSuggestOpBeforeNext ? false : requiresWhitespaceNext;
|
|
67
|
+
const suggestions = [];
|
|
68
|
+
if (ast instanceof ErrorToken) {
|
|
69
|
+
suggestions.push({
|
|
70
|
+
type: SUGGESTION_TYPE.PREFIX,
|
|
71
|
+
requires: createDefaultRequires({ group: true }),
|
|
72
|
+
range: pos({ start: index }, { fill: true }),
|
|
73
|
+
isError: true,
|
|
74
|
+
cursorInfo: token
|
|
75
|
+
});
|
|
76
|
+
suggestions.push({
|
|
77
|
+
type: SUGGESTION_TYPE.VARIABLE,
|
|
78
|
+
requires: createDefaultRequires(),
|
|
79
|
+
range: pos({ start: index }, { fill: true }),
|
|
80
|
+
isError: true,
|
|
81
|
+
cursorInfo: token
|
|
82
|
+
});
|
|
83
|
+
} else {
|
|
84
|
+
const surroundingErrors = getSurroundingErrors(tokens, token);
|
|
85
|
+
const errorTypesHandled = [];
|
|
86
|
+
const errorSuggestion = {
|
|
87
|
+
isError: true,
|
|
88
|
+
cursorInfo: token
|
|
89
|
+
};
|
|
90
|
+
const baseSuggestion = {
|
|
91
|
+
isError: false,
|
|
92
|
+
cursorInfo: token
|
|
93
|
+
};
|
|
94
|
+
for (const error of surroundingErrors) {
|
|
95
|
+
for (const type of error.expected) {
|
|
96
|
+
if (errorTypesHandled.includes(type))
|
|
97
|
+
continue;
|
|
98
|
+
errorTypesHandled.push(type);
|
|
99
|
+
switch (type) {
|
|
100
|
+
case TOKEN_TYPE.DOUBLEQUOTE:
|
|
101
|
+
case TOKEN_TYPE.SINGLEQUOTE:
|
|
102
|
+
case TOKEN_TYPE.BACKTICK:
|
|
103
|
+
{
|
|
104
|
+
const isLeft = error.parent.quote.left === error;
|
|
105
|
+
const isRight = error.parent.quote.right === error;
|
|
106
|
+
suggestions.push({
|
|
107
|
+
...errorSuggestion,
|
|
108
|
+
type,
|
|
109
|
+
requires: createDefaultRequires({
|
|
110
|
+
whitespace: {
|
|
111
|
+
before: isRight ? false : requiresWhitespacePrev,
|
|
112
|
+
after: isLeft ? false : requiresWhitespaceNext
|
|
113
|
+
}
|
|
114
|
+
}),
|
|
115
|
+
range: pos({ start: index }, { fill: true })
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
case TOKEN_TYPE.AND:
|
|
120
|
+
case TOKEN_TYPE.OR:
|
|
121
|
+
suggestions.push({
|
|
122
|
+
...errorSuggestion,
|
|
123
|
+
type: SUGGESTION_TYPE.BOOLEAN_SYMBOL_OP,
|
|
124
|
+
requires: createDefaultRequires(),
|
|
125
|
+
range: pos({ start: index }, { fill: true })
|
|
126
|
+
});
|
|
127
|
+
suggestions.push({
|
|
128
|
+
...errorSuggestion,
|
|
129
|
+
type: SUGGESTION_TYPE.BOOLEAN_WORD_OP,
|
|
130
|
+
requires: createDefaultRequires({
|
|
131
|
+
whitespace: {
|
|
132
|
+
before: requiresWhitespacePrevOp,
|
|
133
|
+
after: requireWhitespaceNextOp
|
|
134
|
+
}
|
|
135
|
+
}),
|
|
136
|
+
range: pos({ start: index }, { fill: true })
|
|
137
|
+
});
|
|
138
|
+
if (type === TOKEN_TYPE.AND)
|
|
139
|
+
errorTypesHandled.push(TOKEN_TYPE.OR);
|
|
140
|
+
if (type === TOKEN_TYPE.OR)
|
|
141
|
+
errorTypesHandled.push(TOKEN_TYPE.AND);
|
|
142
|
+
break;
|
|
143
|
+
case TOKEN_TYPE.PARENL:
|
|
144
|
+
case TOKEN_TYPE.PARENR:
|
|
145
|
+
suggestions.push({
|
|
146
|
+
...errorSuggestion,
|
|
147
|
+
type,
|
|
148
|
+
requires: createDefaultRequires(),
|
|
149
|
+
range: pos({ start: index }, { fill: true })
|
|
150
|
+
});
|
|
151
|
+
break;
|
|
152
|
+
case TOKEN_TYPE.VALUE: {
|
|
153
|
+
const prefixedValue = error.parent instanceof VariableNode ? (_d = (_c = error.parent) == null ? void 0 : _c.prefix) == null ? void 0 : _d.value : false;
|
|
154
|
+
const isRegexValue = error.parent instanceof VariableNode && (((_e = error.parent.quote) == null ? void 0 : _e.left.type) === TOKEN_TYPE.REGEX || ((_f = error.parent.quote) == null ? void 0 : _f.right.type) === TOKEN_TYPE.REGEX);
|
|
155
|
+
if (!isRegexValue) {
|
|
156
|
+
if (!prefixedValue && opts.prefixableGroups) {
|
|
157
|
+
suggestions.push({
|
|
158
|
+
...errorSuggestion,
|
|
159
|
+
type: SUGGESTION_TYPE.PREFIX,
|
|
160
|
+
requires: createDefaultRequires({
|
|
161
|
+
whitespace: {
|
|
162
|
+
before: requiresWhitespacePrev,
|
|
163
|
+
after: false
|
|
164
|
+
/* parens get inserted */
|
|
165
|
+
},
|
|
166
|
+
group: true
|
|
167
|
+
// is always needed
|
|
168
|
+
}),
|
|
169
|
+
range: pos({ start: index }, { fill: true })
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
suggestions.push({
|
|
173
|
+
...errorSuggestion,
|
|
174
|
+
type: SUGGESTION_TYPE.VARIABLE,
|
|
175
|
+
requires: createDefaultRequires({
|
|
176
|
+
whitespace: {
|
|
177
|
+
before: requiresWhitespacePrev,
|
|
178
|
+
after: requiresWhitespaceNext
|
|
179
|
+
},
|
|
180
|
+
prefix: prefixedValue
|
|
181
|
+
}),
|
|
182
|
+
range: pos({ start: index }, { fill: true })
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
case TOKEN_TYPE.BRACKETR: {
|
|
188
|
+
suggestions.push({
|
|
189
|
+
...errorSuggestion,
|
|
190
|
+
type: SUGGESTION_TYPE.BRAKCETR,
|
|
191
|
+
requires: createDefaultRequires(),
|
|
192
|
+
range: pos({ start: index }, { fill: true })
|
|
193
|
+
});
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case TOKEN_TYPE.OP_EXPANDED_SEP:
|
|
197
|
+
suggestions.push({
|
|
198
|
+
...errorSuggestion,
|
|
199
|
+
type: SUGGESTION_TYPE.PROPERTY_SEP,
|
|
200
|
+
requires: createDefaultRequires(),
|
|
201
|
+
range: pos({ start: index }, { fill: true })
|
|
202
|
+
});
|
|
203
|
+
break;
|
|
204
|
+
case TOKEN_TYPE.REGEX:
|
|
205
|
+
suggestions.push({
|
|
206
|
+
...errorSuggestion,
|
|
207
|
+
type: SUGGESTION_TYPE.REGEX,
|
|
208
|
+
requires: createDefaultRequires(),
|
|
209
|
+
range: pos({ start: index }, { fill: true })
|
|
210
|
+
});
|
|
211
|
+
break;
|
|
212
|
+
case TOKEN_TYPE.OP_CUSTOM:
|
|
213
|
+
case TOKEN_TYPE.BRACKETL:
|
|
214
|
+
case TOKEN_TYPE.NOT:
|
|
215
|
+
unreachable();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const prevVar = (_g = token.valid.prev) == null ? void 0 : _g.parent;
|
|
220
|
+
const nextVar = (_h = token.valid.next) == null ? void 0 : _h.parent;
|
|
221
|
+
const prevCondition = prevVar == null ? void 0 : prevVar.parent;
|
|
222
|
+
const nextCondition = nextVar == null ? void 0 : nextVar.parent;
|
|
223
|
+
const atVar = (_i = token.at) == null ? void 0 : _i.parent;
|
|
224
|
+
const atCondition = atVar == null ? void 0 : atVar.parent;
|
|
225
|
+
const isVarPrev = !token.whitespace.prev && ((_j = token.valid.prev) == null ? void 0 : _j.type) !== TOKEN_TYPE.REGEX && prevVar instanceof VariableNode && (prevCondition instanceof ConditionNode && prevCondition.value === prevVar && (((_k = prevVar.quote) == null ? void 0 : _k.right) === token.valid.prev || prevVar.value === token.valid.prev) || prevCondition instanceof ArrayNode);
|
|
226
|
+
const isVarNext = !token.whitespace.next && ((_l = token.valid.next) == null ? void 0 : _l.type) !== TOKEN_TYPE.REGEX && nextVar instanceof VariableNode && (nextCondition instanceof ConditionNode && nextCondition.value === nextVar && (((_m = nextVar.quote) == null ? void 0 : _m.left) === token.valid.next || nextVar.value === token.valid.next) || nextCondition instanceof ArrayNode);
|
|
227
|
+
const isVarAt = atVar instanceof VariableNode && atCondition instanceof ConditionNode || prevVar instanceof VariableNode && token.valid.prev === ((_n = prevVar == null ? void 0 : prevVar.quote) == null ? void 0 : _n.left) || nextVar instanceof VariableNode && token.valid.next === ((_o = nextVar == null ? void 0 : nextVar.quote) == null ? void 0 : _o.right);
|
|
228
|
+
const isPropertyPrev = prevCondition instanceof ConditionNode && prevVar !== void 0 && prevVar === (prevCondition == null ? void 0 : prevCondition.property);
|
|
229
|
+
const isPropertyNext = nextCondition instanceof ConditionNode && nextVar !== void 0 && nextVar === (nextCondition == null ? void 0 : nextCondition.property);
|
|
230
|
+
const isPropertyAt = atCondition instanceof ConditionNode && atVar !== void 0 && atVar === (atCondition == null ? void 0 : atCondition.property);
|
|
231
|
+
const isPropertyOperatorPrev = prevVar instanceof ConditionNode && token.valid.prev === (prevVar == null ? void 0 : prevVar.propertyOperator);
|
|
232
|
+
const isPropertyOperatorNext = nextVar instanceof ConditionNode && token.valid.next === (nextVar == null ? void 0 : nextVar.propertyOperator);
|
|
233
|
+
const isPropertyOperatorAt = atVar instanceof ConditionNode && token.at === (atVar == null ? void 0 : atVar.propertyOperator);
|
|
234
|
+
const noArrayValuesTarget = ((_p = token.valid.prev) == null ? void 0 : _p.type) === TOKEN_TYPE.BRACKETL && (token.valid.next === void 0 || ((_q = token.valid.next) == null ? void 0 : _q.type) === TOKEN_TYPE.BRACKETR);
|
|
235
|
+
const target = isVarPrev ? token.valid.prev : !noArrayValuesTarget && !isPropertyPrev && !isPropertyOperatorPrev && isVarNext ? token.valid.next : isVarAt ? token.at : void 0;
|
|
236
|
+
const propertyTarget = isPropertyPrev ? token.valid.prev : !noArrayValuesTarget && !isVarPrev && !isPropertyOperatorPrev && isPropertyNext ? token.valid.next : isPropertyAt ? token.at : void 0;
|
|
237
|
+
const propOpTarget = isPropertyOperatorPrev ? token.valid.prev : !noArrayValuesTarget && !isVarPrev && !isPropertyPrev && isPropertyOperatorNext ? token.valid.next : isPropertyOperatorAt ? token.at : void 0;
|
|
238
|
+
if (target) {
|
|
239
|
+
const parent = target.parent;
|
|
240
|
+
if (parent instanceof VariableNode) {
|
|
241
|
+
const range = pos(parent);
|
|
242
|
+
const condition = parent == null ? void 0 : parent.parent;
|
|
243
|
+
const isValue = condition.propertyOperator !== void 0 && condition.value === parent;
|
|
244
|
+
const maybeGroup = (_r = parent == null ? void 0 : parent.parent) == null ? void 0 : _r.parent;
|
|
245
|
+
const isPrefix = maybeGroup instanceof GroupNode && maybeGroup.prefix === condition;
|
|
246
|
+
const varStart = getCursorInfo(input, ast, parent.start);
|
|
247
|
+
const varEnd = getCursorInfo(input, ast, parent.end);
|
|
248
|
+
const targetRequiresWhitespacePrev = tokenRequiresWhitespace(varStart.valid.prev, varStart.whitespace.prev, wordOps);
|
|
249
|
+
const targetRequiresWhitespaceNext = tokenRequiresWhitespace(varEnd.valid.next, varEnd.whitespace.next, wordOps);
|
|
250
|
+
const prefixedValue = target.parent instanceof VariableNode ? (_t = (_s = target.parent) == null ? void 0 : _s.prefix) == null ? void 0 : _t.value : false;
|
|
251
|
+
const isSepPrev = ((_u = token.prev) == null ? void 0 : _u.type) === TOKEN_TYPE.OP_EXPANDED_SEP;
|
|
252
|
+
const arrayValue = ((_v = target.parent) == null ? void 0 : _v.parent) instanceof ArrayNode;
|
|
253
|
+
const isRegexFlag = target === ((_w = parent.quote) == null ? void 0 : _w.flags);
|
|
254
|
+
if (!isRegexFlag && !isSepPrev && !isValue && !arrayValue && !prefixedValue && opts.prefixableGroups) {
|
|
255
|
+
suggestions.push({
|
|
256
|
+
...baseSuggestion,
|
|
257
|
+
type: SUGGESTION_TYPE.PREFIX,
|
|
258
|
+
requires: createDefaultRequires({
|
|
259
|
+
group: !isPrefix,
|
|
260
|
+
whitespace: {
|
|
261
|
+
before: targetRequiresWhitespacePrev && !isPrefix,
|
|
262
|
+
after: false
|
|
263
|
+
// parens exist or get inserted
|
|
264
|
+
}
|
|
265
|
+
}),
|
|
266
|
+
range
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
if (!isRegexFlag && !isPrefix) {
|
|
270
|
+
suggestions.push({
|
|
271
|
+
...baseSuggestion,
|
|
272
|
+
type: arrayValue ? SUGGESTION_TYPE.ARRAY_VALUE : isValue ? SUGGESTION_TYPE.VALUE : SUGGESTION_TYPE.VARIABLE,
|
|
273
|
+
requires: createDefaultRequires({
|
|
274
|
+
whitespace: {
|
|
275
|
+
before: targetRequiresWhitespacePrev,
|
|
276
|
+
after: targetRequiresWhitespaceNext
|
|
277
|
+
},
|
|
278
|
+
prefix: prefixedValue
|
|
279
|
+
}),
|
|
280
|
+
range
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (noArrayValuesTarget) {
|
|
286
|
+
suggestions.push({
|
|
287
|
+
...baseSuggestion,
|
|
288
|
+
type: SUGGESTION_TYPE.ARRAY_VALUE,
|
|
289
|
+
requires: createDefaultRequires(),
|
|
290
|
+
range: pos({ start: index }, { fill: true })
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (propertyTarget) {
|
|
294
|
+
suggestions.push({
|
|
295
|
+
...baseSuggestion,
|
|
296
|
+
type: SUGGESTION_TYPE.PROPERTY,
|
|
297
|
+
requires: createDefaultRequires(),
|
|
298
|
+
range: pos(propertyTarget)
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (propOpTarget) {
|
|
302
|
+
suggestions.push({
|
|
303
|
+
...baseSuggestion,
|
|
304
|
+
type: propOpTarget.parent.sep ? SUGGESTION_TYPE.EXPANDED_PROPERTY_OPERATOR : SUGGESTION_TYPE.CUSTOM_PROPERTY_OPERATOR,
|
|
305
|
+
requires: createDefaultRequires(),
|
|
306
|
+
range: pos(propOpTarget)
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
const canSuggestValue = token.whitespace.next && (token.whitespace.prev || ((_x = token.prev) == null ? void 0 : _x.type) === TOKEN_TYPE.BRACKETL || ((_y = token.prev) == null ? void 0 : _y.type) === TOKEN_TYPE.PARENL) || token.whitespace.prev && (token.whitespace.next || ((_z = token.next) == null ? void 0 : _z.type) === TOKEN_TYPE.BRACKETR || ((_A = token.next) == null ? void 0 : _A.type) === TOKEN_TYPE.PARENR);
|
|
310
|
+
if (canSuggestValue) {
|
|
311
|
+
const inArrayNode = [nextCondition, prevCondition, nextVar, prevVar].find((_) => _ instanceof ArrayNode) !== void 0;
|
|
312
|
+
const opsNotNeeded = ["and", "or"].includes(opts.onMissingBooleanOperator);
|
|
313
|
+
if (inArrayNode || opsNotNeeded) {
|
|
314
|
+
suggestions.push({
|
|
315
|
+
type: inArrayNode ? SUGGESTION_TYPE.ARRAY_VALUE : SUGGESTION_TYPE.VARIABLE,
|
|
316
|
+
requires: createDefaultRequires({}),
|
|
317
|
+
range: pos({ start: index }, { fill: true }),
|
|
318
|
+
...baseSuggestion
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
if (!inArrayNode && opsNotNeeded) {
|
|
322
|
+
suggestions.push({
|
|
323
|
+
...baseSuggestion,
|
|
324
|
+
type: SUGGESTION_TYPE.PREFIX,
|
|
325
|
+
requires: createDefaultRequires({
|
|
326
|
+
group: true
|
|
327
|
+
}),
|
|
328
|
+
range: pos({ start: index }, { fill: true })
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const canSuggestRegexFlags = (
|
|
333
|
+
// has existing flags before/after
|
|
334
|
+
token.at && token.at === ((_D = (_C = (_B = token.at) == null ? void 0 : _B.parent) == null ? void 0 : _C.quote) == null ? void 0 : _D.flags) || token.valid.prev && token.valid.prev === ((_G = (_F = (_E = token.valid.prev) == null ? void 0 : _E.parent) == null ? void 0 : _F.quote) == null ? void 0 : _G.flags) || token.valid.next && token.valid.next === ((_J = (_I = (_H = token.valid.next) == null ? void 0 : _H.parent) == null ? void 0 : _I.quote) == null ? void 0 : _J.flags) || // no flags
|
|
335
|
+
((_K = token.valid.prev) == null ? void 0 : _K.type) === TOKEN_TYPE.REGEX && token.valid.prev === ((_L = token.valid.prev.parent.quote) == null ? void 0 : _L.right)
|
|
336
|
+
);
|
|
337
|
+
if (canSuggestRegexFlags) {
|
|
338
|
+
suggestions.push({
|
|
339
|
+
...baseSuggestion,
|
|
340
|
+
type: SUGGESTION_TYPE.REGEX_FLAGS,
|
|
341
|
+
requires: createDefaultRequires(),
|
|
342
|
+
range: pos({ start: index }, { fill: true })
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
if (canSuggestOpAfterPrev || canSuggestOpBeforeNext) {
|
|
346
|
+
const range = pos({ start: index }, { fill: true });
|
|
347
|
+
suggestions.push({
|
|
348
|
+
...baseSuggestion,
|
|
349
|
+
type: SUGGESTION_TYPE.BOOLEAN_SYMBOL_OP,
|
|
350
|
+
requires: createDefaultRequires(),
|
|
351
|
+
range
|
|
352
|
+
});
|
|
353
|
+
suggestions.push({
|
|
354
|
+
...baseSuggestion,
|
|
355
|
+
type: SUGGESTION_TYPE.BOOLEAN_WORD_OP,
|
|
356
|
+
requires: createDefaultRequires({
|
|
357
|
+
whitespace: {
|
|
358
|
+
before: requiresWhitespacePrevOp,
|
|
359
|
+
after: requireWhitespaceNextOp
|
|
360
|
+
}
|
|
361
|
+
}),
|
|
362
|
+
range
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return suggestions;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
export {
|
|
370
|
+
Autosuggest
|
|
371
|
+
};
|