lang-feel 1.1.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/completion.d.ts +20 -0
- package/dist/feel.d.ts +26 -0
- package/dist/index.cjs +216 -98
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +3 -14
- package/dist/index.js +225 -99
- package/dist/index.js.map +1 -0
- package/dist/snippets.d.ts +5 -0
- package/package.json +34 -20
- package/dist/index.d.cts +0 -14
package/README.md
CHANGED
|
@@ -8,4 +8,9 @@ This package implements the [DMN](https://www.omg.org/spec/DMN/) FEEL language s
|
|
|
8
8
|
## Related
|
|
9
9
|
|
|
10
10
|
* [lezer-feel](https://github.com/nikku/lezer-feel) - FEEL grammar
|
|
11
|
-
* [feelin](https://github.com/nikku/feelin) - FEEL parser + interpreter
|
|
11
|
+
* [feelin](https://github.com/nikku/feelin) - FEEL parser + interpreter
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## License
|
|
15
|
+
|
|
16
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SyntaxNode } from '@lezer/common';
|
|
2
|
+
import { CompletionSource, Completion } from '@codemirror/autocomplete';
|
|
3
|
+
export declare function contextualKeyword(options: {
|
|
4
|
+
before?: string;
|
|
5
|
+
after?: string;
|
|
6
|
+
context: string;
|
|
7
|
+
keyword: string;
|
|
8
|
+
}): CompletionSource;
|
|
9
|
+
export declare const keywordCompletions: CompletionSource[];
|
|
10
|
+
export declare const dontComplete: string[];
|
|
11
|
+
export declare function snippetCompletion(snippets: readonly Completion[]): CompletionSource;
|
|
12
|
+
export declare function matchLeft(node: SyntaxNode, position: number, nodes: (string | undefined)[]): SyntaxNode | null;
|
|
13
|
+
export declare function matchRight(node: SyntaxNode, position: number, nodes: (string | undefined)[]): SyntaxNode | null;
|
|
14
|
+
export declare function matchChildren(node: SyntaxNode, position: number, nodes: (string | undefined)[], direction: 1 | -1): SyntaxNode | null;
|
|
15
|
+
export declare function ifInside(options: {
|
|
16
|
+
nodes: string | string[];
|
|
17
|
+
keyword: string;
|
|
18
|
+
before?: string;
|
|
19
|
+
after?: string;
|
|
20
|
+
}, source: CompletionSource): CompletionSource;
|
package/dist/feel.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LRLanguage, LanguageSupport } from '@codemirror/language';
|
|
2
|
+
import { CompletionSource } from '@codemirror/autocomplete';
|
|
3
|
+
/**
|
|
4
|
+
* A FEEL language provider based on the
|
|
5
|
+
* [Lezer FEEL parser](https://github.com/nikku/lezer-feel),
|
|
6
|
+
* extended with highlighting and indentation information.
|
|
7
|
+
*/
|
|
8
|
+
export declare const feelLanguage: LRLanguage;
|
|
9
|
+
/**
|
|
10
|
+
* A language provider for FEEL Unary Tests
|
|
11
|
+
*/
|
|
12
|
+
export declare const unaryTestsLanguage: LRLanguage;
|
|
13
|
+
/**
|
|
14
|
+
* Language provider for FEEL Expression
|
|
15
|
+
*/
|
|
16
|
+
export declare const expressionLanguage: LRLanguage;
|
|
17
|
+
/**
|
|
18
|
+
* Feel language support for CodeMirror.
|
|
19
|
+
*
|
|
20
|
+
* Includes [snippet](#lang-feel.snippets)
|
|
21
|
+
*/
|
|
22
|
+
export declare function feel(config?: {
|
|
23
|
+
dialect?: 'expression' | 'unaryTests';
|
|
24
|
+
completions?: CompletionSource[];
|
|
25
|
+
context?: Record<string, any>;
|
|
26
|
+
}): LanguageSupport;
|
package/dist/index.cjs
CHANGED
|
@@ -1,114 +1,232 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
var lezerFeel = require('lezer-feel');
|
|
4
2
|
var language = require('@codemirror/language');
|
|
5
3
|
var autocomplete = require('@codemirror/autocomplete');
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
5
|
+
/**
|
|
6
|
+
* A collection of FEEL-related [snippets](#autocomplete.snippet).
|
|
7
|
+
*/
|
|
8
|
+
const snippets = [autocomplete.snippetCompletion('function(${params}) ${body}', {
|
|
9
|
+
label: 'function',
|
|
10
|
+
detail: 'definition',
|
|
11
|
+
type: 'keyword'
|
|
12
|
+
}), autocomplete.snippetCompletion('for ${var} in ${collection} return ${value}', {
|
|
13
|
+
label: 'for',
|
|
14
|
+
detail: 'expression',
|
|
15
|
+
type: 'keyword'
|
|
16
|
+
}), autocomplete.snippetCompletion('every ${var} in ${collection} satisfies ${condition}', {
|
|
17
|
+
label: 'every',
|
|
18
|
+
detail: 'quantified expression',
|
|
19
|
+
type: 'keyword'
|
|
20
|
+
}), autocomplete.snippetCompletion('some ${var} in ${collection} satisfies ${condition}', {
|
|
21
|
+
label: 'some',
|
|
22
|
+
detail: 'quantified expression',
|
|
23
|
+
type: 'keyword'
|
|
24
|
+
}), autocomplete.snippetCompletion('if ${condition} then ${value} else ${other value}', {
|
|
25
|
+
label: 'if',
|
|
26
|
+
detail: 'block',
|
|
27
|
+
type: 'keyword'
|
|
28
|
+
}), autocomplete.snippetCompletion('{ ${key}: ${value} }', {
|
|
29
|
+
label: 'context',
|
|
30
|
+
detail: 'block',
|
|
31
|
+
type: 'keyword'
|
|
32
|
+
})];
|
|
33
|
+
|
|
34
|
+
function contextualKeyword(options) {
|
|
35
|
+
const {
|
|
36
|
+
context: nodes,
|
|
37
|
+
after,
|
|
38
|
+
before,
|
|
39
|
+
keyword
|
|
40
|
+
} = options;
|
|
41
|
+
return ifInside({
|
|
42
|
+
nodes,
|
|
43
|
+
before,
|
|
44
|
+
after,
|
|
45
|
+
keyword
|
|
46
|
+
}, autocomplete.completeFromList([{
|
|
47
|
+
label: keyword,
|
|
48
|
+
type: 'keyword',
|
|
49
|
+
boost: 10
|
|
50
|
+
}]));
|
|
51
|
+
}
|
|
52
|
+
const keywordCompletions = [contextualKeyword({
|
|
53
|
+
context: 'InExpression',
|
|
54
|
+
keyword: 'in'
|
|
55
|
+
}), contextualKeyword({
|
|
56
|
+
context: 'IfExpression',
|
|
57
|
+
keyword: 'then',
|
|
58
|
+
after: 'if',
|
|
59
|
+
before: 'else'
|
|
60
|
+
}), contextualKeyword({
|
|
61
|
+
context: 'IfExpression',
|
|
62
|
+
keyword: 'else',
|
|
63
|
+
after: 'then'
|
|
64
|
+
}), contextualKeyword({
|
|
65
|
+
context: 'QuantifiedExpression',
|
|
66
|
+
keyword: 'satisfies'
|
|
67
|
+
}), contextualKeyword({
|
|
68
|
+
context: 'ForExpression',
|
|
69
|
+
after: 'InExpressions',
|
|
70
|
+
keyword: 'return'
|
|
71
|
+
})];
|
|
72
|
+
const dontComplete = ['StringLiteral', 'Identifier', 'LineComment', 'BlockComment'];
|
|
73
|
+
function snippetCompletion(snippets) {
|
|
74
|
+
return autocomplete.ifNotIn(dontComplete, autocomplete.completeFromList(snippets.map(s => ({
|
|
75
|
+
...s,
|
|
76
|
+
type: 'text'
|
|
77
|
+
}))));
|
|
78
|
+
}
|
|
79
|
+
function matchLeft(node, position, nodes) {
|
|
80
|
+
return matchChildren(node, position, nodes, -1);
|
|
81
|
+
}
|
|
82
|
+
function matchRight(node, position, nodes) {
|
|
83
|
+
return matchChildren(node, position, nodes, 1);
|
|
84
|
+
}
|
|
85
|
+
function matchChildren(node, position, nodes, direction) {
|
|
86
|
+
let child = node[direction > 0 ? 'childAfter' : 'childBefore'](position);
|
|
87
|
+
while (child) {
|
|
88
|
+
if (nodes.includes(child.name)) {
|
|
89
|
+
return child;
|
|
90
|
+
}
|
|
91
|
+
if (child.type.isError && child.firstChild) {
|
|
92
|
+
if (nodes.includes(child.firstChild.name)) {
|
|
93
|
+
return child.firstChild;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
child = child[direction > 0 ? 'nextSibling' : 'prevSibling'];
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function matchUp(node, nodeNames) {
|
|
101
|
+
if (!Array.isArray(nodeNames)) {
|
|
102
|
+
nodeNames = [nodeNames];
|
|
103
|
+
}
|
|
104
|
+
for (; node; node = node.parent) {
|
|
105
|
+
if (nodeNames.includes(node.name)) {
|
|
106
|
+
return node;
|
|
107
|
+
}
|
|
108
|
+
if (node.type.isTop) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
function ifInside(options, source) {
|
|
115
|
+
const {
|
|
116
|
+
nodes,
|
|
117
|
+
before,
|
|
118
|
+
after,
|
|
119
|
+
keyword
|
|
120
|
+
} = options;
|
|
121
|
+
return context => {
|
|
122
|
+
const {
|
|
123
|
+
state,
|
|
124
|
+
pos
|
|
125
|
+
} = context;
|
|
126
|
+
const node = matchUp(language.syntaxTree(state).resolveInner(pos, -1), nodes);
|
|
127
|
+
if (!node) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
if (matchLeft(node, pos, [keyword, before])) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
if (matchRight(node, pos, [keyword, after])) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
if (after && !matchLeft(node, pos, [after])) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
return source(context);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
36
142
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
143
|
+
/**
|
|
144
|
+
* A FEEL language provider based on the
|
|
145
|
+
* [Lezer FEEL parser](https://github.com/nikku/lezer-feel),
|
|
146
|
+
* extended with highlighting and indentation information.
|
|
147
|
+
*/
|
|
40
148
|
const feelLanguage = language.LRLanguage.define({
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
block: {
|
|
81
|
-
open: '/*',
|
|
82
|
-
close: '*/'
|
|
83
|
-
}
|
|
84
|
-
}
|
|
149
|
+
parser: lezerFeel.parser.configure({
|
|
150
|
+
props: [language.indentNodeProp.add({
|
|
151
|
+
'Context': language.delimitedIndent({
|
|
152
|
+
closing: '}'
|
|
153
|
+
}),
|
|
154
|
+
'List FilterExpression': language.delimitedIndent({
|
|
155
|
+
closing: ']'
|
|
156
|
+
}),
|
|
157
|
+
'ParenthesizedExpression FunctionInvocation': language.continuedIndent({
|
|
158
|
+
except: /^\s*\)/
|
|
159
|
+
}),
|
|
160
|
+
'ForExpression QuantifiedExpression IfExpression': language.continuedIndent({
|
|
161
|
+
except: /^\s*(then|else|return|satisfies)\b/
|
|
162
|
+
}),
|
|
163
|
+
'FunctionDefinition': language.continuedIndent({
|
|
164
|
+
except: /^\s*(\(|\))/
|
|
165
|
+
})
|
|
166
|
+
}), language.foldNodeProp.add({
|
|
167
|
+
Context: language.foldInside,
|
|
168
|
+
List: language.foldInside,
|
|
169
|
+
ParenthesizedExpression: language.foldInside,
|
|
170
|
+
FunctionDefinition(node) {
|
|
171
|
+
const last = node.getChild(')');
|
|
172
|
+
if (!last) return null;
|
|
173
|
+
return {
|
|
174
|
+
from: last.to,
|
|
175
|
+
to: node.to
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
})]
|
|
179
|
+
}),
|
|
180
|
+
languageData: {
|
|
181
|
+
indentOnInput: /^\s*(\)|\}|\]|then|else|return|satisfies)$/,
|
|
182
|
+
commentTokens: {
|
|
183
|
+
line: '//',
|
|
184
|
+
block: {
|
|
185
|
+
open: '/*',
|
|
186
|
+
close: '*/'
|
|
187
|
+
}
|
|
85
188
|
}
|
|
189
|
+
}
|
|
86
190
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
191
|
+
/**
|
|
192
|
+
* A language provider for FEEL Unary Tests
|
|
193
|
+
*/
|
|
194
|
+
const unaryTestsLanguage = feelLanguage.configure({
|
|
195
|
+
top: 'UnaryTests'
|
|
196
|
+
}, 'FEEL unary tests');
|
|
197
|
+
/**
|
|
198
|
+
* Language provider for FEEL Expression
|
|
199
|
+
*/
|
|
200
|
+
const expressionLanguage = feelLanguage.configure({
|
|
201
|
+
top: 'Expression'
|
|
202
|
+
}, 'FEEL expression');
|
|
203
|
+
/**
|
|
204
|
+
* Feel language support for CodeMirror.
|
|
205
|
+
*
|
|
206
|
+
* Includes [snippet](#lang-feel.snippets)
|
|
207
|
+
*/
|
|
98
208
|
function feel(config = {}) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
]);
|
|
209
|
+
const lang = config.dialect === 'unaryTests' ? unaryTestsLanguage : expressionLanguage;
|
|
210
|
+
const contextualLang = lang.configure({
|
|
211
|
+
contextTracker: lezerFeel.trackVariables(config.context)
|
|
212
|
+
});
|
|
213
|
+
const completions = config.completions || [snippetCompletion(snippets), keywordCompletions].flat();
|
|
214
|
+
return new language.LanguageSupport(contextualLang, [...completions.map(autocomplete => contextualLang.data.of({
|
|
215
|
+
autocomplete
|
|
216
|
+
}))]);
|
|
108
217
|
}
|
|
109
218
|
|
|
219
|
+
exports.contextualKeyword = contextualKeyword;
|
|
220
|
+
exports.dontComplete = dontComplete;
|
|
110
221
|
exports.expressionLanguage = expressionLanguage;
|
|
111
222
|
exports.feel = feel;
|
|
112
223
|
exports.feelLanguage = feelLanguage;
|
|
224
|
+
exports.ifInside = ifInside;
|
|
225
|
+
exports.keywordCompletions = keywordCompletions;
|
|
226
|
+
exports.matchChildren = matchChildren;
|
|
227
|
+
exports.matchLeft = matchLeft;
|
|
228
|
+
exports.matchRight = matchRight;
|
|
229
|
+
exports.snippetCompletion = snippetCompletion;
|
|
113
230
|
exports.snippets = snippets;
|
|
114
231
|
exports.unaryTestsLanguage = unaryTestsLanguage;
|
|
232
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/snippets.ts","../src/completion.ts","../src/feel.ts"],"sourcesContent":["import { Completion, snippetCompletion } from '@codemirror/autocomplete';\n\n/**\n * A collection of FEEL-related [snippets](#autocomplete.snippet).\n */\nexport const snippets: readonly Completion[] = [\n snippetCompletion('function(${params}) ${body}', {\n label: 'function',\n detail: 'definition',\n type: 'keyword'\n }),\n snippetCompletion('for ${var} in ${collection} return ${value}', {\n label: 'for',\n detail: 'expression',\n type: 'keyword'\n }),\n snippetCompletion('every ${var} in ${collection} satisfies ${condition}', {\n label: 'every',\n detail: 'quantified expression',\n type: 'keyword'\n }),\n snippetCompletion('some ${var} in ${collection} satisfies ${condition}', {\n label: 'some',\n detail: 'quantified expression',\n type: 'keyword'\n }),\n snippetCompletion('if ${condition} then ${value} else ${other value}', {\n label: 'if',\n detail: 'block',\n type: 'keyword'\n }),\n snippetCompletion('{ ${key}: ${value} }', {\n label: 'context',\n detail: 'block',\n type: 'keyword'\n })\n];\n","import { syntaxTree } from '@codemirror/language';\nimport { SyntaxNode } from '@lezer/common';\n\nimport {\n CompletionSource,\n Completion,\n completeFromList,\n ifNotIn\n} from '@codemirror/autocomplete';\n\n\nexport function contextualKeyword(options: {\n before?: string,\n after?: string,\n context: string,\n keyword: string\n}) : CompletionSource {\n\n const {\n context: nodes,\n after,\n before,\n keyword\n } = options;\n\n return ifInside({ nodes, before, after, keyword }, completeFromList([\n { label: keyword, type: 'keyword', boost: 10 }\n ]));\n}\n\nexport const keywordCompletions = [\n contextualKeyword({\n context: 'InExpression',\n keyword: 'in'\n }),\n contextualKeyword({\n context: 'IfExpression',\n keyword: 'then',\n after: 'if',\n before: 'else'\n }),\n contextualKeyword({\n context: 'IfExpression',\n keyword: 'else',\n after: 'then'\n }),\n contextualKeyword({\n context: 'QuantifiedExpression',\n keyword: 'satisfies'\n }),\n contextualKeyword({\n context: 'ForExpression',\n after: 'InExpressions',\n keyword: 'return'\n })\n];\n\nexport const dontComplete = [\n 'StringLiteral', 'Identifier',\n 'LineComment', 'BlockComment'\n];\n\nexport function snippetCompletion(snippets: readonly Completion[]) : CompletionSource {\n return ifNotIn(\n dontComplete, completeFromList(snippets.map(s => ({ ...s, type: 'text' })))\n );\n}\n\nexport function matchLeft(node: SyntaxNode, position: number, nodes: (string|undefined)[]) : SyntaxNode | null {\n return matchChildren(node, position, nodes, -1);\n}\n\nexport function matchRight(node: SyntaxNode, position: number, nodes: (string|undefined)[]) : SyntaxNode | null {\n return matchChildren(node, position, nodes, 1);\n}\n\nexport function matchChildren(node: SyntaxNode, position: number, nodes: (string|undefined)[], direction: 1 | -1) : SyntaxNode | null {\n\n let child = node[direction > 0 ? 'childAfter' : 'childBefore'](position);\n\n while (child) {\n if (nodes.includes(child.name)) {\n return child;\n }\n\n if (child.type.isError && child.firstChild) {\n if (nodes.includes(child.firstChild.name)) {\n return child.firstChild;\n }\n }\n\n child = child[direction > 0 ? 'nextSibling' : 'prevSibling'];\n }\n\n return null;\n}\n\nfunction matchUp(node: SyntaxNode, nodeNames: string | undefined | (string | undefined)[]) {\n\n if (!Array.isArray(nodeNames)) {\n nodeNames = [ nodeNames ];\n }\n\n for (; node; node = node.parent!) {\n if (nodeNames.includes(node.name)) {\n return node;\n }\n\n if (node.type.isTop) {\n break;\n }\n }\n\n return null;\n}\n\nexport function ifInside(options: {\n nodes: string | string[],\n keyword: string,\n before?: string,\n after?: string\n}, source: CompletionSource): CompletionSource {\n\n const {\n nodes,\n before,\n after,\n keyword\n } = options;\n\n return (context) => {\n\n const { state, pos } = context;\n\n const node = matchUp(syntaxTree(state).resolveInner(pos, -1), nodes);\n\n if (!node) {\n return null;\n }\n\n if (matchLeft(node, pos, [ keyword, before ])) {\n return null;\n }\n\n if (matchRight(node, pos, [ keyword, after ])) {\n return null;\n }\n\n if (after && !matchLeft(node, pos, [ after ])) {\n return null;\n }\n\n return source(context);\n };\n}","import {\n parser,\n trackVariables\n} from 'lezer-feel';\n\nimport {\n LRLanguage,\n LanguageSupport,\n delimitedIndent,\n continuedIndent,\n indentNodeProp,\n foldNodeProp,\n foldInside\n} from '@codemirror/language';\n\nimport {\n snippets\n} from './snippets';\n\nimport {\n keywordCompletions,\n snippetCompletion\n} from './completion';\n\nimport {\n CompletionSource\n} from '@codemirror/autocomplete';\n\n\n/**\n * A FEEL language provider based on the\n * [Lezer FEEL parser](https://github.com/nikku/lezer-feel),\n * extended with highlighting and indentation information.\n */\nexport const feelLanguage = LRLanguage.define({\n parser: parser.configure({\n props: [\n indentNodeProp.add({\n 'Context': delimitedIndent({\n closing: '}'\n }),\n 'List FilterExpression': delimitedIndent({\n closing: ']'\n }),\n 'ParenthesizedExpression FunctionInvocation': continuedIndent({\n except: /^\\s*\\)/\n }),\n 'ForExpression QuantifiedExpression IfExpression': continuedIndent({\n except: /^\\s*(then|else|return|satisfies)\\b/\n }),\n 'FunctionDefinition': continuedIndent({\n except: /^\\s*(\\(|\\))/\n })\n }),\n foldNodeProp.add({\n Context: foldInside,\n List: foldInside,\n ParenthesizedExpression: foldInside,\n FunctionDefinition(node) {\n const last = node.getChild(')');\n\n if (!last) return null;\n\n return {\n from: last.to,\n to: node.to\n };\n }\n })\n ]\n }),\n languageData: {\n indentOnInput: /^\\s*(\\)|\\}|\\]|then|else|return|satisfies)$/,\n commentTokens: {\n line: '//',\n block: {\n open: '/*',\n close: '*/'\n }\n }\n }\n});\n\n/**\n * A language provider for FEEL Unary Tests\n */\nexport const unaryTestsLanguage = feelLanguage.configure({\n top: 'UnaryTests',\n}, 'FEEL unary tests');\n\n/**\n * Language provider for FEEL Expression\n */\nexport const expressionLanguage = feelLanguage.configure({\n top: 'Expression'\n}, 'FEEL expression');\n\n\n\n/**\n * Feel language support for CodeMirror.\n *\n * Includes [snippet](#lang-feel.snippets)\n */\nexport function feel(config: {\n dialect?: 'expression' | 'unaryTests',\n completions?: CompletionSource[],\n context?: Record<string, any>\n} = {}) {\n const lang = config.dialect === 'unaryTests' ? unaryTestsLanguage : expressionLanguage;\n\n const contextualLang = lang.configure({\n contextTracker: trackVariables(config.context)\n });\n\n const completions = config.completions || [\n snippetCompletion(snippets),\n keywordCompletions,\n ].flat();\n\n return new LanguageSupport(contextualLang, [\n ...(\n completions.map(autocomplete => contextualLang.data.of({\n autocomplete\n }))\n )\n ]);\n\n}"],"names":["snippets","snippetCompletion","label","detail","type","contextualKeyword","options","context","nodes","after","before","keyword","ifInside","completeFromList","boost","keywordCompletions","dontComplete","ifNotIn","map","s","matchLeft","node","position","matchChildren","matchRight","direction","child","includes","name","isError","firstChild","matchUp","nodeNames","Array","isArray","parent","isTop","source","state","pos","syntaxTree","resolveInner","feelLanguage","LRLanguage","define","parser","configure","props","indentNodeProp","add","delimitedIndent","closing","continuedIndent","except","foldNodeProp","Context","foldInside","List","ParenthesizedExpression","FunctionDefinition","last","getChild","from","to","languageData","indentOnInput","commentTokens","line","block","open","close","unaryTestsLanguage","top","expressionLanguage","feel","config","lang","dialect","contextualLang","contextTracker","trackVariables","completions","flat","LanguageSupport","autocomplete","data","of"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
declare const feelLanguage: LRLanguage;
|
|
5
|
-
declare const unaryTestsLanguage: LRLanguage;
|
|
6
|
-
declare const expressionLanguage: LRLanguage;
|
|
7
|
-
declare function feel(config?: {
|
|
8
|
-
dialect?: 'expression' | 'unaryTests';
|
|
9
|
-
context?: Record<string, any>;
|
|
10
|
-
}): LanguageSupport;
|
|
11
|
-
|
|
12
|
-
declare const snippets: readonly Completion[];
|
|
13
|
-
|
|
14
|
-
export { expressionLanguage, feel, feelLanguage, snippets, unaryTestsLanguage };
|
|
1
|
+
export { feel, feelLanguage, expressionLanguage, unaryTestsLanguage } from './feel';
|
|
2
|
+
export { snippets } from './snippets';
|
|
3
|
+
export * from './completion';
|
package/dist/index.js
CHANGED
|
@@ -1,108 +1,234 @@
|
|
|
1
1
|
import { parser, trackVariables } from 'lezer-feel';
|
|
2
|
-
import { LRLanguage, indentNodeProp, delimitedIndent, continuedIndent, foldNodeProp, foldInside, LanguageSupport } from '@codemirror/language';
|
|
3
|
-
import { snippetCompletion
|
|
2
|
+
import { syntaxTree, LRLanguage, indentNodeProp, delimitedIndent, continuedIndent, foldNodeProp, foldInside, LanguageSupport } from '@codemirror/language';
|
|
3
|
+
import { snippetCompletion as snippetCompletion$1, completeFromList, ifNotIn } from '@codemirror/autocomplete';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
];
|
|
5
|
+
/**
|
|
6
|
+
* A collection of FEEL-related [snippets](#autocomplete.snippet).
|
|
7
|
+
*/
|
|
8
|
+
const snippets = [snippetCompletion$1('function(${params}) ${body}', {
|
|
9
|
+
label: 'function',
|
|
10
|
+
detail: 'definition',
|
|
11
|
+
type: 'keyword'
|
|
12
|
+
}), snippetCompletion$1('for ${var} in ${collection} return ${value}', {
|
|
13
|
+
label: 'for',
|
|
14
|
+
detail: 'expression',
|
|
15
|
+
type: 'keyword'
|
|
16
|
+
}), snippetCompletion$1('every ${var} in ${collection} satisfies ${condition}', {
|
|
17
|
+
label: 'every',
|
|
18
|
+
detail: 'quantified expression',
|
|
19
|
+
type: 'keyword'
|
|
20
|
+
}), snippetCompletion$1('some ${var} in ${collection} satisfies ${condition}', {
|
|
21
|
+
label: 'some',
|
|
22
|
+
detail: 'quantified expression',
|
|
23
|
+
type: 'keyword'
|
|
24
|
+
}), snippetCompletion$1('if ${condition} then ${value} else ${other value}', {
|
|
25
|
+
label: 'if',
|
|
26
|
+
detail: 'block',
|
|
27
|
+
type: 'keyword'
|
|
28
|
+
}), snippetCompletion$1('{ ${key}: ${value} }', {
|
|
29
|
+
label: 'context',
|
|
30
|
+
detail: 'block',
|
|
31
|
+
type: 'keyword'
|
|
32
|
+
})];
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
'Context': /*@__PURE__*/delimitedIndent({
|
|
43
|
-
closing: '}'
|
|
44
|
-
}),
|
|
45
|
-
'List FilterExpression': /*@__PURE__*/delimitedIndent({
|
|
46
|
-
closing: ']'
|
|
47
|
-
}),
|
|
48
|
-
'ParenthesizedExpression FunctionInvocation': /*@__PURE__*/continuedIndent({
|
|
49
|
-
except: /^\s*\)/
|
|
50
|
-
}),
|
|
51
|
-
'ForExpression QuantifiedExpression IfExpression': /*@__PURE__*/continuedIndent({
|
|
52
|
-
except: /^\s*(then|else|return|satisfies)\b/
|
|
53
|
-
}),
|
|
54
|
-
'FunctionDefinition': /*@__PURE__*/continuedIndent({
|
|
55
|
-
except: /^\s*(\(|\))/
|
|
56
|
-
})
|
|
57
|
-
}),
|
|
58
|
-
/*@__PURE__*/foldNodeProp.add({
|
|
59
|
-
Context: foldInside,
|
|
60
|
-
List: foldInside,
|
|
61
|
-
ParenthesizedExpression: foldInside,
|
|
62
|
-
FunctionDefinition(node) {
|
|
63
|
-
const last = node.getChild(')');
|
|
64
|
-
if (!last)
|
|
65
|
-
return null;
|
|
66
|
-
return {
|
|
67
|
-
from: last.to,
|
|
68
|
-
to: node.to
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
]
|
|
73
|
-
}),
|
|
74
|
-
languageData: {
|
|
75
|
-
indentOnInput: /^\s*(\)|\}|\]|then|else|return|satisfies)$/,
|
|
76
|
-
commentTokens: {
|
|
77
|
-
line: '//',
|
|
78
|
-
block: {
|
|
79
|
-
open: '/*',
|
|
80
|
-
close: '*/'
|
|
81
|
-
}
|
|
34
|
+
function _extends() {
|
|
35
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
36
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
37
|
+
var source = arguments[i];
|
|
38
|
+
for (var key in source) {
|
|
39
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
40
|
+
target[key] = source[key];
|
|
82
41
|
}
|
|
42
|
+
}
|
|
83
43
|
}
|
|
44
|
+
return target;
|
|
45
|
+
};
|
|
46
|
+
return _extends.apply(this, arguments);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function contextualKeyword(options) {
|
|
50
|
+
const {
|
|
51
|
+
context: nodes,
|
|
52
|
+
after,
|
|
53
|
+
before,
|
|
54
|
+
keyword
|
|
55
|
+
} = options;
|
|
56
|
+
return ifInside({
|
|
57
|
+
nodes,
|
|
58
|
+
before,
|
|
59
|
+
after,
|
|
60
|
+
keyword
|
|
61
|
+
}, completeFromList([{
|
|
62
|
+
label: keyword,
|
|
63
|
+
type: 'keyword',
|
|
64
|
+
boost: 10
|
|
65
|
+
}]));
|
|
66
|
+
}
|
|
67
|
+
const keywordCompletions = [contextualKeyword({
|
|
68
|
+
context: 'InExpression',
|
|
69
|
+
keyword: 'in'
|
|
70
|
+
}), contextualKeyword({
|
|
71
|
+
context: 'IfExpression',
|
|
72
|
+
keyword: 'then',
|
|
73
|
+
after: 'if',
|
|
74
|
+
before: 'else'
|
|
75
|
+
}), contextualKeyword({
|
|
76
|
+
context: 'IfExpression',
|
|
77
|
+
keyword: 'else',
|
|
78
|
+
after: 'then'
|
|
79
|
+
}), contextualKeyword({
|
|
80
|
+
context: 'QuantifiedExpression',
|
|
81
|
+
keyword: 'satisfies'
|
|
82
|
+
}), contextualKeyword({
|
|
83
|
+
context: 'ForExpression',
|
|
84
|
+
after: 'InExpressions',
|
|
85
|
+
keyword: 'return'
|
|
86
|
+
})];
|
|
87
|
+
const dontComplete = ['StringLiteral', 'Identifier', 'LineComment', 'BlockComment'];
|
|
88
|
+
function snippetCompletion(snippets) {
|
|
89
|
+
return ifNotIn(dontComplete, completeFromList(snippets.map(s => _extends({}, s, {
|
|
90
|
+
type: 'text'
|
|
91
|
+
}))));
|
|
92
|
+
}
|
|
93
|
+
function matchLeft(node, position, nodes) {
|
|
94
|
+
return matchChildren(node, position, nodes, -1);
|
|
95
|
+
}
|
|
96
|
+
function matchRight(node, position, nodes) {
|
|
97
|
+
return matchChildren(node, position, nodes, 1);
|
|
98
|
+
}
|
|
99
|
+
function matchChildren(node, position, nodes, direction) {
|
|
100
|
+
let child = node[direction > 0 ? 'childAfter' : 'childBefore'](position);
|
|
101
|
+
while (child) {
|
|
102
|
+
if (nodes.includes(child.name)) {
|
|
103
|
+
return child;
|
|
104
|
+
}
|
|
105
|
+
if (child.type.isError && child.firstChild) {
|
|
106
|
+
if (nodes.includes(child.firstChild.name)) {
|
|
107
|
+
return child.firstChild;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
child = child[direction > 0 ? 'nextSibling' : 'prevSibling'];
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
function matchUp(node, nodeNames) {
|
|
115
|
+
if (!Array.isArray(nodeNames)) {
|
|
116
|
+
nodeNames = [nodeNames];
|
|
117
|
+
}
|
|
118
|
+
for (; node; node = node.parent) {
|
|
119
|
+
if (nodeNames.includes(node.name)) {
|
|
120
|
+
return node;
|
|
121
|
+
}
|
|
122
|
+
if (node.type.isTop) {
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
function ifInside(options, source) {
|
|
129
|
+
const {
|
|
130
|
+
nodes,
|
|
131
|
+
before,
|
|
132
|
+
after,
|
|
133
|
+
keyword
|
|
134
|
+
} = options;
|
|
135
|
+
return context => {
|
|
136
|
+
const {
|
|
137
|
+
state,
|
|
138
|
+
pos
|
|
139
|
+
} = context;
|
|
140
|
+
const node = matchUp(syntaxTree(state).resolveInner(pos, -1), nodes);
|
|
141
|
+
if (!node) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
if (matchLeft(node, pos, [keyword, before])) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
if (matchRight(node, pos, [keyword, after])) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
if (after && !matchLeft(node, pos, [after])) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return source(context);
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* A FEEL language provider based on the
|
|
159
|
+
* [Lezer FEEL parser](https://github.com/nikku/lezer-feel),
|
|
160
|
+
* extended with highlighting and indentation information.
|
|
161
|
+
*/
|
|
162
|
+
const feelLanguage = LRLanguage.define({
|
|
163
|
+
parser: parser.configure({
|
|
164
|
+
props: [indentNodeProp.add({
|
|
165
|
+
'Context': delimitedIndent({
|
|
166
|
+
closing: '}'
|
|
167
|
+
}),
|
|
168
|
+
'List FilterExpression': delimitedIndent({
|
|
169
|
+
closing: ']'
|
|
170
|
+
}),
|
|
171
|
+
'ParenthesizedExpression FunctionInvocation': continuedIndent({
|
|
172
|
+
except: /^\s*\)/
|
|
173
|
+
}),
|
|
174
|
+
'ForExpression QuantifiedExpression IfExpression': continuedIndent({
|
|
175
|
+
except: /^\s*(then|else|return|satisfies)\b/
|
|
176
|
+
}),
|
|
177
|
+
'FunctionDefinition': continuedIndent({
|
|
178
|
+
except: /^\s*(\(|\))/
|
|
179
|
+
})
|
|
180
|
+
}), foldNodeProp.add({
|
|
181
|
+
Context: foldInside,
|
|
182
|
+
List: foldInside,
|
|
183
|
+
ParenthesizedExpression: foldInside,
|
|
184
|
+
FunctionDefinition(node) {
|
|
185
|
+
const last = node.getChild(')');
|
|
186
|
+
if (!last) return null;
|
|
187
|
+
return {
|
|
188
|
+
from: last.to,
|
|
189
|
+
to: node.to
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
})]
|
|
193
|
+
}),
|
|
194
|
+
languageData: {
|
|
195
|
+
indentOnInput: /^\s*(\)|\}|\]|then|else|return|satisfies)$/,
|
|
196
|
+
commentTokens: {
|
|
197
|
+
line: '//',
|
|
198
|
+
block: {
|
|
199
|
+
open: '/*',
|
|
200
|
+
close: '*/'
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
84
204
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
205
|
+
/**
|
|
206
|
+
* A language provider for FEEL Unary Tests
|
|
207
|
+
*/
|
|
208
|
+
const unaryTestsLanguage = feelLanguage.configure({
|
|
209
|
+
top: 'UnaryTests'
|
|
210
|
+
}, 'FEEL unary tests');
|
|
211
|
+
/**
|
|
212
|
+
* Language provider for FEEL Expression
|
|
213
|
+
*/
|
|
214
|
+
const expressionLanguage = feelLanguage.configure({
|
|
215
|
+
top: 'Expression'
|
|
216
|
+
}, 'FEEL expression');
|
|
217
|
+
/**
|
|
218
|
+
* Feel language support for CodeMirror.
|
|
219
|
+
*
|
|
220
|
+
* Includes [snippet](#lang-feel.snippets)
|
|
221
|
+
*/
|
|
96
222
|
function feel(config = {}) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
]);
|
|
223
|
+
const lang = config.dialect === 'unaryTests' ? unaryTestsLanguage : expressionLanguage;
|
|
224
|
+
const contextualLang = lang.configure({
|
|
225
|
+
contextTracker: trackVariables(config.context)
|
|
226
|
+
});
|
|
227
|
+
const completions = config.completions || [snippetCompletion(snippets), keywordCompletions].flat();
|
|
228
|
+
return new LanguageSupport(contextualLang, [...completions.map(autocomplete => contextualLang.data.of({
|
|
229
|
+
autocomplete
|
|
230
|
+
}))]);
|
|
106
231
|
}
|
|
107
232
|
|
|
108
|
-
export { expressionLanguage, feel, feelLanguage, snippets, unaryTestsLanguage };
|
|
233
|
+
export { contextualKeyword, dontComplete, expressionLanguage, feel, feelLanguage, ifInside, keywordCompletions, matchChildren, matchLeft, matchRight, snippetCompletion, snippets, unaryTestsLanguage };
|
|
234
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/snippets.ts","../src/completion.ts","../src/feel.ts"],"sourcesContent":["import { Completion, snippetCompletion } from '@codemirror/autocomplete';\n\n/**\n * A collection of FEEL-related [snippets](#autocomplete.snippet).\n */\nexport const snippets: readonly Completion[] = [\n snippetCompletion('function(${params}) ${body}', {\n label: 'function',\n detail: 'definition',\n type: 'keyword'\n }),\n snippetCompletion('for ${var} in ${collection} return ${value}', {\n label: 'for',\n detail: 'expression',\n type: 'keyword'\n }),\n snippetCompletion('every ${var} in ${collection} satisfies ${condition}', {\n label: 'every',\n detail: 'quantified expression',\n type: 'keyword'\n }),\n snippetCompletion('some ${var} in ${collection} satisfies ${condition}', {\n label: 'some',\n detail: 'quantified expression',\n type: 'keyword'\n }),\n snippetCompletion('if ${condition} then ${value} else ${other value}', {\n label: 'if',\n detail: 'block',\n type: 'keyword'\n }),\n snippetCompletion('{ ${key}: ${value} }', {\n label: 'context',\n detail: 'block',\n type: 'keyword'\n })\n];\n","import { syntaxTree } from '@codemirror/language';\nimport { SyntaxNode } from '@lezer/common';\n\nimport {\n CompletionSource,\n Completion,\n completeFromList,\n ifNotIn\n} from '@codemirror/autocomplete';\n\n\nexport function contextualKeyword(options: {\n before?: string,\n after?: string,\n context: string,\n keyword: string\n}) : CompletionSource {\n\n const {\n context: nodes,\n after,\n before,\n keyword\n } = options;\n\n return ifInside({ nodes, before, after, keyword }, completeFromList([\n { label: keyword, type: 'keyword', boost: 10 }\n ]));\n}\n\nexport const keywordCompletions = [\n contextualKeyword({\n context: 'InExpression',\n keyword: 'in'\n }),\n contextualKeyword({\n context: 'IfExpression',\n keyword: 'then',\n after: 'if',\n before: 'else'\n }),\n contextualKeyword({\n context: 'IfExpression',\n keyword: 'else',\n after: 'then'\n }),\n contextualKeyword({\n context: 'QuantifiedExpression',\n keyword: 'satisfies'\n }),\n contextualKeyword({\n context: 'ForExpression',\n after: 'InExpressions',\n keyword: 'return'\n })\n];\n\nexport const dontComplete = [\n 'StringLiteral', 'Identifier',\n 'LineComment', 'BlockComment'\n];\n\nexport function snippetCompletion(snippets: readonly Completion[]) : CompletionSource {\n return ifNotIn(\n dontComplete, completeFromList(snippets.map(s => ({ ...s, type: 'text' })))\n );\n}\n\nexport function matchLeft(node: SyntaxNode, position: number, nodes: (string|undefined)[]) : SyntaxNode | null {\n return matchChildren(node, position, nodes, -1);\n}\n\nexport function matchRight(node: SyntaxNode, position: number, nodes: (string|undefined)[]) : SyntaxNode | null {\n return matchChildren(node, position, nodes, 1);\n}\n\nexport function matchChildren(node: SyntaxNode, position: number, nodes: (string|undefined)[], direction: 1 | -1) : SyntaxNode | null {\n\n let child = node[direction > 0 ? 'childAfter' : 'childBefore'](position);\n\n while (child) {\n if (nodes.includes(child.name)) {\n return child;\n }\n\n if (child.type.isError && child.firstChild) {\n if (nodes.includes(child.firstChild.name)) {\n return child.firstChild;\n }\n }\n\n child = child[direction > 0 ? 'nextSibling' : 'prevSibling'];\n }\n\n return null;\n}\n\nfunction matchUp(node: SyntaxNode, nodeNames: string | undefined | (string | undefined)[]) {\n\n if (!Array.isArray(nodeNames)) {\n nodeNames = [ nodeNames ];\n }\n\n for (; node; node = node.parent!) {\n if (nodeNames.includes(node.name)) {\n return node;\n }\n\n if (node.type.isTop) {\n break;\n }\n }\n\n return null;\n}\n\nexport function ifInside(options: {\n nodes: string | string[],\n keyword: string,\n before?: string,\n after?: string\n}, source: CompletionSource): CompletionSource {\n\n const {\n nodes,\n before,\n after,\n keyword\n } = options;\n\n return (context) => {\n\n const { state, pos } = context;\n\n const node = matchUp(syntaxTree(state).resolveInner(pos, -1), nodes);\n\n if (!node) {\n return null;\n }\n\n if (matchLeft(node, pos, [ keyword, before ])) {\n return null;\n }\n\n if (matchRight(node, pos, [ keyword, after ])) {\n return null;\n }\n\n if (after && !matchLeft(node, pos, [ after ])) {\n return null;\n }\n\n return source(context);\n };\n}","import {\n parser,\n trackVariables\n} from 'lezer-feel';\n\nimport {\n LRLanguage,\n LanguageSupport,\n delimitedIndent,\n continuedIndent,\n indentNodeProp,\n foldNodeProp,\n foldInside\n} from '@codemirror/language';\n\nimport {\n snippets\n} from './snippets';\n\nimport {\n keywordCompletions,\n snippetCompletion\n} from './completion';\n\nimport {\n CompletionSource\n} from '@codemirror/autocomplete';\n\n\n/**\n * A FEEL language provider based on the\n * [Lezer FEEL parser](https://github.com/nikku/lezer-feel),\n * extended with highlighting and indentation information.\n */\nexport const feelLanguage = LRLanguage.define({\n parser: parser.configure({\n props: [\n indentNodeProp.add({\n 'Context': delimitedIndent({\n closing: '}'\n }),\n 'List FilterExpression': delimitedIndent({\n closing: ']'\n }),\n 'ParenthesizedExpression FunctionInvocation': continuedIndent({\n except: /^\\s*\\)/\n }),\n 'ForExpression QuantifiedExpression IfExpression': continuedIndent({\n except: /^\\s*(then|else|return|satisfies)\\b/\n }),\n 'FunctionDefinition': continuedIndent({\n except: /^\\s*(\\(|\\))/\n })\n }),\n foldNodeProp.add({\n Context: foldInside,\n List: foldInside,\n ParenthesizedExpression: foldInside,\n FunctionDefinition(node) {\n const last = node.getChild(')');\n\n if (!last) return null;\n\n return {\n from: last.to,\n to: node.to\n };\n }\n })\n ]\n }),\n languageData: {\n indentOnInput: /^\\s*(\\)|\\}|\\]|then|else|return|satisfies)$/,\n commentTokens: {\n line: '//',\n block: {\n open: '/*',\n close: '*/'\n }\n }\n }\n});\n\n/**\n * A language provider for FEEL Unary Tests\n */\nexport const unaryTestsLanguage = feelLanguage.configure({\n top: 'UnaryTests',\n}, 'FEEL unary tests');\n\n/**\n * Language provider for FEEL Expression\n */\nexport const expressionLanguage = feelLanguage.configure({\n top: 'Expression'\n}, 'FEEL expression');\n\n\n\n/**\n * Feel language support for CodeMirror.\n *\n * Includes [snippet](#lang-feel.snippets)\n */\nexport function feel(config: {\n dialect?: 'expression' | 'unaryTests',\n completions?: CompletionSource[],\n context?: Record<string, any>\n} = {}) {\n const lang = config.dialect === 'unaryTests' ? unaryTestsLanguage : expressionLanguage;\n\n const contextualLang = lang.configure({\n contextTracker: trackVariables(config.context)\n });\n\n const completions = config.completions || [\n snippetCompletion(snippets),\n keywordCompletions,\n ].flat();\n\n return new LanguageSupport(contextualLang, [\n ...(\n completions.map(autocomplete => contextualLang.data.of({\n autocomplete\n }))\n )\n ]);\n\n}"],"names":["snippets","snippetCompletion","label","detail","type","contextualKeyword","options","context","nodes","after","before","keyword","ifInside","completeFromList","boost","keywordCompletions","dontComplete","ifNotIn","map","s","_extends","matchLeft","node","position","matchChildren","matchRight","direction","child","includes","name","isError","firstChild","matchUp","nodeNames","Array","isArray","parent","isTop","source","state","pos","syntaxTree","resolveInner","feelLanguage","LRLanguage","define","parser","configure","props","indentNodeProp","add","delimitedIndent","closing","continuedIndent","except","foldNodeProp","Context","foldInside","List","ParenthesizedExpression","FunctionDefinition","last","getChild","from","to","languageData","indentOnInput","commentTokens","line","block","open","close","unaryTestsLanguage","top","expressionLanguage","feel","config","lang","dialect","contextualLang","contextTracker","trackVariables","completions","flat","LanguageSupport","autocomplete","data","of"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lang-feel",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "FEEL language support for the CodeMirror code editor",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"all": "run-s lint build test",
|
|
7
|
-
"test": "
|
|
7
|
+
"test": "karma start karma.conf.cjs",
|
|
8
|
+
"dev": "run-p 'build -- watch' 'test -- --no-single-run --auto-watch'",
|
|
8
9
|
"lint": "eslint . --ext ts",
|
|
9
|
-
"build": "
|
|
10
|
-
"prepare": "npm run build"
|
|
11
|
-
"dev": "chokidar 'src/*.ts' 'test/*.ts' --initial -c 'npm run build && npm test'"
|
|
10
|
+
"build": "microbundle -f modern,cjs --target node",
|
|
11
|
+
"prepare": "npm run build"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
14
|
"editor",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"url": "https://github.com/nikku"
|
|
20
20
|
},
|
|
21
21
|
"type": "module",
|
|
22
|
+
"source": "src/index.ts",
|
|
22
23
|
"main": "dist/index.cjs",
|
|
23
24
|
"exports": {
|
|
24
25
|
"import": "./dist/index.js",
|
|
@@ -29,24 +30,37 @@
|
|
|
29
30
|
"sideEffects": false,
|
|
30
31
|
"license": "MIT",
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@codemirror/autocomplete": "^6.
|
|
33
|
-
"@codemirror/language": "^6.
|
|
34
|
-
"@codemirror/state": "^6.
|
|
35
|
-
"@codemirror/view": "^6.
|
|
36
|
-
"@lezer/common": "^1.1
|
|
37
|
-
"lezer-feel": "^1.2.
|
|
33
|
+
"@codemirror/autocomplete": "^6.16.2",
|
|
34
|
+
"@codemirror/language": "^6.10.2",
|
|
35
|
+
"@codemirror/state": "^6.4.1",
|
|
36
|
+
"@codemirror/view": "^6.28.1",
|
|
37
|
+
"@lezer/common": "^1.2.1",
|
|
38
|
+
"lezer-feel": "^1.2.9"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
41
|
+
"@lezer/lr": "^1.4.1",
|
|
42
|
+
"@types/karma-chai": "^0.1.6",
|
|
43
|
+
"@types/karma-mocha": "^1.3.4",
|
|
44
|
+
"@types/mocha": "^10.0.6",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^7.13.0",
|
|
46
|
+
"@typescript-eslint/parser": "^7.13.0",
|
|
47
|
+
"chai": "^4.4.1",
|
|
48
|
+
"codemirror": "^6.0.1",
|
|
49
|
+
"eslint": "^8.57.0",
|
|
47
50
|
"eslint-plugin-bpmn-io": "^1.0.0",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
51
|
+
"karma": "^6.4.3",
|
|
52
|
+
"karma-chai": "^0.1.0",
|
|
53
|
+
"karma-chrome-launcher": "^3.2.0",
|
|
54
|
+
"karma-debug-launcher": "^0.0.5",
|
|
55
|
+
"karma-mocha": "^2.0.1",
|
|
56
|
+
"karma-webpack": "^5.0.1",
|
|
57
|
+
"microbundle": "^0.15.1",
|
|
58
|
+
"mocha": "^10.4.0",
|
|
59
|
+
"npm-run-all2": "^6.2.0",
|
|
60
|
+
"puppeteer": "^22.11.0",
|
|
61
|
+
"ts-loader": "^9.5.1",
|
|
62
|
+
"typescript": "^5.4.5",
|
|
63
|
+
"webpack": "^5.92.0"
|
|
50
64
|
},
|
|
51
65
|
"repository": {
|
|
52
66
|
"type": "git",
|
package/dist/index.d.cts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { LRLanguage, LanguageSupport } from '@codemirror/language';
|
|
2
|
-
import { Completion } from '@codemirror/autocomplete';
|
|
3
|
-
|
|
4
|
-
declare const feelLanguage: LRLanguage;
|
|
5
|
-
declare const unaryTestsLanguage: LRLanguage;
|
|
6
|
-
declare const expressionLanguage: LRLanguage;
|
|
7
|
-
declare function feel(config?: {
|
|
8
|
-
dialect?: 'expression' | 'unaryTests';
|
|
9
|
-
context?: Record<string, any>;
|
|
10
|
-
}): LanguageSupport;
|
|
11
|
-
|
|
12
|
-
declare const snippets: readonly Completion[];
|
|
13
|
-
|
|
14
|
-
export { expressionLanguage, feel, feelLanguage, snippets, unaryTestsLanguage };
|