@bhsd/codemirror-mediawiki 3.0.2 → 3.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 +358 -4
- package/dist/codemirror.d.ts +8 -25
- package/dist/codemirror.js +10 -174
- package/dist/color.d.ts +1 -1
- package/dist/color.js +14 -16
- package/dist/demo.min.js +38 -0
- package/dist/escape.d.ts +3 -2
- package/dist/escape.js +34 -3
- package/dist/fold.d.ts +3 -52
- package/dist/fold.js +10 -11
- package/dist/index.d.ts +98 -0
- package/dist/index.js +316 -0
- package/dist/linter.js +18 -6
- package/dist/lintsource.js +5 -1
- package/dist/main.min.js +23 -23
- package/dist/mw.min.js +26 -26
- package/dist/statusBar.js +1 -1
- package/dist/wiki.min.js +25 -25
- package/i18n/en.json +3 -3
- package/i18n/zh-hans.json +3 -3
- package/i18n/zh-hant.json +3 -3
- package/package.json +19 -19
- package/dist/lsp.d.ts +0 -3
- package/dist/lsp.js +0 -34
package/dist/escape.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { CodeMirror6 } from './codemirror';
|
|
2
|
+
import type { Extension } from '@codemirror/state';
|
|
2
3
|
export declare const escapeHTML: (str: string) => string, escapeURI: (str: string) => string;
|
|
3
|
-
declare const _default:
|
|
4
|
+
declare const _default: (cm: CodeMirror6) => Extension;
|
|
4
5
|
export default _default;
|
package/dist/escape.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { keymap } from '@codemirror/view';
|
|
2
|
+
import { EditorSelection } from '@codemirror/state';
|
|
1
3
|
import { indentMore, indentLess } from '@codemirror/commands';
|
|
4
|
+
import { getLSP } from '@bhsd/browser';
|
|
2
5
|
import { CodeMirror6 } from './codemirror';
|
|
3
6
|
const entity = { '"': 'quot', "'": 'apos', '<': 'lt', '>': 'gt', '&': 'amp', ' ': 'nbsp' };
|
|
4
7
|
/**
|
|
@@ -7,7 +10,7 @@ const entity = { '"': 'quot', "'": 'apos', '<': 'lt', '>': 'gt', '&': 'amp', ' '
|
|
|
7
10
|
* @param cmd 原命令
|
|
8
11
|
*/
|
|
9
12
|
const convert = (func, cmd) => (view) => {
|
|
10
|
-
if (view.state.selection.ranges.some(
|
|
13
|
+
if (view.state.selection.ranges.some(({ empty }) => !empty)) {
|
|
11
14
|
CodeMirror6.replaceSelections(view, func);
|
|
12
15
|
return true;
|
|
13
16
|
}
|
|
@@ -29,7 +32,35 @@ export const escapeHTML = (str) => [...str].map(c => {
|
|
|
29
32
|
}
|
|
30
33
|
return encodeURIComponent(str);
|
|
31
34
|
};
|
|
32
|
-
export default
|
|
35
|
+
export default (cm) => keymap.of([
|
|
33
36
|
{ key: 'Mod-[', run: convert(escapeHTML, indentLess) },
|
|
34
37
|
{ key: 'Mod-]', run: convert(escapeURI, indentMore) },
|
|
35
|
-
|
|
38
|
+
{
|
|
39
|
+
key: 'Mod-\\',
|
|
40
|
+
run(view) {
|
|
41
|
+
const { state } = view, { ranges } = state.selection, lsp = getLSP(view, false, cm.getWikiConfig);
|
|
42
|
+
if (lsp && 'provideRefactoringAction' in lsp && ranges.some(({ empty }) => !empty)) {
|
|
43
|
+
(async () => {
|
|
44
|
+
const replacements = new WeakMap();
|
|
45
|
+
for (const range of ranges) {
|
|
46
|
+
// eslint-disable-next-line no-await-in-loop
|
|
47
|
+
const [action] = await lsp.provideRefactoringAction(state.sliceDoc(range.from, range.to));
|
|
48
|
+
replacements.set(range, action?.edit.changes[''][0].newText);
|
|
49
|
+
}
|
|
50
|
+
view.dispatch(state.changeByRange(range => {
|
|
51
|
+
const insert = replacements.get(range);
|
|
52
|
+
if (insert === undefined) {
|
|
53
|
+
return { range };
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
range: EditorSelection.range(range.from, range.from + insert.length),
|
|
57
|
+
changes: { from: range.from, to: range.to, insert },
|
|
58
|
+
};
|
|
59
|
+
}));
|
|
60
|
+
})();
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
]);
|
package/dist/fold.d.ts
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import type { EditorView, Tooltip, ViewUpdate, BlockInfo, Command } from '@codemirror/view';
|
|
4
|
-
import type { EditorState, StateEffect, Extension } from '@codemirror/state';
|
|
1
|
+
import type { EditorView, Command } from '@codemirror/view';
|
|
2
|
+
import type { EditorState, Extension } from '@codemirror/state';
|
|
5
3
|
import type { SyntaxNode, Tree } from '@lezer/common';
|
|
6
4
|
export interface DocRange {
|
|
7
5
|
from: number;
|
|
8
6
|
to: number;
|
|
9
7
|
}
|
|
10
|
-
declare type AnchorUpdate = (pos: number, range: DocRange) => number;
|
|
11
|
-
export declare const updateSelection: AnchorUpdate;
|
|
12
8
|
/**
|
|
13
9
|
* Update the stack of opening (+) or closing (-) brackets
|
|
14
10
|
* @param state
|
|
@@ -23,54 +19,9 @@ export declare const braceStackUpdate: (state: EditorState, node: SyntaxNode) =>
|
|
|
23
19
|
* @param refOnly 是否仅检查`<ref>`标签
|
|
24
20
|
*/
|
|
25
21
|
export declare const foldable: (state: EditorState, posOrNode: number | SyntaxNode, tree?: Tree | null, refOnly?: boolean) => DocRange | false;
|
|
26
|
-
/**
|
|
27
|
-
* 创建折叠提示
|
|
28
|
-
* @param state
|
|
29
|
-
*/
|
|
30
|
-
export declare const create: (state: EditorState) => Tooltip | null;
|
|
31
|
-
/**
|
|
32
|
-
* 执行折叠
|
|
33
|
-
* @param view
|
|
34
|
-
* @param effects 折叠
|
|
35
|
-
* @param anchor 光标位置
|
|
36
|
-
*/
|
|
37
|
-
export declare const execute: (view: EditorView, effects: StateEffect<DocRange>[], anchor: number) => boolean;
|
|
38
|
-
/**
|
|
39
|
-
* The rightmost position of all selections, to be updated with folding
|
|
40
|
-
* @param state
|
|
41
|
-
*/
|
|
42
|
-
export declare const getAnchor: (state: EditorState) => number;
|
|
43
|
-
/**
|
|
44
|
-
* 折叠所有模板
|
|
45
|
-
* @param state
|
|
46
|
-
* @param tree 语法树
|
|
47
|
-
* @param effects 折叠
|
|
48
|
-
* @param node 语法树节点
|
|
49
|
-
* @param end 终止位置
|
|
50
|
-
* @param anchor 光标位置
|
|
51
|
-
* @param update 更新光标位置
|
|
52
|
-
* @param refOnly 是否仅检查`<ref>`标签
|
|
53
|
-
*/
|
|
54
|
-
export declare const traverse: (state: EditorState, tree: Tree, effects: StateEffect<DocRange>[], node: SyntaxNode | null, end: number, anchor: number, update: AnchorUpdate, refOnly?: boolean) => number;
|
|
55
|
-
export declare class FoldMarker extends GutterMarker {
|
|
56
|
-
readonly open: boolean;
|
|
57
|
-
constructor(open: boolean);
|
|
58
|
-
eq(other: this): boolean;
|
|
59
|
-
toDOM({ state }: EditorView): HTMLSpanElement;
|
|
60
|
-
}
|
|
61
|
-
export declare const findFold: ({ state }: EditorView, line: BlockInfo) => DocRange | undefined;
|
|
62
22
|
export declare const foldableLine: ({ state, viewport: { to: end }, viewportLineBlocks }: EditorView, { from: f, to: t }: DocRange) => DocRange | false;
|
|
63
|
-
export declare const markers: ViewPlugin<{
|
|
64
|
-
markers: RangeSet<FoldMarker>;
|
|
65
|
-
update({ docChanged, viewportChanged, startState, state, view }: ViewUpdate): void;
|
|
66
|
-
}, undefined>;
|
|
67
|
-
/**
|
|
68
|
-
* 生成折叠命令
|
|
69
|
-
* @param refOnly 是否仅检查`<ref>`标签
|
|
70
|
-
*/
|
|
71
|
-
export declare const foldCommand: (refOnly?: boolean) => Command;
|
|
72
23
|
export declare const foldRef: Command;
|
|
73
|
-
declare const _default:
|
|
24
|
+
declare const _default: (e?: Extension | undefined) => Extension;
|
|
74
25
|
export default _default;
|
|
75
26
|
export declare const mediaWikiFold: Extension;
|
|
76
27
|
/**
|
package/dist/fold.js
CHANGED
|
@@ -5,8 +5,7 @@ import { getRegex } from '@bhsd/common';
|
|
|
5
5
|
import { tokens } from './config';
|
|
6
6
|
import { matchTag, getTag } from './matchTag';
|
|
7
7
|
const getExtRegex = /* @__PURE__ */ getRegex(tag => new RegExp(`mw-tag-${tag}(?![a-z])`, 'u'));
|
|
8
|
-
|
|
9
|
-
const updateAll = (pos, { from, to }) => from <= pos && to > pos ? to : pos;
|
|
8
|
+
const updateSelection = (pos, { to }) => Math.max(pos, to), updateAll = (pos, { from, to }) => from <= pos && to > pos ? to : pos;
|
|
10
9
|
/**
|
|
11
10
|
* Check if a SyntaxNode is among the specified components
|
|
12
11
|
* @param keys The keys of the tokens to check
|
|
@@ -145,7 +144,7 @@ export const foldable = (state, posOrNode, tree, refOnly = false) => {
|
|
|
145
144
|
* 创建折叠提示
|
|
146
145
|
* @param state
|
|
147
146
|
*/
|
|
148
|
-
|
|
147
|
+
const create = (state) => {
|
|
149
148
|
const { selection: { main: { head } } } = state, range = foldable(state, head);
|
|
150
149
|
if (range) {
|
|
151
150
|
const { from, to } = range;
|
|
@@ -179,7 +178,7 @@ export const create = (state) => {
|
|
|
179
178
|
* @param effects 折叠
|
|
180
179
|
* @param anchor 光标位置
|
|
181
180
|
*/
|
|
182
|
-
|
|
181
|
+
const execute = (view, effects, anchor) => {
|
|
183
182
|
if (effects.length > 0) {
|
|
184
183
|
view.dom.querySelector('.cm-tooltip-fold')?.remove();
|
|
185
184
|
// Fold the template(s) and update the cursor position
|
|
@@ -192,7 +191,7 @@ export const execute = (view, effects, anchor) => {
|
|
|
192
191
|
* The rightmost position of all selections, to be updated with folding
|
|
193
192
|
* @param state
|
|
194
193
|
*/
|
|
195
|
-
|
|
194
|
+
const getAnchor = (state) => Math.max(...state.selection.ranges.map(({ to }) => to));
|
|
196
195
|
/**
|
|
197
196
|
* 折叠所有模板
|
|
198
197
|
* @param state
|
|
@@ -204,7 +203,7 @@ export const getAnchor = (state) => Math.max(...state.selection.ranges.map(({ to
|
|
|
204
203
|
* @param update 更新光标位置
|
|
205
204
|
* @param refOnly 是否仅检查`<ref>`标签
|
|
206
205
|
*/
|
|
207
|
-
|
|
206
|
+
const traverse = (state, tree, effects, node, end, anchor, update, refOnly) => {
|
|
208
207
|
while (node && node.from <= end) {
|
|
209
208
|
/* eslint-disable no-param-reassign */
|
|
210
209
|
const range = foldable(state, node, tree, refOnly);
|
|
@@ -220,7 +219,7 @@ export const traverse = (state, tree, effects, node, end, anchor, update, refOnl
|
|
|
220
219
|
}
|
|
221
220
|
return anchor;
|
|
222
221
|
};
|
|
223
|
-
|
|
222
|
+
class FoldMarker extends GutterMarker {
|
|
224
223
|
constructor(open) {
|
|
225
224
|
super();
|
|
226
225
|
this.open = open;
|
|
@@ -236,7 +235,7 @@ export class FoldMarker extends GutterMarker {
|
|
|
236
235
|
}
|
|
237
236
|
}
|
|
238
237
|
const canFold = /* @__PURE__ */ new FoldMarker(true), canUnfold = /* @__PURE__ */ new FoldMarker(false);
|
|
239
|
-
|
|
238
|
+
const findFold = ({ state }, line) => {
|
|
240
239
|
let found;
|
|
241
240
|
state.field(foldState, false)?.between(line.from, line.to, (from, to) => {
|
|
242
241
|
if (!found && to === line.to) {
|
|
@@ -310,7 +309,7 @@ const buildMarkers = (view) => {
|
|
|
310
309
|
}
|
|
311
310
|
return builder.finish();
|
|
312
311
|
};
|
|
313
|
-
|
|
312
|
+
const markers = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
314
313
|
constructor(view) {
|
|
315
314
|
this.markers = buildMarkers(view);
|
|
316
315
|
}
|
|
@@ -329,12 +328,12 @@ const defaultFoldExtension = [foldGutter(), keymap.of(foldKeymap)];
|
|
|
329
328
|
* 生成折叠命令
|
|
330
329
|
* @param refOnly 是否仅检查`<ref>`标签
|
|
331
330
|
*/
|
|
332
|
-
|
|
331
|
+
const foldCommand = (refOnly) => view => {
|
|
333
332
|
const { state } = view, tree = syntaxTree(state), effects = [], anchor = traverse(state, tree, effects, tree.topNode.firstChild, Infinity, getAnchor(state), updateAll, refOnly);
|
|
334
333
|
return execute(view, effects, anchor);
|
|
335
334
|
};
|
|
336
335
|
export const foldRef = /* @__PURE__ */ foldCommand(true);
|
|
337
|
-
export default
|
|
336
|
+
export default ((e = defaultFoldExtension) => e);
|
|
338
337
|
export const mediaWikiFold = /* @__PURE__ */ (() => [
|
|
339
338
|
codeFolding({
|
|
340
339
|
placeholderDOM(view) {
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { CodeMirror6 } from './codemirror';
|
|
2
|
+
import type { LanguageSupport } from '@codemirror/language';
|
|
3
|
+
import type { MwConfig } from './token';
|
|
4
|
+
import type { LintSourceGetter } from './lintsource';
|
|
5
|
+
export type { MwConfig };
|
|
6
|
+
export { CodeMirror6 };
|
|
7
|
+
/** Register the `highlightSpecialChars` extension */
|
|
8
|
+
export declare const registerHighlightSpecialChars: () => void;
|
|
9
|
+
/** Register the `highlightActiveLine` extension */
|
|
10
|
+
export declare const registerHighlightActiveLine: () => void;
|
|
11
|
+
/** Register the `highlightWhitespace` extension */
|
|
12
|
+
export declare const registerHighlightWhitespace: () => void;
|
|
13
|
+
/** Register the `highlightTrailingWhitespace` extension */
|
|
14
|
+
export declare const registerHighlightTrailingWhitespace: () => void;
|
|
15
|
+
/** Register the `highlightSelectionMatches` extension */
|
|
16
|
+
export declare const registerHighlightSelectionMatches: () => void;
|
|
17
|
+
/** Register the `bracketMatching` extension */
|
|
18
|
+
export declare const registerBracketMatching: () => void;
|
|
19
|
+
/** Register the `closeBrackets` extension */
|
|
20
|
+
export declare const registerCloseBrackets: () => void;
|
|
21
|
+
/** Register the `scrollPastEnd` extension */
|
|
22
|
+
export declare const registerScrollPastEnd: () => void;
|
|
23
|
+
/** Register the `allowMultipleSelections` extension */
|
|
24
|
+
export declare const registerAllowMultipleSelections: () => void;
|
|
25
|
+
/** Register the `autocompletion` extension */
|
|
26
|
+
export declare const registerAutocompletion: () => void;
|
|
27
|
+
/** Register the `codeFolding` extension */
|
|
28
|
+
export declare const registerCodeFolding: () => void;
|
|
29
|
+
/** Register the `colorPicker` extension */
|
|
30
|
+
export declare const registerColorPicker: () => void;
|
|
31
|
+
/** Register all common extensions */
|
|
32
|
+
export declare const registerCommonExtensions: () => void;
|
|
33
|
+
/** Register MediaWiki language support */
|
|
34
|
+
export declare const registerMediaWiki: () => void;
|
|
35
|
+
/** Register the `openLinks` extension */
|
|
36
|
+
export declare const registerOpenLinks: () => void;
|
|
37
|
+
/** Register the `escape` extension */
|
|
38
|
+
export declare const registerEscape: () => void;
|
|
39
|
+
/** Register the `refHover` extension */
|
|
40
|
+
export declare const registerRefHover: () => void;
|
|
41
|
+
/** Register the `hover` extension */
|
|
42
|
+
export declare const registerHover: () => void;
|
|
43
|
+
/** Register the `signatureHelp` extension */
|
|
44
|
+
export declare const registerSignatureHelp: () => void;
|
|
45
|
+
/** Register the `inlayHints` extension */
|
|
46
|
+
export declare const registerInlayHints: () => void;
|
|
47
|
+
/** Register the `colorPicker` extension for MediaWiki */
|
|
48
|
+
export declare const registerColorPickerForMediaWiki: () => void;
|
|
49
|
+
/** Register the `bracketMatching` extension for MediaWiki */
|
|
50
|
+
export declare const registerBracketMatchingForMediaWiki: () => void;
|
|
51
|
+
/** Register the `codeFolding` extension for MediaWiki */
|
|
52
|
+
export declare const registerCodeFoldingForMediaWiki: () => void;
|
|
53
|
+
/** Register MediaWiki core language support */
|
|
54
|
+
export declare const registerMediaWikiCore: () => void;
|
|
55
|
+
/** Register mixed MediaWiki-HTML language support */
|
|
56
|
+
export declare const registerHTML: () => void;
|
|
57
|
+
/** Register HTML core language support */
|
|
58
|
+
export declare const registerHTMLCore: () => void;
|
|
59
|
+
/** Register JavaScript language support */
|
|
60
|
+
export declare const registerJavaScript: () => void;
|
|
61
|
+
/** Register JavaScript core language support */
|
|
62
|
+
export declare const registerJavaScriptCore: () => void;
|
|
63
|
+
/** Register CSS language support */
|
|
64
|
+
export declare const registerCSS: () => void;
|
|
65
|
+
/** Register the `colorPicker` extension for CSS */
|
|
66
|
+
export declare const registerColorPickerForCSS: () => void;
|
|
67
|
+
/** Register CSS core language support */
|
|
68
|
+
export declare const registerCSSCore: () => void;
|
|
69
|
+
/** Register JSON language support */
|
|
70
|
+
export declare const registerJSON: () => void;
|
|
71
|
+
/** Register JSON core language support */
|
|
72
|
+
export declare const registerJSONCore: () => void;
|
|
73
|
+
/** Register Lua language support */
|
|
74
|
+
export declare const registerLua: () => void;
|
|
75
|
+
/** Register Lua core language support */
|
|
76
|
+
export declare const registerLuaCore: () => void;
|
|
77
|
+
/** Register Vue language support */
|
|
78
|
+
export declare const registerVue: () => void;
|
|
79
|
+
/** Register the `closeBrackets` extension for Vue */
|
|
80
|
+
export declare const registerCloseBracketsForVue: () => void;
|
|
81
|
+
/** Register the `colorPicker` extension for Vue */
|
|
82
|
+
export declare const registerColorPickerForVue: () => void;
|
|
83
|
+
/** Register Vue core language support */
|
|
84
|
+
export declare const registerVueCore: () => void;
|
|
85
|
+
/**
|
|
86
|
+
* Register a custom language support
|
|
87
|
+
* @param name language name
|
|
88
|
+
* @param lang language support
|
|
89
|
+
* @param lintSource optional linter
|
|
90
|
+
*/
|
|
91
|
+
export declare const registerLanguage: (name: string, lang: (config?: unknown) => LanguageSupport, lintSource?: LintSourceGetter) => void;
|
|
92
|
+
/**
|
|
93
|
+
* Register a custom language support without common extensions
|
|
94
|
+
* @param name language name
|
|
95
|
+
* @param lang language support
|
|
96
|
+
* @param lintSource optional linter
|
|
97
|
+
*/
|
|
98
|
+
export declare const registerLanguageCore: (name: string, lang: (config?: unknown) => LanguageSupport, lintSource?: LintSourceGetter) => void;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { keymap, highlightSpecialChars, highlightActiveLine, highlightWhitespace, highlightTrailingWhitespace, scrollPastEnd, drawSelection, rectangularSelection, crosshairCursor, } from '@codemirror/view';
|
|
2
|
+
import { EditorState } from '@codemirror/state';
|
|
3
|
+
import { highlightSelectionMatches } from '@codemirror/search';
|
|
4
|
+
import { closeBrackets, autocompletion, acceptCompletion, completionKeymap, startCompletion, } from '@codemirror/autocomplete';
|
|
5
|
+
import { json } from '@codemirror/lang-json';
|
|
6
|
+
import { autoCloseTags } from '@codemirror/lang-html';
|
|
7
|
+
import { css as cssParser } from '@codemirror/legacy-modes/mode/css';
|
|
8
|
+
import { getLSP } from '@bhsd/browser';
|
|
9
|
+
import { colorPicker as cssColorPicker, colorPickerTheme, makeColorPicker } from '@bhsd/codemirror-css-color-picker';
|
|
10
|
+
import colorPicker, { discoverColors } from './color';
|
|
11
|
+
import { mediawiki, html, FullMediaWiki } from './mediawiki';
|
|
12
|
+
import escape from './escape';
|
|
13
|
+
import codeFolding, { mediaWikiFold } from './fold';
|
|
14
|
+
import tagMatchingState from './matchTag';
|
|
15
|
+
import refHover from './ref';
|
|
16
|
+
import magicWordHover from './hover';
|
|
17
|
+
import signatureHelp from './signature';
|
|
18
|
+
import inlayHints from './inlay';
|
|
19
|
+
import { getWikiLintSource, getJsLintSource, getCssLintSource, getJsonLintSource, getLuaLintSource, getVueLintSource, } from './lintsource';
|
|
20
|
+
import openLinks from './openLinks';
|
|
21
|
+
import { tagModes, getStaticMwConfig } from './static';
|
|
22
|
+
import bidiIsolation from './bidi';
|
|
23
|
+
import toolKeymap from './keymap';
|
|
24
|
+
import bracketMatching from './matchBrackets';
|
|
25
|
+
import javascript from './javascript';
|
|
26
|
+
import css from './css';
|
|
27
|
+
import lua from './lua';
|
|
28
|
+
import vue from './vue';
|
|
29
|
+
import { CodeMirror6, avail, languages, linterRegistry, destroyListeners, plain } from './codemirror';
|
|
30
|
+
export { CodeMirror6 };
|
|
31
|
+
/**
|
|
32
|
+
* 注册通用扩展
|
|
33
|
+
* @param name 扩展名
|
|
34
|
+
* @param ext 扩展
|
|
35
|
+
*/
|
|
36
|
+
const registerExtension = (name, ext) => {
|
|
37
|
+
avail[name] ??= [];
|
|
38
|
+
const addon = avail[name];
|
|
39
|
+
addon[0] = ext;
|
|
40
|
+
};
|
|
41
|
+
/** Register the `highlightSpecialChars` extension */
|
|
42
|
+
export const registerHighlightSpecialChars = () => {
|
|
43
|
+
registerExtension('highlightSpecialChars', highlightSpecialChars);
|
|
44
|
+
};
|
|
45
|
+
/** Register the `highlightActiveLine` extension */
|
|
46
|
+
export const registerHighlightActiveLine = () => {
|
|
47
|
+
registerExtension('highlightActiveLine', highlightActiveLine);
|
|
48
|
+
};
|
|
49
|
+
/** Register the `highlightWhitespace` extension */
|
|
50
|
+
export const registerHighlightWhitespace = () => {
|
|
51
|
+
registerExtension('highlightWhitespace', highlightWhitespace);
|
|
52
|
+
};
|
|
53
|
+
/** Register the `highlightTrailingWhitespace` extension */
|
|
54
|
+
export const registerHighlightTrailingWhitespace = () => {
|
|
55
|
+
registerExtension('highlightTrailingWhitespace', highlightTrailingWhitespace);
|
|
56
|
+
};
|
|
57
|
+
/** Register the `highlightSelectionMatches` extension */
|
|
58
|
+
export const registerHighlightSelectionMatches = () => {
|
|
59
|
+
registerExtension('highlightSelectionMatches', highlightSelectionMatches);
|
|
60
|
+
};
|
|
61
|
+
/** Register the `bracketMatching` extension */
|
|
62
|
+
export const registerBracketMatching = () => {
|
|
63
|
+
registerExtension('bracketMatching', ([config, e = []] = []) => [
|
|
64
|
+
bracketMatching(config),
|
|
65
|
+
e,
|
|
66
|
+
]);
|
|
67
|
+
};
|
|
68
|
+
/** Register the `closeBrackets` extension */
|
|
69
|
+
export const registerCloseBrackets = () => {
|
|
70
|
+
registerExtension('closeBrackets', (e = []) => [closeBrackets(), e]);
|
|
71
|
+
};
|
|
72
|
+
/** Register the `scrollPastEnd` extension */
|
|
73
|
+
export const registerScrollPastEnd = () => {
|
|
74
|
+
registerExtension('scrollPastEnd', scrollPastEnd);
|
|
75
|
+
};
|
|
76
|
+
/** Register the `allowMultipleSelections` extension */
|
|
77
|
+
export const registerAllowMultipleSelections = () => {
|
|
78
|
+
registerExtension('allowMultipleSelections', () => [
|
|
79
|
+
EditorState.allowMultipleSelections.of(true),
|
|
80
|
+
drawSelection(),
|
|
81
|
+
rectangularSelection(),
|
|
82
|
+
crosshairCursor(),
|
|
83
|
+
]);
|
|
84
|
+
};
|
|
85
|
+
/** Register the `autocompletion` extension */
|
|
86
|
+
export const registerAutocompletion = () => {
|
|
87
|
+
registerExtension('autocompletion', () => [
|
|
88
|
+
autocompletion({ defaultKeymap: false }),
|
|
89
|
+
keymap.of([
|
|
90
|
+
...completionKeymap.filter(({ run }) => run !== startCompletion),
|
|
91
|
+
{ key: 'Shift-Enter', run: startCompletion },
|
|
92
|
+
{ key: 'Tab', run: acceptCompletion },
|
|
93
|
+
]),
|
|
94
|
+
]);
|
|
95
|
+
};
|
|
96
|
+
/** Register the `codeFolding` extension */
|
|
97
|
+
export const registerCodeFolding = () => {
|
|
98
|
+
registerExtension('codeFolding', codeFolding);
|
|
99
|
+
};
|
|
100
|
+
/** Register the `colorPicker` extension */
|
|
101
|
+
export const registerColorPicker = () => {
|
|
102
|
+
registerExtension('colorPicker', colorPicker);
|
|
103
|
+
};
|
|
104
|
+
/** 注册所有通用扩展(除`colorPicker`) */
|
|
105
|
+
const registerExtensions = () => {
|
|
106
|
+
highlightSpecialChars();
|
|
107
|
+
registerHighlightActiveLine();
|
|
108
|
+
registerHighlightWhitespace();
|
|
109
|
+
registerHighlightTrailingWhitespace();
|
|
110
|
+
registerHighlightSelectionMatches();
|
|
111
|
+
registerBracketMatching();
|
|
112
|
+
registerCloseBrackets();
|
|
113
|
+
registerScrollPastEnd();
|
|
114
|
+
registerAllowMultipleSelections();
|
|
115
|
+
registerAutocompletion();
|
|
116
|
+
registerCodeFolding();
|
|
117
|
+
};
|
|
118
|
+
/** Register all common extensions */
|
|
119
|
+
export const registerCommonExtensions = () => {
|
|
120
|
+
registerExtensions();
|
|
121
|
+
registerColorPicker();
|
|
122
|
+
};
|
|
123
|
+
function mediawikiOnly(ext) {
|
|
124
|
+
return typeof ext === 'function'
|
|
125
|
+
? [(enable, cm) => enable ? ext(cm) : [], { mediawiki: true }]
|
|
126
|
+
: [(e = []) => e, { mediawiki: ext }];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 注册特定语言的扩展
|
|
130
|
+
* @param lang 语言
|
|
131
|
+
* @param name 扩展名
|
|
132
|
+
* @param ext 扩展
|
|
133
|
+
*/
|
|
134
|
+
const registerLangExtension = (lang, name, ext) => {
|
|
135
|
+
avail[name] ??= [() => []];
|
|
136
|
+
const addon = avail[name];
|
|
137
|
+
addon[1] ??= {};
|
|
138
|
+
addon[1][lang] = ext;
|
|
139
|
+
};
|
|
140
|
+
/** Register MediaWiki language support */
|
|
141
|
+
export const registerMediaWiki = () => {
|
|
142
|
+
registerCommonExtensions();
|
|
143
|
+
registerMediaWikiCore();
|
|
144
|
+
registerOpenLinks();
|
|
145
|
+
registerEscape();
|
|
146
|
+
registerRefHover();
|
|
147
|
+
registerHover();
|
|
148
|
+
registerSignatureHelp();
|
|
149
|
+
registerInlayHints();
|
|
150
|
+
registerColorPickerForMediaWiki();
|
|
151
|
+
registerBracketMatchingForMediaWiki();
|
|
152
|
+
registerCodeFoldingForMediaWiki();
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* 注册MediaWiki专用扩展
|
|
156
|
+
* @param name 扩展名
|
|
157
|
+
* @param ext 扩展
|
|
158
|
+
*/
|
|
159
|
+
const registerExtensionForMediaWiki = (name, ext) => {
|
|
160
|
+
avail[name] ??= mediawikiOnly(ext);
|
|
161
|
+
};
|
|
162
|
+
/** Register the `openLinks` extension */
|
|
163
|
+
export const registerOpenLinks = () => {
|
|
164
|
+
registerExtensionForMediaWiki('openLinks', openLinks);
|
|
165
|
+
};
|
|
166
|
+
/** Register the `escape` extension */
|
|
167
|
+
export const registerEscape = () => {
|
|
168
|
+
registerExtensionForMediaWiki('escape', escape);
|
|
169
|
+
};
|
|
170
|
+
/** Register the `refHover` extension */
|
|
171
|
+
export const registerRefHover = () => {
|
|
172
|
+
registerExtensionForMediaWiki('refHover', refHover);
|
|
173
|
+
};
|
|
174
|
+
/** Register the `hover` extension */
|
|
175
|
+
export const registerHover = () => {
|
|
176
|
+
registerExtensionForMediaWiki('hover', magicWordHover);
|
|
177
|
+
};
|
|
178
|
+
/** Register the `signatureHelp` extension */
|
|
179
|
+
export const registerSignatureHelp = () => {
|
|
180
|
+
registerExtensionForMediaWiki('signatureHelp', signatureHelp);
|
|
181
|
+
};
|
|
182
|
+
/** Register the `inlayHints` extension */
|
|
183
|
+
export const registerInlayHints = () => {
|
|
184
|
+
registerExtensionForMediaWiki('inlayHints', inlayHints);
|
|
185
|
+
};
|
|
186
|
+
/** Register the `colorPicker` extension for MediaWiki */
|
|
187
|
+
export const registerColorPickerForMediaWiki = () => {
|
|
188
|
+
registerLangExtension('mediawiki', 'colorPicker', [
|
|
189
|
+
[makeColorPicker({ discoverColors }), colorPickerTheme],
|
|
190
|
+
{ marginLeft: '0.6ch' },
|
|
191
|
+
]);
|
|
192
|
+
};
|
|
193
|
+
/** Register the `bracketMatching` extension for MediaWiki */
|
|
194
|
+
export const registerBracketMatchingForMediaWiki = () => {
|
|
195
|
+
registerLangExtension('mediawiki', 'bracketMatching', [
|
|
196
|
+
{ brackets: '()[]{}()【】[]{}' },
|
|
197
|
+
tagMatchingState,
|
|
198
|
+
]);
|
|
199
|
+
};
|
|
200
|
+
/** Register the `codeFolding` extension for MediaWiki */
|
|
201
|
+
export const registerCodeFoldingForMediaWiki = () => {
|
|
202
|
+
registerLangExtension('mediawiki', 'codeFolding', mediaWikiFold);
|
|
203
|
+
};
|
|
204
|
+
/** Register MediaWiki core language support */
|
|
205
|
+
export const registerMediaWikiCore = () => {
|
|
206
|
+
CodeMirror6.getMwConfig = (config) => getStaticMwConfig(config, tagModes);
|
|
207
|
+
languages['mediawiki'] = (config) => [
|
|
208
|
+
mediawiki(config),
|
|
209
|
+
plain(),
|
|
210
|
+
bidiIsolation,
|
|
211
|
+
toolKeymap,
|
|
212
|
+
];
|
|
213
|
+
linterRegistry['mediawiki'] = getWikiLintSource;
|
|
214
|
+
destroyListeners.push(view => getLSP(view)?.destroy());
|
|
215
|
+
};
|
|
216
|
+
/** Register mixed MediaWiki-HTML language support */
|
|
217
|
+
export const registerHTML = () => {
|
|
218
|
+
registerCommonExtensions();
|
|
219
|
+
registerHTMLCore();
|
|
220
|
+
};
|
|
221
|
+
/** Register HTML core language support */
|
|
222
|
+
export const registerHTMLCore = () => {
|
|
223
|
+
Object.assign(FullMediaWiki.prototype, {
|
|
224
|
+
css() {
|
|
225
|
+
return cssParser;
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
languages['html'] = html;
|
|
229
|
+
};
|
|
230
|
+
/** Register JavaScript language support */
|
|
231
|
+
export const registerJavaScript = () => {
|
|
232
|
+
registerExtensions();
|
|
233
|
+
registerJavaScriptCore();
|
|
234
|
+
};
|
|
235
|
+
/** Register JavaScript core language support */
|
|
236
|
+
export const registerJavaScriptCore = () => {
|
|
237
|
+
languages['javascript'] = javascript;
|
|
238
|
+
linterRegistry['javascript'] = getJsLintSource;
|
|
239
|
+
};
|
|
240
|
+
/** Register CSS language support */
|
|
241
|
+
export const registerCSS = () => {
|
|
242
|
+
registerCommonExtensions();
|
|
243
|
+
registerCSSCore();
|
|
244
|
+
registerColorPickerForCSS();
|
|
245
|
+
};
|
|
246
|
+
/** Register the `colorPicker` extension for CSS */
|
|
247
|
+
export const registerColorPickerForCSS = () => {
|
|
248
|
+
registerLangExtension('css', 'colorPicker', [cssColorPicker]);
|
|
249
|
+
};
|
|
250
|
+
/** Register CSS core language support */
|
|
251
|
+
export const registerCSSCore = () => {
|
|
252
|
+
languages['css'] = css;
|
|
253
|
+
linterRegistry['css'] = getCssLintSource;
|
|
254
|
+
};
|
|
255
|
+
/** Register JSON language support */
|
|
256
|
+
export const registerJSON = () => {
|
|
257
|
+
registerExtensions();
|
|
258
|
+
registerJSONCore();
|
|
259
|
+
};
|
|
260
|
+
/** Register JSON core language support */
|
|
261
|
+
export const registerJSONCore = () => {
|
|
262
|
+
languages['json'] = json;
|
|
263
|
+
linterRegistry['json'] = getJsonLintSource;
|
|
264
|
+
};
|
|
265
|
+
/** Register Lua language support */
|
|
266
|
+
export const registerLua = () => {
|
|
267
|
+
registerExtensions();
|
|
268
|
+
registerLuaCore();
|
|
269
|
+
};
|
|
270
|
+
/** Register Lua core language support */
|
|
271
|
+
export const registerLuaCore = () => {
|
|
272
|
+
languages['lua'] = lua;
|
|
273
|
+
linterRegistry['lua'] = getLuaLintSource;
|
|
274
|
+
};
|
|
275
|
+
/** Register Vue language support */
|
|
276
|
+
export const registerVue = () => {
|
|
277
|
+
registerCommonExtensions();
|
|
278
|
+
registerVueCore();
|
|
279
|
+
registerCloseBracketsForVue();
|
|
280
|
+
registerColorPickerForVue();
|
|
281
|
+
};
|
|
282
|
+
/** Register the `closeBrackets` extension for Vue */
|
|
283
|
+
export const registerCloseBracketsForVue = () => {
|
|
284
|
+
registerLangExtension('vue', 'closeBrackets', autoCloseTags);
|
|
285
|
+
};
|
|
286
|
+
/** Register the `colorPicker` extension for Vue */
|
|
287
|
+
export const registerColorPickerForVue = () => {
|
|
288
|
+
registerLangExtension('vue', 'colorPicker', [cssColorPicker]);
|
|
289
|
+
};
|
|
290
|
+
/** Register Vue core language support */
|
|
291
|
+
export const registerVueCore = () => {
|
|
292
|
+
languages['vue'] = vue;
|
|
293
|
+
linterRegistry['vue'] = getVueLintSource;
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Register a custom language support
|
|
297
|
+
* @param name language name
|
|
298
|
+
* @param lang language support
|
|
299
|
+
* @param lintSource optional linter
|
|
300
|
+
*/
|
|
301
|
+
export const registerLanguage = (name, lang, lintSource) => {
|
|
302
|
+
registerCommonExtensions();
|
|
303
|
+
registerLanguageCore(name, lang, lintSource);
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Register a custom language support without common extensions
|
|
307
|
+
* @param name language name
|
|
308
|
+
* @param lang language support
|
|
309
|
+
* @param lintSource optional linter
|
|
310
|
+
*/
|
|
311
|
+
export const registerLanguageCore = (name, lang, lintSource) => {
|
|
312
|
+
languages[name] = lang;
|
|
313
|
+
if (lintSource) {
|
|
314
|
+
linterRegistry[name] = lintSource;
|
|
315
|
+
}
|
|
316
|
+
};
|