@valtzu/codemirror-lang-el 0.2.1 → 0.2.3

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 CHANGED
@@ -13,7 +13,7 @@
13
13
  "codemirror": "https://esm.sh/codemirror@6.0.1",
14
14
  "@codemirror/autocomplete": "https://esm.sh/@codemirror/autocomplete@6.9.0",
15
15
  "@codemirror/view": "https://esm.sh/@codemirror/view@6.17.1",
16
- "@valtzu/codemirror-lang-el": "https://esm.sh/@valtzu/codemirror-lang-el@0.1.13"
16
+ "@valtzu/codemirror-lang-el": "https://esm.sh/@valtzu/codemirror-lang-el@0.2.3"
17
17
  }
18
18
  }
19
19
  </script>
@@ -27,7 +27,16 @@ let editor = new EditorView({
27
27
  extensions: [
28
28
  basicSetup,
29
29
  keymap.of([{key: "Tab", run: acceptCompletion}]),
30
- expressionlanguage({ identifiers: ['foo', 'bar'], functions: {'smh': [], smash_my_head: ['object']} })
30
+ expressionlanguage({
31
+ identifiers: [
32
+ { name: 'foo', info: 'Foo is a variable' },
33
+ { name: 'bar' }
34
+ ],
35
+ functions: [
36
+ { name: 'smh' },
37
+ { name: 'smash_my_head', args: ['object'] },
38
+ ],
39
+ })
31
40
  ],
32
41
  parent: document.getElementById('editor'),
33
42
  });
package/dist/index.cjs CHANGED
@@ -5,6 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var lr = require('@lezer/lr');
6
6
  var language = require('@codemirror/language');
7
7
  var highlight = require('@lezer/highlight');
8
+ var lint = require('@codemirror/lint');
9
+ var view = require('@codemirror/view');
8
10
 
9
11
  // This file was generated by lezer-generator. You probably shouldn't edit it.
