@bhsd/codemirror-mediawiki 3.12.1 → 3.12.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/dist/codemirror.d.ts +2 -1
- package/dist/codemirror.js +5 -5
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +1 -1
- package/dist/css.js +2 -2
- package/dist/escape.js +9 -10
- package/dist/fold.d.ts +5 -8
- package/dist/fold.js +18 -18
- package/dist/hover.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/inlay.js +2 -2
- package/dist/javascript.d.ts +1 -1
- package/dist/javascript.js +8 -4
- package/dist/json.d.ts +8 -0
- package/dist/json.js +101 -0
- package/dist/keymap.d.ts +8 -1
- package/dist/keymap.js +89 -7
- package/dist/lilypond.d.ts +14 -0
- package/dist/lilypond.js +240 -0
- package/dist/lint.js +2 -2
- package/dist/lintsource.d.ts +1 -1
- package/dist/lintsource.js +7 -7
- package/dist/lua.d.ts +1 -1
- package/dist/lua.js +39 -63
- package/dist/main.min.js +32 -31
- package/dist/matchBrackets.d.ts +3 -11
- package/dist/matchBrackets.js +51 -39
- package/dist/matchTag.d.ts +5 -5
- package/dist/matchTag.js +4 -4
- package/dist/math.d.ts +3 -0
- package/dist/math.js +58 -0
- package/dist/mediawiki.d.ts +2 -3
- package/dist/mediawiki.js +34 -26
- package/dist/mw.min.js +33 -32
- package/dist/ref.d.ts +2 -2
- package/dist/ref.js +5 -5
- package/dist/signature.js +13 -13
- package/dist/static.d.ts +7 -0
- package/dist/static.js +7 -0
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +9 -3
- package/dist/token.d.ts +10 -6
- package/dist/token.js +54 -20
- package/dist/util.d.ts +35 -10
- package/dist/util.js +43 -15
- package/dist/wiki.min.js +33 -32
- package/i18n/en.json +1 -1
- package/i18n/zh-hans.json +1 -1
- package/i18n/zh-hant.json +1 -1
- package/package.json +8 -10
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { StreamParser, StringStream } from '@codemirror/language';
|
|
2
|
+
declare interface State {
|
|
3
|
+
tokenize: Tokenizer;
|
|
4
|
+
/** 只用于Scheme */
|
|
5
|
+
parens: number;
|
|
6
|
+
/** 只用于歌词 */
|
|
7
|
+
braces: number;
|
|
8
|
+
/** 只用于歌词 */
|
|
9
|
+
spaced: boolean;
|
|
10
|
+
lyrics: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare type Tokenizer = (stream: StringStream, state: State) => string;
|
|
13
|
+
export declare const lilypond: StreamParser<State>;
|
|
14
|
+
export {};
|
package/dist/lilypond.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { inComment, getCompletions } from './util.js';
|
|
2
|
+
import { extData, extCompletion } from './constants.js';
|
|
3
|
+
let scoreFetch;
|
|
4
|
+
const inString = (parent) => (stream, state) => {
|
|
5
|
+
let escaped = false, next = stream.next();
|
|
6
|
+
while (next) {
|
|
7
|
+
if (!escaped && next === '"') {
|
|
8
|
+
state.tokenize = parent;
|
|
9
|
+
return /* #a11 */ 'string';
|
|
10
|
+
}
|
|
11
|
+
escaped = !escaped && next === '\\';
|
|
12
|
+
next = stream.next();
|
|
13
|
+
}
|
|
14
|
+
return /* #a11 */ 'string';
|
|
15
|
+
};
|
|
16
|
+
const inScheme = (parent) => {
|
|
17
|
+
const style = 'mw-tag-score-scheme';
|
|
18
|
+
const tokenizer = (stream, state) => {
|
|
19
|
+
if (stream.eatSpace()) {
|
|
20
|
+
return style;
|
|
21
|
+
}
|
|
22
|
+
const ch = stream.next();
|
|
23
|
+
switch (ch) {
|
|
24
|
+
case '(':
|
|
25
|
+
state.parens++;
|
|
26
|
+
return style;
|
|
27
|
+
case ')':
|
|
28
|
+
state.parens--;
|
|
29
|
+
if (state.parens === 0) {
|
|
30
|
+
state.tokenize = parent;
|
|
31
|
+
return 'separator';
|
|
32
|
+
}
|
|
33
|
+
return style;
|
|
34
|
+
case '"':
|
|
35
|
+
state.tokenize = inString(tokenizer);
|
|
36
|
+
return /* #a11 */ `string ${style}`;
|
|
37
|
+
case ';':
|
|
38
|
+
stream.skipToEnd();
|
|
39
|
+
return /* #940 */ `comment ${style}`;
|
|
40
|
+
case '#':
|
|
41
|
+
if (stream.eat('!')) {
|
|
42
|
+
state.tokenize = inComment(tokenizer, '!#');
|
|
43
|
+
return /* #940 */ `comment ${style}`;
|
|
44
|
+
}
|
|
45
|
+
// fall through
|
|
46
|
+
default:
|
|
47
|
+
return style;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return tokenizer;
|
|
51
|
+
};
|
|
52
|
+
const eatHash = (stream, state, ch, parent) => {
|
|
53
|
+
if (stream.match(/^#[tf]/u)) {
|
|
54
|
+
return /* #219 */ 'bool';
|
|
55
|
+
}
|
|
56
|
+
else if (ch === '#' && stream.match(/^(?:\d+|#x[\da-f]*)/iu)) {
|
|
57
|
+
return /* #a11 */ 'character';
|
|
58
|
+
}
|
|
59
|
+
else if (stream.eat('(')) {
|
|
60
|
+
state.tokenize = inScheme(parent);
|
|
61
|
+
state.parens = 1;
|
|
62
|
+
return 'separator';
|
|
63
|
+
}
|
|
64
|
+
return stream.match(/^\s*[-_a-z][-\w]*/iu) ? 'variableName.local' : 'operator';
|
|
65
|
+
};
|
|
66
|
+
const eatQuote = (state, parent) => {
|
|
67
|
+
state.tokenize = inString(parent);
|
|
68
|
+
return /* #a11 */ 'string';
|
|
69
|
+
};
|
|
70
|
+
const eatPercent = (stream, state, parent) => {
|
|
71
|
+
if (stream.eat('{')) {
|
|
72
|
+
state.tokenize = inComment(parent, '%}');
|
|
73
|
+
return /* #940 */ 'comment';
|
|
74
|
+
}
|
|
75
|
+
stream.skipToEnd();
|
|
76
|
+
return /* #940 */ 'comment';
|
|
77
|
+
};
|
|
78
|
+
const lyricsCommands = new Set(['addlyrics', 'lyricmode', 'lyrics', 'lyricsto']), setCommands = new Set(['set', 'override']), unsetCommands = new Set(['unset', 'revert', 'tweak']), newCommands = new Set(['new', 'context']);
|
|
79
|
+
const eatCommand = (stream, state, parent, base) => {
|
|
80
|
+
const mt = stream.match(/^[a-z](?:[a-z]|-+(?=[a-z]))*/iu), cmd = mt?.[0], isUnset = unsetCommands.has(cmd), isNew = newCommands.has(cmd);
|
|
81
|
+
if (base && lyricsCommands.has(cmd)) {
|
|
82
|
+
state.lyrics = true;
|
|
83
|
+
}
|
|
84
|
+
else if (isUnset || isNew || setCommands.has(cmd)) {
|
|
85
|
+
state.tokenize = inAssignment(parent, isUnset ? -1 : 1, isNew);
|
|
86
|
+
}
|
|
87
|
+
return mt && extData['score']?.has(`\\${cmd}`) !== false ? /* #708 */ 'keyword' : '';
|
|
88
|
+
};
|
|
89
|
+
const inAssignment = (parent, step, cls) => (stream, state) => {
|
|
90
|
+
if (stream.eatSpace()) {
|
|
91
|
+
return '';
|
|
92
|
+
}
|
|
93
|
+
else if (step === 0) {
|
|
94
|
+
stream.eat('=');
|
|
95
|
+
state.tokenize = parent;
|
|
96
|
+
return 'operator';
|
|
97
|
+
}
|
|
98
|
+
stream.match(/^[a-z][-\w.]*/iu);
|
|
99
|
+
state.tokenize = step === 1 ? inAssignment(parent, 0) : parent;
|
|
100
|
+
return cls ? /* #167 */ 'className' : /* #00f */ 'variableName.definition';
|
|
101
|
+
};
|
|
102
|
+
const inBase = (stream, state) => {
|
|
103
|
+
if (stream.eatSpace()) {
|
|
104
|
+
return '';
|
|
105
|
+
}
|
|
106
|
+
const ch = stream.next();
|
|
107
|
+
switch (ch) {
|
|
108
|
+
case '-':
|
|
109
|
+
return stream.eat(/[->.+_!^]/u) ? 'operator' : 'punctuation';
|
|
110
|
+
case '#':
|
|
111
|
+
case '$':
|
|
112
|
+
return eatHash(stream, state, ch, inBase);
|
|
113
|
+
case '"':
|
|
114
|
+
return eatQuote(state, inBase);
|
|
115
|
+
case '%':
|
|
116
|
+
return eatPercent(stream, state, inBase);
|
|
117
|
+
case '/':
|
|
118
|
+
stream.eat('+');
|
|
119
|
+
return 'punctuation';
|
|
120
|
+
case '\\':
|
|
121
|
+
if (stream.eat(/[-<>!]/u)) {
|
|
122
|
+
return 'operator';
|
|
123
|
+
}
|
|
124
|
+
else if (stream.eat(/[()[\]]/u)) {
|
|
125
|
+
return 'squareBracket';
|
|
126
|
+
}
|
|
127
|
+
return stream.eat(/[\\=]/u) ? 'punctuation' : eatCommand(stream, state, inBase, true);
|
|
128
|
+
case '}':
|
|
129
|
+
state.lyrics = false;
|
|
130
|
+
return 'squareBracket';
|
|
131
|
+
case '{':
|
|
132
|
+
if (state.lyrics) {
|
|
133
|
+
state.lyrics = false;
|
|
134
|
+
state.braces = 1;
|
|
135
|
+
state.spaced = true;
|
|
136
|
+
state.tokenize = inLyrics;
|
|
137
|
+
}
|
|
138
|
+
return 'squareBracket';
|
|
139
|
+
default:
|
|
140
|
+
if (/[<>()[\]]/u.test(ch)) {
|
|
141
|
+
return 'squareBracket';
|
|
142
|
+
}
|
|
143
|
+
else if (/[:|~^_=]/u.test(ch)) {
|
|
144
|
+
return 'punctuation';
|
|
145
|
+
}
|
|
146
|
+
else if (/[',.!?]/u.test(ch)) {
|
|
147
|
+
return 'operator';
|
|
148
|
+
}
|
|
149
|
+
else if (/\d/u.test(ch)) {
|
|
150
|
+
stream.match(/^\d*(?:[./]\d+)?/u);
|
|
151
|
+
return /* #164 */ 'number';
|
|
152
|
+
}
|
|
153
|
+
else if (/[a-z]/iu.test(ch)) {
|
|
154
|
+
stream.match(/^(?:[a-z]|[-_\d]+(?=[a-z]))+/iu);
|
|
155
|
+
return /^(?:[rs]|[a-g](?:is)*(?:ih)*|[a-g]?(?:es)*(?:eh)*)$/u.test(stream.current())
|
|
156
|
+
? ''
|
|
157
|
+
: /* #219 */ 'atom';
|
|
158
|
+
}
|
|
159
|
+
return '';
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const inLyrics = (stream, state) => {
|
|
163
|
+
if (stream.eatSpace()) {
|
|
164
|
+
state.spaced = true;
|
|
165
|
+
return '';
|
|
166
|
+
}
|
|
167
|
+
else if (stream.sol()) {
|
|
168
|
+
state.spaced = true;
|
|
169
|
+
}
|
|
170
|
+
const ch = stream.next();
|
|
171
|
+
switch (ch) {
|
|
172
|
+
case '-':
|
|
173
|
+
if (state.spaced && stream.match(/^-(?=\s)/u)) {
|
|
174
|
+
return 'punctuation';
|
|
175
|
+
}
|
|
176
|
+
state.spaced = false;
|
|
177
|
+
return 'string';
|
|
178
|
+
case '_':
|
|
179
|
+
case '~':
|
|
180
|
+
case '|':
|
|
181
|
+
state.spaced = false;
|
|
182
|
+
return 'punctuation';
|
|
183
|
+
case '#':
|
|
184
|
+
case '$':
|
|
185
|
+
state.spaced = false;
|
|
186
|
+
return eatHash(stream, state, ch, inLyrics);
|
|
187
|
+
case '"':
|
|
188
|
+
state.spaced = true;
|
|
189
|
+
return eatQuote(state, inLyrics);
|
|
190
|
+
case '%':
|
|
191
|
+
state.spaced = true;
|
|
192
|
+
return eatPercent(stream, state, inLyrics);
|
|
193
|
+
case '\\':
|
|
194
|
+
if (stream.eat(/[<>!\\]/u)) {
|
|
195
|
+
state.spaced = true;
|
|
196
|
+
return '';
|
|
197
|
+
}
|
|
198
|
+
state.spaced = false;
|
|
199
|
+
return eatCommand(stream, state, inLyrics);
|
|
200
|
+
case '{':
|
|
201
|
+
case '}':
|
|
202
|
+
state.braces += ch === '{' ? 1 : -1;
|
|
203
|
+
if (state.braces) {
|
|
204
|
+
state.spaced = true;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
state.tokenize = inBase;
|
|
208
|
+
}
|
|
209
|
+
return 'squareBracket';
|
|
210
|
+
default:
|
|
211
|
+
state.spaced = false;
|
|
212
|
+
if (/\d/u.test(ch)) {
|
|
213
|
+
stream.eatWhile(/\d/u);
|
|
214
|
+
return /* #164 */ 'number';
|
|
215
|
+
}
|
|
216
|
+
stream.eatWhile(/[^\s\d_~{}#$"%\\]/u);
|
|
217
|
+
return /* #a11 */ 'string';
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
export const lilypond = {
|
|
221
|
+
startState() {
|
|
222
|
+
if (typeof wikiparse === 'object') {
|
|
223
|
+
scoreFetch ??= (async () => {
|
|
224
|
+
const data = await (await fetch(`${wikiparse.CDN}/data/ext/score.json`)).json();
|
|
225
|
+
extData['score'] = new Set(data.flatMap(item => item.split('.')));
|
|
226
|
+
extCompletion['score'] = getCompletions(data.filter(s => s.startsWith('\\')), 'keyword');
|
|
227
|
+
})();
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
tokenize: inBase,
|
|
231
|
+
parens: 0,
|
|
232
|
+
braces: 0,
|
|
233
|
+
lyrics: false,
|
|
234
|
+
spaced: false,
|
|
235
|
+
};
|
|
236
|
+
},
|
|
237
|
+
token(stream, state) {
|
|
238
|
+
return state.tokenize(stream, state);
|
|
239
|
+
},
|
|
240
|
+
};
|
package/dist/lint.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const myFindDiagnostic = (deco, head, anchor = head) => {
|
|
2
2
|
let found;
|
|
3
3
|
deco.between(head, Infinity, (_, __, { spec: { diagnostics } }) => {
|
|
4
4
|
const next = diagnostics.sort((a, b) => a.from - b.from || a.to - b.to)
|
|
@@ -16,7 +16,7 @@ const findDiagnostic = (deco, head, anchor = head) => {
|
|
|
16
16
|
* @param cm CodeMirror6 实例
|
|
17
17
|
*/
|
|
18
18
|
export const nextDiagnostic = (cm) => {
|
|
19
|
-
const view = cm.view, { state } = view, { diagnostics } = state.field(cm.getLintExtension()[2][0]), { from, to } = state.selection.main, next =
|
|
19
|
+
const view = cm.view, { state } = view, { diagnostics } = state.field(cm.getLintExtension()[2][0]), { from, to } = state.selection.main, next = myFindDiagnostic(diagnostics, from, to) ?? myFindDiagnostic(diagnostics, 0);
|
|
20
20
|
if (!next || next.from === from && next.to === to) {
|
|
21
21
|
return false;
|
|
22
22
|
}
|
package/dist/lintsource.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Text, EditorState } from '@codemirror/state';
|
|
|
3
3
|
import type { Language } from '@codemirror/language';
|
|
4
4
|
import type { Diagnostic, Action } from '@codemirror/lint';
|
|
5
5
|
import type { Option, LiveOption } from './linter';
|
|
6
|
-
import type { DocRange } from './
|
|
6
|
+
import type { DocRange } from './util';
|
|
7
7
|
export type LintSource<T = unknown> = ((state: EditorState) => readonly Diagnostic[] | Promise<readonly Diagnostic[]>) & {
|
|
8
8
|
config?: T;
|
|
9
9
|
fixer?: (doc: Text, rule?: string) => string | Promise<string>;
|
package/dist/lintsource.js
CHANGED
|
@@ -4,7 +4,7 @@ import { javascriptLanguage } from '@codemirror/lang-javascript';
|
|
|
4
4
|
import { sanitizeInlineStyle, lintJSON } from '@bhsd/common';
|
|
5
5
|
import { getWikiLinter, getJsLinter, getCssLinter, getLuaLinter, stylelintRepo, eslintRepo, luacheckRepo, isStylelintConfig, } from './linter.js';
|
|
6
6
|
import { posToIndex, toConfigGetter, } from './util.js';
|
|
7
|
-
import {
|
|
7
|
+
import { baseData } from './constants.js';
|
|
8
8
|
import { vue } from './javascript-globals.js';
|
|
9
9
|
/**
|
|
10
10
|
* 获取Linter选项
|
|
@@ -67,7 +67,7 @@ const wikiLintSource = async (wikiLint, text, opt, doc, f = 0, t) => (await wiki
|
|
|
67
67
|
* @test
|
|
68
68
|
*/
|
|
69
69
|
export const getWikiLintSource = (articlePath) => async (opt, v) => {
|
|
70
|
-
const options = { ...await getOpt(opt), cdn:
|
|
70
|
+
const options = { ...await getOpt(opt), cdn: baseData.CDN };
|
|
71
71
|
if (articlePath) {
|
|
72
72
|
options.getConfig = toConfigGetter(options.getConfig, articlePath);
|
|
73
73
|
}
|
|
@@ -113,7 +113,7 @@ const jsLintSource = (esLint, code, opt, doc, f = 0, t) => esLint(code, opt)
|
|
|
113
113
|
* @test
|
|
114
114
|
*/
|
|
115
115
|
export const getJsLintSource = async (opt) => {
|
|
116
|
-
const { CDN } =
|
|
116
|
+
const { CDN } = baseData, esLint = await getJsLinter(CDN && `${CDN}/${eslintRepo}`);
|
|
117
117
|
const lintSource = async ({ doc }) => jsLintSource(esLint, doc.toString(), await getOpt(opt), doc);
|
|
118
118
|
lintSource.fixer = (doc, rule) => esLint.fixer(doc.toString(), rule);
|
|
119
119
|
Object.defineProperty(lintSource, 'config', {
|
|
@@ -156,7 +156,7 @@ const cssLintSource = async (styleLint, code, opt, doc, f = 0, t) => {
|
|
|
156
156
|
* @test
|
|
157
157
|
*/
|
|
158
158
|
export const getCssLintSource = async (opt) => {
|
|
159
|
-
const { CDN } =
|
|
159
|
+
const { CDN } = baseData, styleLint = await getCssLinter(CDN && `${CDN}/${stylelintRepo}`);
|
|
160
160
|
const lintSource = async ({ doc }) => cssLintSource(styleLint, doc.toString(), await getOpt(opt), doc);
|
|
161
161
|
lintSource.fixer = async (doc, rule) => styleLint.fixer(doc.toString(), rule);
|
|
162
162
|
Object.defineProperty(lintSource, 'config', {
|
|
@@ -180,7 +180,7 @@ const stylelintConfigVue = /* #__PURE__ */ (() => ({
|
|
|
180
180
|
}))();
|
|
181
181
|
/** @implements */
|
|
182
182
|
const getVueOrHtmlLintSource = (rules, globals) => async (opt) => {
|
|
183
|
-
const { CDN } =
|
|
183
|
+
const { CDN } = baseData, styleLint = await getCssLinter(CDN && `${CDN}/${stylelintRepo}`), esLint = await getJsLinter(CDN && `${CDN}/${eslintRepo}`);
|
|
184
184
|
const lintSource = async (state) => {
|
|
185
185
|
const { doc } = state, option = await getOpt(opt, true) ?? {};
|
|
186
186
|
let js = option['js'], css = option['css'];
|
|
@@ -228,7 +228,7 @@ export const getVueLintSource = /* #__PURE__ */ getVueOrHtmlLintSource(stylelint
|
|
|
228
228
|
* @test
|
|
229
229
|
*/
|
|
230
230
|
export const getHTMLLintSource = async (opt, view, language) => {
|
|
231
|
-
const vueLintSource = await getVueOrHtmlLintSource()(opt), wikiLint = await getWikiLinter({ include: false, ...await getOpt(opt), cdn:
|
|
231
|
+
const vueLintSource = await getVueOrHtmlLintSource()(opt), wikiLint = await getWikiLinter({ include: false, ...await getOpt(opt), cdn: baseData.CDN }, view);
|
|
232
232
|
const lintSource = async (state) => {
|
|
233
233
|
const { doc } = state, option = await getOpt(opt, true) ?? {}, wiki = option['wiki'];
|
|
234
234
|
return [
|
|
@@ -255,7 +255,7 @@ export const getJsonLintSource = () => ({ doc }) => lintJSON(doc.toString())
|
|
|
255
255
|
* @test
|
|
256
256
|
*/
|
|
257
257
|
export const getLuaLintSource = async () => {
|
|
258
|
-
const { CDN } =
|
|
258
|
+
const { CDN } = baseData, luaLint = await getLuaLinter(CDN && `${CDN}/${luacheckRepo}`);
|
|
259
259
|
return async ({ doc }) => (await luaLint(doc.toString()))
|
|
260
260
|
.map(({ line, column, end_column, msg: message, severity }) => ({
|
|
261
261
|
source: 'Luacheck',
|
package/dist/lua.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { LanguageSupport } from '@codemirror/language';
|
|
|
3
3
|
import type { ViewUpdate, DecorationSet } from '@codemirror/view';
|
|
4
4
|
import type { EditorState } from '@codemirror/state';
|
|
5
5
|
import type { Tree } from '@lezer/common';
|
|
6
|
-
import type { DocRange } from './
|
|
6
|
+
import type { DocRange } from './util';
|
|
7
7
|
/**
|
|
8
8
|
* 高亮显示LDoc标签
|
|
9
9
|
* @ignore
|
package/dist/lua.js
CHANGED
|
@@ -4,7 +4,7 @@ import { ViewPlugin, Decoration } from '@codemirror/view';
|
|
|
4
4
|
import { syntaxTree, LanguageSupport, StreamLanguage, foldService, HighlightStyle, syntaxHighlighting, } from '@codemirror/language';
|
|
5
5
|
import { snippetCompletion } from '@codemirror/autocomplete';
|
|
6
6
|
import { tags } from '@lezer/highlight';
|
|
7
|
-
import { leadingSpaces, sliceDoc, markDocTagType } from './util.js';
|
|
7
|
+
import { leadingSpaces, sliceDoc, markDocTagType, getCompletions } from './util.js';
|
|
8
8
|
import { lightHighlightStyle } from './theme.js';
|
|
9
9
|
const map = {
|
|
10
10
|
1: 'constant',
|
|
@@ -218,12 +218,9 @@ const map = {
|
|
|
218
218
|
},
|
|
219
219
|
ext: 4,
|
|
220
220
|
},
|
|
221
|
-
},
|
|
222
|
-
'_G',
|
|
223
|
-
...Object.keys(globals),
|
|
224
|
-
].map(label => ({ label, type: 'namespace' })), constants = [
|
|
221
|
+
}, luaBuiltin = ['false', 'nil', 'true'], luaBuiltins = getCompletions(luaBuiltin, 'constant'), tables = getCompletions(['_G', ...Object.keys(globals)], 'namespace'), constants = [
|
|
225
222
|
{ label: '_VERSION', type: 'constant' },
|
|
226
|
-
...[
|
|
223
|
+
...getCompletions([
|
|
227
224
|
'assert',
|
|
228
225
|
'error',
|
|
229
226
|
'getfenv',
|
|
@@ -243,22 +240,15 @@ const map = {
|
|
|
243
240
|
'unpack',
|
|
244
241
|
'xpcall',
|
|
245
242
|
'require',
|
|
246
|
-
]
|
|
247
|
-
], binary = [
|
|
248
|
-
'
|
|
249
|
-
'or',
|
|
250
|
-
'in',
|
|
251
|
-
].map(label => ({ label, type: 'keyword' })), unary = [
|
|
252
|
-
...[
|
|
253
|
-
'not',
|
|
254
|
-
'function',
|
|
255
|
-
].map(label => ({ label, type: 'keyword' })),
|
|
243
|
+
], 'function'),
|
|
244
|
+
], binary = getCompletions(['and', 'or', 'in']), unary = [
|
|
245
|
+
...getCompletions(['not', 'function']),
|
|
256
246
|
snippetCompletion('function ${name}(${})\n\t${}\nend', {
|
|
257
247
|
label: 'function',
|
|
258
248
|
detail: 'definition',
|
|
259
249
|
type: 'keyword',
|
|
260
250
|
}),
|
|
261
|
-
], blocks = [
|
|
251
|
+
], blocks = getCompletions([
|
|
262
252
|
'break',
|
|
263
253
|
'elseif',
|
|
264
254
|
'return',
|
|
@@ -268,14 +258,14 @@ const map = {
|
|
|
268
258
|
'do',
|
|
269
259
|
'until',
|
|
270
260
|
'goto',
|
|
271
|
-
]
|
|
272
|
-
...[
|
|
261
|
+
]), luaKeywords = [
|
|
262
|
+
...getCompletions([
|
|
273
263
|
'if',
|
|
274
264
|
'while',
|
|
275
265
|
'repeat',
|
|
276
266
|
'for',
|
|
277
267
|
'local',
|
|
278
|
-
]
|
|
268
|
+
]),
|
|
279
269
|
snippetCompletion('if ${condition} then\n\t${}\nend', {
|
|
280
270
|
label: 'if',
|
|
281
271
|
detail: 'block',
|
|
@@ -306,14 +296,14 @@ const map = {
|
|
|
306
296
|
detail: 'in loop',
|
|
307
297
|
type: 'keyword',
|
|
308
298
|
}),
|
|
309
|
-
],
|
|
299
|
+
], excludedTypes = new Set(['variableName', 'variableName.standard', 'keyword']), lang = StreamLanguage.define(lua);
|
|
310
300
|
/**
|
|
311
301
|
* @implements
|
|
312
302
|
* @test
|
|
313
303
|
*/
|
|
314
304
|
const source = context => {
|
|
315
305
|
const { state, pos } = context, node = syntaxTree(state).resolveInner(pos, -1);
|
|
316
|
-
if (!
|
|
306
|
+
if (!excludedTypes.has(node.name)) {
|
|
317
307
|
return null;
|
|
318
308
|
}
|
|
319
309
|
const match = context.matchBefore(/(?:(?:^|\S|\.\.)\s+|^|[^\w\s]|\.\.)\w+$|\.{1,2}$/u);
|
|
@@ -358,57 +348,43 @@ const source = context => {
|
|
|
358
348
|
};
|
|
359
349
|
}
|
|
360
350
|
break;
|
|
361
|
-
case '..':
|
|
362
|
-
case '+':
|
|
363
|
-
case '-':
|
|
364
|
-
case '*':
|
|
365
|
-
case '/':
|
|
366
|
-
case '%':
|
|
367
|
-
case '^':
|
|
368
|
-
case '&':
|
|
369
|
-
case '|':
|
|
370
|
-
case '~':
|
|
371
|
-
case '<':
|
|
372
|
-
case '>':
|
|
373
|
-
case '[':
|
|
374
|
-
return {
|
|
375
|
-
from,
|
|
376
|
-
options: [...constants, ...tables],
|
|
377
|
-
validFor,
|
|
378
|
-
};
|
|
379
|
-
case '=':
|
|
380
|
-
case '{':
|
|
381
|
-
case '(':
|
|
382
|
-
case ',':
|
|
383
|
-
return {
|
|
384
|
-
from,
|
|
385
|
-
options: [...builtins, ...constants, ...tables, ...unary],
|
|
386
|
-
validFor,
|
|
387
|
-
};
|
|
388
|
-
case '}':
|
|
389
|
-
case ']':
|
|
390
|
-
case ')':
|
|
391
|
-
return {
|
|
392
|
-
from,
|
|
393
|
-
options: [...binary, ...blocks],
|
|
394
|
-
validFor,
|
|
395
|
-
};
|
|
396
351
|
case ';':
|
|
397
352
|
case '':
|
|
398
353
|
return {
|
|
399
354
|
from,
|
|
400
|
-
options: [...
|
|
355
|
+
options: [...luaKeywords, ...blocks, ...unary, ...constants, ...tables, ...luaBuiltins],
|
|
401
356
|
validFor,
|
|
402
357
|
};
|
|
403
358
|
default:
|
|
404
|
-
if (
|
|
359
|
+
if (/\.\.|[-+*/%^&|~<>[]/u.test(char)) {
|
|
360
|
+
return {
|
|
361
|
+
from,
|
|
362
|
+
options: [...constants, ...tables],
|
|
363
|
+
validFor,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
else if (/[={(,]/u.test(char)) {
|
|
367
|
+
return {
|
|
368
|
+
from,
|
|
369
|
+
options: [...luaBuiltins, ...constants, ...tables, ...unary],
|
|
370
|
+
validFor,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
else if (/[}\])]/u.test(char)) {
|
|
374
|
+
return {
|
|
375
|
+
from,
|
|
376
|
+
options: [...binary, ...blocks],
|
|
377
|
+
validFor,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
else if (pre !== char) {
|
|
405
381
|
const { prevSibling } = node;
|
|
406
382
|
return {
|
|
407
383
|
from,
|
|
408
384
|
options: prevSibling?.name !== 'keyword'
|
|
409
|
-
||
|
|
385
|
+
|| luaBuiltin.includes(sliceDoc(state, prevSibling))
|
|
410
386
|
? [...binary, ...blocks]
|
|
411
|
-
: [...
|
|
387
|
+
: [...luaBuiltins, ...constants, ...tables, ...unary, ...blocks],
|
|
412
388
|
validFor,
|
|
413
389
|
};
|
|
414
390
|
}
|
|
@@ -455,9 +431,9 @@ export const markDocTag = (tree, visibleRanges, state) => {
|
|
|
455
431
|
|| firstLine.startsWith('---')
|
|
456
432
|
&& !(firstLine.endsWith('--') && /[^-]/u.test(firstLine))) {
|
|
457
433
|
while (node.name === 'comment') {
|
|
458
|
-
const comment = sliceDoc(state, node), mt = /^\s*(?:-{2,}\s*)?(@[a-z]+)(\s+\{
|
|
434
|
+
const comment = sliceDoc(state, node), mt = /^\s*(?:-{2,}\s*)?(@[a-z]+)(\s+\{)?/diu.exec(comment);
|
|
459
435
|
if (mt) {
|
|
460
|
-
markDocTagType(decorations, node.from, mt);
|
|
436
|
+
markDocTagType(decorations, node.from, mt, 1);
|
|
461
437
|
}
|
|
462
438
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
463
439
|
const { nextSibling } = node;
|