10
12
  const parser = lr.LRParser.deserialize({
@@ -27,6 +29,53 @@ const parser = lr.LRParser.deserialize({
27
29
  });
28
30
 
29
31
  const identifier = /^[a-zA-Z_]+[a-zA-Z_0-9]*$/;
32
+ const isFunction = (identifier, config) => { var _a; return (_a = config.functions) === null || _a === void 0 ? void 0 : _a.find(fn => fn.name === identifier); };
33
+ const isVariable = (identifier, config) => { var _a; return (_a = config.identifiers) === null || _a === void 0 ? void 0 : _a.find(variable => variable.name === identifier); };
34
+ const expressionLanguageLinter = (config) => lint.linter(view => {
35
+ let diagnostics = [];
36
+ language.syntaxTree(view.state).cursor().iterate(node => {
37
+ if (node.name == "Identifier") {
38
+ const identifier = view.state.sliceDoc(node.from, node.to);
39
+ if (!isFunction(identifier, config) && !isVariable(identifier, config)) {
40
+ diagnostics.push({
41
+ from: node.from,
42
+ to: node.to,
43
+ severity: 'error',
44
+ message: `Identifier "${identifier}" not found`,
45
+ });
46
+ }
47
+ }
48
+ });
49
+ return diagnostics;
50
+ });
51
+ const keywordTooltip = (config) => view.hoverTooltip((view, pos, side) => {
52
+ var _a, _b;
53
+ let { from, to, text } = view.state.doc.lineAt(pos);
54
+ let start = pos, end = pos;
55
+ while (start > from && /\w/.test(text[start - from - 1]))
56
+ start--;
57
+ while (end < to && /\w/.test(text[end - from]))
58
+ end++;
59
+ if (start == pos && side < 0 || end == pos && side > 0) {
60
+ return null;
61
+ }
62
+ const keyword = text.slice(start - from, end - from);
63
+ const info = (_b = ((_a = isFunction(keyword, config)) !== null && _a !== void 0 ? _a : isVariable(keyword, config))) === null || _b === void 0 ? void 0 : _b.info;
64
+ if (!info) {
65
+ return null;
66
+ }
67
+ return {
68
+ pos: start,
69
+ end,
70
+ above: true,
71
+ create(view) {
72
+ let dom = document.createElement("div");
73
+ dom.textContent = info;
74
+ dom.className = 'cm-diagnostic';
75
+ return { dom };
76
+ },
77
+ };
78
+ });
30
79
  const ELLanguage = language.LRLanguage.define({
31
80
  parser: parser.configure({
32
81
  props: [
@@ -86,7 +135,7 @@ function expressionLanguageCompletionFor(config, context) {
86
135
  if (tree.name == 'String') {
87
136
  return null;
88
137
  }
89
- if (tree.prevSibling && !['Operator', 'OperatorKeyword', 'Punctuation', 'NullSafe', 'NullCoalescing'].includes(tree.prevSibling.name)) {
138
+ if (tree.prevSibling && !['Operator', 'OperatorKeyword', 'Punctuation', 'NullSafe', 'NullCoalescing', 'OpeningBracket'].includes(tree.prevSibling.name)) {
90
139
  return completeOperatorKeyword(state, config, tree, tree.from, pos);
91
140
  }
92
141
  if (tree.name == "Identifier") {
@@ -100,8 +149,14 @@ function expressionLanguageCompletionSourceWith(config) {
100
149
  return (context) => expressionLanguageCompletionFor(config, context);
101
150
  }
102
151
  function expressionlanguage(config = {}, extensions = []) {
103
- return new language.LanguageSupport(ELLanguage, [ELLanguage.data.of({ autocomplete: expressionLanguageCompletionSourceWith(config) }), ...extensions]);
152
+ return new language.LanguageSupport(ELLanguage, [
153
+ ELLanguage.data.of({ autocomplete: expressionLanguageCompletionSourceWith(config) }),
154
+ expressionLanguageLinter(config),
155
+ keywordTooltip(config),
156
+ ...extensions,
157
+ ]);
104
158
  }
105
159
 
106
160
  exports.ELLanguage = ELLanguage;
107
161
  exports.expressionlanguage = expressionlanguage;
162
+ exports.keywordTooltip = keywordTooltip;
package/dist/index.d.cts CHANGED
@@ -12,6 +12,7 @@ interface ExpressionLanguageConfig {
12
12
  }[];
13
13
  operatorKeywords?: readonly string[];
14
14
  }
15
+ declare const keywordTooltip: (config: ExpressionLanguageConfig) => import("@codemirror/state").Extension;
15
16
  declare const ELLanguage: LRLanguage;
16
17
  declare function expressionlanguage(config?: ExpressionLanguageConfig, extensions?: Array<any>): LanguageSupport;
17
- export { ExpressionLanguageConfig, ELLanguage, expressionlanguage };
18
+ export { ExpressionLanguageConfig, keywordTooltip, ELLanguage, expressionlanguage };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ interface ExpressionLanguageConfig {
12
12
  }[];
13
13
  operatorKeywords?: readonly string[];
14
14
  }
15
+ declare const keywordTooltip: (config: ExpressionLanguageConfig) => import("@codemirror/state").Extension;
15
16
  declare const ELLanguage: LRLanguage;
16
17
  declare function expressionlanguage(config?: ExpressionLanguageConfig, extensions?: Array<any>): LanguageSupport;
17
- export { ExpressionLanguageConfig, ELLanguage, expressionlanguage };
18
+ export { ExpressionLanguageConfig, keywordTooltip, ELLanguage, expressionlanguage };
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { LRParser } from '@lezer/lr';
2
2
  import { LRLanguage, indentNodeProp, delimitedIndent, foldNodeProp, foldInside, LanguageSupport, syntaxTree } from '@codemirror/language';
3
3
  import { styleTags, tags } from '@lezer/highlight';
4
+ import { linter } from '@codemirror/lint';
5
+ import { hoverTooltip } from '@codemirror/view';
4
6
 
5
7
  // This file was generated by lezer-generator. You probably shouldn't edit it.
6
8
  const parser = LRParser.deserialize({
@@ -23,6 +25,53 @@ const parser = LRParser.deserialize({
23
25
  });
24
26
 
25
27
  const identifier = /^[a-zA-Z_]+[a-zA-Z_0-9]*$/;
28
+ const isFunction = (identifier, config) => { var _a; return (_a = config.functions) === null || _a === void 0 ? void 0 : _a.find(fn => fn.name === identifier); };
29
+ const isVariable = (identifier, config) => { var _a; return (_a = config.identifiers) === null || _a === void 0 ? void 0 : _a.find(variable => variable.name === identifier); };
30
+ const expressionLanguageLinter = (config) => linter(view => {
31
+ let diagnostics = [];
32
+ syntaxTree(view.state).cursor().iterate(node => {
33
+ if (node.name == "Identifier") {
34
+ const identifier = view.state.sliceDoc(node.from, node.to);
35
+ if (!isFunction(identifier, config) && !isVariable(identifier, config)) {
36
+ diagnostics.push({
37
+ from: node.from,
38
+ to: node.to,
39
+ severity: 'error',
40
+ message: `Identifier "${identifier}" not found`,
41
+ });
42
+ }
43
+ }
44
+ });
45
+ return diagnostics;
46
+ });
47
+ const keywordTooltip = (config) => hoverTooltip((view, pos, side) => {
48
+ var _a, _b;
49
+ let { from, to, text } = view.state.doc.lineAt(pos);
50
+ let start = pos, end = pos;
51
+ while (start > from && /\w/.test(text[start - from - 1]))
52
+ start--;
53
+ while (end < to && /\w/.test(text[end - from]))
54
+ end++;
55
+ if (start == pos && side < 0 || end == pos && side > 0) {
56
+ return null;
57
+ }
58
+ const keyword = text.slice(start - from, end - from);
59
+ const info = (_b = ((_a = isFunction(keyword, config)) !== null && _a !== void 0 ? _a : isVariable(keyword, config))) === null || _b === void 0 ? void 0 : _b.info;
60
+ if (!info) {
61
+ return null;
62
+ }
63
+ return {
64
+ pos: start,
65
+ end,
66
+ above: true,
67
+ create(view) {
68
+ let dom = document.createElement("div");
69
+ dom.textContent = info;
70
+ dom.className = 'cm-diagnostic';
71
+ return { dom };
72
+ },
73
+ };
74
+ });
26
75
  const ELLanguage = LRLanguage.define({
27
76
  parser: parser.configure({
28
77
  props: [
@@ -82,7 +131,7 @@ function expressionLanguageCompletionFor(config, context) {
82
131
  if (tree.name == 'String') {
83
132
  return null;
84
133
  }
85
- if (tree.prevSibling && !['Operator', 'OperatorKeyword', 'Punctuation', 'NullSafe', 'NullCoalescing'].includes(tree.prevSibling.name)) {
134
+ if (tree.prevSibling && !['Operator', 'OperatorKeyword', 'Punctuation', 'NullSafe', 'NullCoalescing', 'OpeningBracket'].includes(tree.prevSibling.name)) {
86
135
  return completeOperatorKeyword(state, config, tree, tree.from, pos);
87
136
  }
88
137
  if (tree.name == "Identifier") {
@@ -96,7 +145,12 @@ function expressionLanguageCompletionSourceWith(config) {
96
145
  return (context) => expressionLanguageCompletionFor(config, context);
97
146
  }
98
147
  function expressionlanguage(config = {}, extensions = []) {
99
- return new LanguageSupport(ELLanguage, [ELLanguage.data.of({ autocomplete: expressionLanguageCompletionSourceWith(config) }), ...extensions]);
148
+ return new LanguageSupport(ELLanguage, [
149
+ ELLanguage.data.of({ autocomplete: expressionLanguageCompletionSourceWith(config) }),
150
+ expressionLanguageLinter(config),
151
+ keywordTooltip(config),
152
+ ...extensions,
153
+ ]);
100
154
  }
101
155
 
102
- export { ELLanguage, expressionlanguage };
156
+ export { ELLanguage, expressionlanguage, keywordTooltip };
package/package.json CHANGED
@@ -17,10 +17,12 @@
17
17
  "dependencies": {
18
18
  "@codemirror/autocomplete": "^6.9.0",
19
19
  "@codemirror/language": "^6.0.0",
20
+ "@codemirror/lint": "^6.4.2",
20
21
  "@lezer/highlight": "^1.0.0",
21
22
  "@lezer/lr": "^1.0.0"
22
23
  },
23
24
  "devDependencies": {
25
+ "@codemirror/state": "^6.2.1",
24
26
  "@lezer/generator": "^1.0.0",
25
27
  "@types/mocha": "^10.0.1",
26
28
  "ist": "^1.1.7",
@@ -39,5 +41,5 @@
39
41
  "access": "public",
40
42
  "registry": "https://registry.npmjs.org/"
41
43
  },
42
- "version": "0.2.1"
44
+ "version": "0.2.3"
43
45
  }