@difizen/libro-cofine-editor 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/es/editor-contribution.d.ts +10 -0
- package/es/editor-contribution.d.ts.map +1 -0
- package/es/editor-contribution.js +31 -0
- package/es/index.d.ts +7 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +6 -0
- package/es/index.less +32 -0
- package/es/language/lsp/completion-provider.d.ts +13 -0
- package/es/language/lsp/completion-provider.d.ts.map +1 -0
- package/es/language/lsp/completion-provider.js +290 -0
- package/es/language/lsp/diagnostic-provider.d.ts +22 -0
- package/es/language/lsp/diagnostic-provider.d.ts.map +1 -0
- package/es/language/lsp/diagnostic-provider.js +161 -0
- package/es/language/lsp/format-provider.d.ts +9 -0
- package/es/language/lsp/format-provider.d.ts.map +1 -0
- package/es/language/lsp/format-provider.js +139 -0
- package/es/language/lsp/hover-provider.d.ts +8 -0
- package/es/language/lsp/hover-provider.d.ts.map +1 -0
- package/es/language/lsp/hover-provider.js +136 -0
- package/es/language/lsp/language-feature-provider.d.ts +17 -0
- package/es/language/lsp/language-feature-provider.d.ts.map +1 -0
- package/es/language/lsp/language-feature-provider.js +89 -0
- package/es/language/lsp/lsp-contribution.d.ts +25 -0
- package/es/language/lsp/lsp-contribution.d.ts.map +1 -0
- package/es/language/lsp/lsp-contribution.js +213 -0
- package/es/language/lsp/module.d.ts +2 -0
- package/es/language/lsp/module.d.ts.map +1 -0
- package/es/language/lsp/module.js +3 -0
- package/es/language/lsp/semantic-highlight-provider.d.ts +9 -0
- package/es/language/lsp/semantic-highlight-provider.d.ts.map +1 -0
- package/es/language/lsp/semantic-highlight-provider.js +41 -0
- package/es/language/lsp/signature-help-provider.d.ts +8 -0
- package/es/language/lsp/signature-help-provider.d.ts.map +1 -0
- package/es/language/lsp/signature-help-provider.js +108 -0
- package/es/language/lsp/type-concerters.d.ts +7 -0
- package/es/language/lsp/type-concerters.d.ts.map +1 -0
- package/es/language/lsp/type-concerters.js +37 -0
- package/es/language/python/data/MagicPython.tmLanguage.json +4213 -0
- package/es/language/python/data/MagicRegExp.tmLanguage.json +497 -0
- package/es/language/python/data/configurations/python.json +135 -0
- package/es/language/python/data/snippets/python.snippets.json +223 -0
- package/es/language/python/module.d.ts +2 -0
- package/es/language/python/module.d.ts.map +1 -0
- package/es/language/python/module.js +3 -0
- package/es/language/python/python-builtin.d.ts +86 -0
- package/es/language/python/python-builtin.d.ts.map +1 -0
- package/es/language/python/python-builtin.js +569 -0
- package/es/language/python/python-language-feature.d.ts +26 -0
- package/es/language/python/python-language-feature.d.ts.map +1 -0
- package/es/language/python/python-language-feature.js +174 -0
- package/es/language-specs.d.ts +33 -0
- package/es/language-specs.d.ts.map +1 -0
- package/es/language-specs.js +115 -0
- package/es/libro-e2-editor.d.ts +277 -0
- package/es/libro-e2-editor.d.ts.map +1 -0
- package/es/libro-e2-editor.js +720 -0
- package/es/libro-e2-preload.d.ts +5 -0
- package/es/libro-e2-preload.d.ts.map +1 -0
- package/es/libro-e2-preload.js +57 -0
- package/es/libro-sql-api.d.ts +8 -0
- package/es/libro-sql-api.d.ts.map +1 -0
- package/es/libro-sql-api.js +26 -0
- package/es/module.d.ts +3 -0
- package/es/module.d.ts.map +1 -0
- package/es/module.js +44 -0
- package/es/placeholder.d.ts +31 -0
- package/es/placeholder.d.ts.map +1 -0
- package/es/placeholder.js +101 -0
- package/es/theme/data/jupyter_dark.json +406 -0
- package/es/theme/data/jupyter_hc_dark.json +385 -0
- package/es/theme/data/jupyter_hc_light.json +386 -0
- package/es/theme/data/jupyter_light.json +386 -0
- package/es/theme/data/libro_dark.json +186 -0
- package/es/theme/data/libro_light.json +170 -0
- package/es/theme/libro-python-theme-contribution.d.ts +6 -0
- package/es/theme/libro-python-theme-contribution.d.ts.map +1 -0
- package/es/theme/libro-python-theme-contribution.js +49 -0
- package/es/theme/module.d.ts +2 -0
- package/es/theme/module.d.ts.map +1 -0
- package/es/theme/module.js +3 -0
- package/es/types.d.ts +10 -0
- package/es/types.d.ts.map +1 -0
- package/es/types.js +3 -0
- package/package.json +67 -0
- package/src/editor-contribution.ts +30 -0
- package/src/index.less +32 -0
- package/src/index.spec.ts +8 -0
- package/src/index.ts +6 -0
- package/src/language/lsp/completion-provider.ts +214 -0
- package/src/language/lsp/diagnostic-provider.ts +148 -0
- package/src/language/lsp/format-provider.ts +87 -0
- package/src/language/lsp/hover-provider.ts +98 -0
- package/src/language/lsp/language-feature-provider.ts +69 -0
- package/src/language/lsp/lsp-contribution.ts +159 -0
- package/src/language/lsp/module.ts +5 -0
- package/src/language/lsp/semantic-highlight-provider.ts +26 -0
- package/src/language/lsp/signature-help-provider.ts +65 -0
- package/src/language/lsp/type-concerters.ts +72 -0
- package/src/language/python/data/MagicPython.tmLanguage.json +4213 -0
- package/src/language/python/data/MagicRegExp.tmLanguage.json +497 -0
- package/src/language/python/data/configurations/python.json +135 -0
- package/src/language/python/data/snippets/python.snippets.json +223 -0
- package/src/language/python/module.ts +5 -0
- package/src/language/python/python-builtin.ts +891 -0
- package/src/language/python/python-language-feature.ts +163 -0
- package/src/language-specs.ts +99 -0
- package/src/libro-e2-editor.ts +922 -0
- package/src/libro-e2-preload.ts +23 -0
- package/src/libro-sql-api.ts +20 -0
- package/src/module.ts +44 -0
- package/src/placeholder.ts +100 -0
- package/src/theme/data/jupyter_dark.json +406 -0
- package/src/theme/data/jupyter_hc_dark.json +385 -0
- package/src/theme/data/jupyter_hc_light.json +386 -0
- package/src/theme/data/jupyter_light.json +386 -0
- package/src/theme/data/libro_dark.json +186 -0
- package/src/theme/data/libro_light.json +170 -0
- package/src/theme/libro-python-theme-contribution.ts +36 -0
- package/src/theme/module.ts +5 -0
- package/src/types.ts +11 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type { LibroService } from '@difizen/libro-core';
|
|
2
|
+
import { EditorCellView } from '@difizen/libro-core';
|
|
3
|
+
import type { LSPConnection, VirtualDocument } from '@difizen/libro-lsp';
|
|
4
|
+
import * as monaco from '@difizen/monaco-editor-core';
|
|
5
|
+
|
|
6
|
+
import { LibroE2Editor } from '../../libro-e2-editor.js';
|
|
7
|
+
import { MonacoRange, MonacoUri } from '../../types.js';
|
|
8
|
+
|
|
9
|
+
import { LangaugeFeatureProvider } from './language-feature-provider.js';
|
|
10
|
+
|
|
11
|
+
export enum MarkerSeverity {
|
|
12
|
+
Hint = 1,
|
|
13
|
+
Info = 2,
|
|
14
|
+
Warning = 4,
|
|
15
|
+
Error = 8,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const vererityMap = {
|
|
19
|
+
1: MarkerSeverity.Error,
|
|
20
|
+
2: MarkerSeverity.Warning,
|
|
21
|
+
3: MarkerSeverity.Info,
|
|
22
|
+
4: MarkerSeverity.Hint,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export class DiagnosticProvider extends LangaugeFeatureProvider {
|
|
26
|
+
constructor(
|
|
27
|
+
libroService: LibroService,
|
|
28
|
+
lspConnection: LSPConnection,
|
|
29
|
+
virtualDocument: VirtualDocument,
|
|
30
|
+
) {
|
|
31
|
+
super(libroService, lspConnection, virtualDocument);
|
|
32
|
+
this.processDiagnostic();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected diagnosticList: {
|
|
36
|
+
model: monaco.editor.ITextModel;
|
|
37
|
+
markers: monaco.editor.IMarkerData[];
|
|
38
|
+
}[] = [];
|
|
39
|
+
|
|
40
|
+
protected addDiagnostic(
|
|
41
|
+
model: monaco.editor.ITextModel,
|
|
42
|
+
marker: monaco.editor.IMarkerData,
|
|
43
|
+
) {
|
|
44
|
+
if (
|
|
45
|
+
!this.diagnosticList.some((d) => d.model.uri.toString() === model.uri.toString())
|
|
46
|
+
) {
|
|
47
|
+
this.diagnosticList.push({
|
|
48
|
+
model,
|
|
49
|
+
markers: [marker],
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
this.diagnosticList
|
|
53
|
+
.find((d) => d.model.uri.toString() === model.uri.toString())
|
|
54
|
+
?.markers.push(marker);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
protected clearDiagnostic() {
|
|
59
|
+
this.libroService.active?.model.cells.forEach((item) => {
|
|
60
|
+
if (EditorCellView.is(item)) {
|
|
61
|
+
if (item.editor instanceof LibroE2Editor) {
|
|
62
|
+
const model = item.editor.monacoEditor?.getModel();
|
|
63
|
+
if (model) {
|
|
64
|
+
monaco.editor.setModelMarkers(model, 'libro-e2', []);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
protected displayDiagnostic() {
|
|
72
|
+
this.clearDiagnostic();
|
|
73
|
+
this.diagnosticList.forEach((d) => {
|
|
74
|
+
monaco.editor.setModelMarkers(d.model, 'libro-e2', d.markers);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async processDiagnostic() {
|
|
79
|
+
this.lspConnection.serverNotifications['textDocument/publishDiagnostics'].event(
|
|
80
|
+
(e) => {
|
|
81
|
+
this.diagnosticList = [];
|
|
82
|
+
e.diagnostics.forEach((diagnostic) => {
|
|
83
|
+
const { range } = diagnostic;
|
|
84
|
+
// the diagnostic range must be in current editor
|
|
85
|
+
const editor = this.getEditorFromLSPPosition(range);
|
|
86
|
+
if (!editor || editor.getOption('lspEnabled') !== true) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const model = editor?.monacoEditor?.getModel();
|
|
90
|
+
if (!model) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const editorStart = this.virtualDocument.transformVirtualToEditor({
|
|
95
|
+
line: range.start.line,
|
|
96
|
+
ch: range.start.character,
|
|
97
|
+
isVirtual: true,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const editorEnd = this.virtualDocument.transformVirtualToEditor({
|
|
101
|
+
line: range.end.line,
|
|
102
|
+
ch: range.end.character,
|
|
103
|
+
isVirtual: true,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (!editorStart || !editorEnd) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const markerRange = new MonacoRange(
|
|
111
|
+
editorStart.line + 1,
|
|
112
|
+
editorStart.ch,
|
|
113
|
+
editorEnd.line + 1,
|
|
114
|
+
editorEnd.ch,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const marker: monaco.editor.IMarkerData = {
|
|
118
|
+
source: diagnostic.source,
|
|
119
|
+
tags: diagnostic.tags,
|
|
120
|
+
message: diagnostic.message,
|
|
121
|
+
code: String(diagnostic.code),
|
|
122
|
+
severity: diagnostic.severity
|
|
123
|
+
? vererityMap[diagnostic.severity]
|
|
124
|
+
: monaco.MarkerSeverity.Info,
|
|
125
|
+
relatedInformation: diagnostic.relatedInformation?.map((item) => {
|
|
126
|
+
return {
|
|
127
|
+
message: item.message,
|
|
128
|
+
resource: MonacoUri.parse(item.location.uri),
|
|
129
|
+
startLineNumber: markerRange.startLineNumber,
|
|
130
|
+
startColumn: markerRange.startColumn,
|
|
131
|
+
endLineNumber: markerRange.endLineNumber,
|
|
132
|
+
endColumn: markerRange.endColumn,
|
|
133
|
+
};
|
|
134
|
+
}),
|
|
135
|
+
startLineNumber: editorStart.line + 1,
|
|
136
|
+
startColumn: editorStart.ch + 1,
|
|
137
|
+
endLineNumber: editorEnd.line + 1,
|
|
138
|
+
endColumn: editorEnd.ch + 1,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
this.addDiagnostic(model, marker);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
this.displayDiagnostic();
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type monaco from '@difizen/monaco-editor-core';
|
|
2
|
+
|
|
3
|
+
import { LangaugeFeatureProvider } from './language-feature-provider.js';
|
|
4
|
+
|
|
5
|
+
export class FormatProvider
|
|
6
|
+
extends LangaugeFeatureProvider
|
|
7
|
+
implements
|
|
8
|
+
monaco.languages.DocumentFormattingEditProvider,
|
|
9
|
+
monaco.languages.DocumentRangeFormattingEditProvider
|
|
10
|
+
{
|
|
11
|
+
displayName = 'libro-e2-format';
|
|
12
|
+
|
|
13
|
+
provideDocumentRangeFormattingEdits = async (
|
|
14
|
+
model: monaco.editor.ITextModel,
|
|
15
|
+
range: monaco.Range,
|
|
16
|
+
options: monaco.languages.FormattingOptions,
|
|
17
|
+
token: monaco.CancellationToken,
|
|
18
|
+
): Promise<monaco.languages.TextEdit[]> => {
|
|
19
|
+
return this.formatDocumentByRange(model, range, options, token);
|
|
20
|
+
};
|
|
21
|
+
provideDocumentFormattingEdits = async (
|
|
22
|
+
model: monaco.editor.ITextModel,
|
|
23
|
+
options: monaco.languages.FormattingOptions,
|
|
24
|
+
token: monaco.CancellationToken,
|
|
25
|
+
): Promise<monaco.languages.TextEdit[]> => {
|
|
26
|
+
return this.formatDocumentByRange(model, model.getFullModelRange(), options, token);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
formatDocumentByRange = async (
|
|
30
|
+
model: monaco.editor.ITextModel,
|
|
31
|
+
range: monaco.Range,
|
|
32
|
+
options: monaco.languages.FormattingOptions,
|
|
33
|
+
token: monaco.CancellationToken,
|
|
34
|
+
): Promise<monaco.languages.TextEdit[]> => {
|
|
35
|
+
const provider = await this.getProvider(model);
|
|
36
|
+
if (!provider) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { virtualDocument: doc } = provider;
|
|
41
|
+
const result = await this.lspConnection.clientRequests[
|
|
42
|
+
'textDocument/rangeFormatting'
|
|
43
|
+
].request({
|
|
44
|
+
// TODO: range transform
|
|
45
|
+
// TODO: pyright-extend supoport range format
|
|
46
|
+
range: {
|
|
47
|
+
start: {
|
|
48
|
+
line: range.startLineNumber - 1,
|
|
49
|
+
character: range.startColumn - 1,
|
|
50
|
+
},
|
|
51
|
+
end: {
|
|
52
|
+
line: range.endLineNumber - 1,
|
|
53
|
+
character: range.endColumn - 1,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
textDocument: {
|
|
57
|
+
uri: doc.documentInfo.uri,
|
|
58
|
+
},
|
|
59
|
+
options: {
|
|
60
|
+
insertSpaces: options.insertSpaces,
|
|
61
|
+
tabSize: options.tabSize,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (token.isCancellationRequested) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!result) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const edits: monaco.languages.TextEdit[] = result.map((item) => {
|
|
74
|
+
return {
|
|
75
|
+
range: {
|
|
76
|
+
startColumn: item.range.start.character + 1,
|
|
77
|
+
startLineNumber: item.range.start.line + 1,
|
|
78
|
+
endColumn: item.range.end.character + 1,
|
|
79
|
+
endLineNumber: item.range.end.line + 1,
|
|
80
|
+
},
|
|
81
|
+
text: item.newText,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return edits;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type monaco from '@difizen/monaco-editor-core';
|
|
2
|
+
import type * as lsp from 'vscode-languageserver-protocol';
|
|
3
|
+
|
|
4
|
+
import { MonacoRange } from '../../types.js';
|
|
5
|
+
|
|
6
|
+
import { LangaugeFeatureProvider } from './language-feature-provider.js';
|
|
7
|
+
|
|
8
|
+
export class HoverProvider
|
|
9
|
+
extends LangaugeFeatureProvider
|
|
10
|
+
implements monaco.languages.HoverProvider
|
|
11
|
+
{
|
|
12
|
+
provideHover = async (
|
|
13
|
+
model: monaco.editor.ITextModel,
|
|
14
|
+
position: monaco.Position,
|
|
15
|
+
token: monaco.CancellationToken,
|
|
16
|
+
): Promise<monaco.languages.Hover | undefined> => {
|
|
17
|
+
const editor = this.getEditorByModel(model);
|
|
18
|
+
if (!editor || editor.getOption('lspEnabled') !== true) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const provider = await this.getProvider(model);
|
|
22
|
+
if (!provider) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { lspConnection, editor: docEditor, virtualDocument: doc } = provider;
|
|
27
|
+
|
|
28
|
+
const virtualPos = doc.transformEditorToVirtual(docEditor, {
|
|
29
|
+
line: position.lineNumber - 1, // lsp is zero based, monaco is one based
|
|
30
|
+
ch: position.column,
|
|
31
|
+
isEditor: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (!virtualPos) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const result = await lspConnection.clientRequests['textDocument/hover'].request({
|
|
39
|
+
position: { line: virtualPos.line, character: virtualPos.ch },
|
|
40
|
+
textDocument: {
|
|
41
|
+
uri: doc.documentInfo.uri,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (!result) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const { contents, range } = result;
|
|
50
|
+
|
|
51
|
+
const resultContents = [{ value: formatContents(contents) }];
|
|
52
|
+
|
|
53
|
+
let resultRange: monaco.Range | undefined;
|
|
54
|
+
|
|
55
|
+
if (range) {
|
|
56
|
+
const editorStart = doc.transformVirtualToEditor({
|
|
57
|
+
line: range.start.line,
|
|
58
|
+
ch: range.start.character,
|
|
59
|
+
isVirtual: true,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const editorEnd = doc.transformVirtualToEditor({
|
|
63
|
+
line: range.end.line,
|
|
64
|
+
ch: range.end.character,
|
|
65
|
+
isVirtual: true,
|
|
66
|
+
});
|
|
67
|
+
if (editorStart && editorEnd) {
|
|
68
|
+
resultRange = new MonacoRange(
|
|
69
|
+
editorStart.line + 1,
|
|
70
|
+
editorStart.ch + 1,
|
|
71
|
+
editorEnd.line + 1,
|
|
72
|
+
editorEnd.ch + 1,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (token.isCancellationRequested) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
contents: resultContents,
|
|
83
|
+
range: resultRange,
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function formatContents(
|
|
89
|
+
contents: lsp.MarkupContent | lsp.MarkedString | lsp.MarkedString[],
|
|
90
|
+
): string {
|
|
91
|
+
if (Array.isArray(contents)) {
|
|
92
|
+
return contents.map((c) => formatContents(c) + '\n\n').join('');
|
|
93
|
+
} else if (typeof contents === 'string') {
|
|
94
|
+
return contents;
|
|
95
|
+
} else {
|
|
96
|
+
return contents.value;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { LibroService } from '@difizen/libro-core';
|
|
2
|
+
import { EditorCellView } from '@difizen/libro-core';
|
|
3
|
+
import type { LSPProviderResult } from '@difizen/libro-lsp';
|
|
4
|
+
import type { LSPConnection, VirtualDocument } from '@difizen/libro-lsp';
|
|
5
|
+
import type monaco from '@difizen/monaco-editor-core';
|
|
6
|
+
import type * as lsp from 'vscode-languageserver-protocol';
|
|
7
|
+
|
|
8
|
+
import { LibroE2Editor } from '../../libro-e2-editor.js';
|
|
9
|
+
|
|
10
|
+
export class LangaugeFeatureProvider {
|
|
11
|
+
protected libroService: LibroService;
|
|
12
|
+
protected lspProvider?: LSPProviderResult;
|
|
13
|
+
protected lspConnection: LSPConnection;
|
|
14
|
+
virtualDocument: VirtualDocument;
|
|
15
|
+
constructor(
|
|
16
|
+
libroService: LibroService,
|
|
17
|
+
lspConnection: LSPConnection,
|
|
18
|
+
virtualDocument: VirtualDocument,
|
|
19
|
+
) {
|
|
20
|
+
this.libroService = libroService;
|
|
21
|
+
this.lspConnection = lspConnection;
|
|
22
|
+
this.virtualDocument = virtualDocument;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
protected getEditorByModel(model: monaco.editor.ITextModel) {
|
|
26
|
+
const cells = this.libroService.active?.model.cells;
|
|
27
|
+
if (!cells) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const cell = cells.find((item) => {
|
|
31
|
+
const editorUuid = model.uri.path.split('.')[0];
|
|
32
|
+
if (!EditorCellView.is(item)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const e2editor = item.editor;
|
|
36
|
+
if (!(e2editor instanceof LibroE2Editor)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return editorUuid === e2editor.uuid;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return (cell as EditorCellView).editor as LibroE2Editor | undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected getEditorFromLSPPosition(range: lsp.Range) {
|
|
46
|
+
const currentEditor = this.virtualDocument.getEditorAtVirtualLine({
|
|
47
|
+
line: range.start.line,
|
|
48
|
+
ch: range.start.character,
|
|
49
|
+
isVirtual: true,
|
|
50
|
+
});
|
|
51
|
+
const editor = currentEditor.getEditor();
|
|
52
|
+
if (editor instanceof LibroE2Editor) {
|
|
53
|
+
return editor;
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
protected async getProvider(model: monaco.editor.ITextModel) {
|
|
59
|
+
const editor = this.getEditorByModel(model);
|
|
60
|
+
|
|
61
|
+
if (!editor) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const provider = await editor.lspProvider?.();
|
|
66
|
+
this.lspProvider = provider;
|
|
67
|
+
return provider;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EditorHandlerContribution,
|
|
3
|
+
LanguageOptionsRegistry,
|
|
4
|
+
} from '@difizen/libro-cofine-editor-core';
|
|
5
|
+
import { LibroService } from '@difizen/libro-core';
|
|
6
|
+
import type { LSPConnection } from '@difizen/libro-lsp';
|
|
7
|
+
import { ILSPDocumentConnectionManager } from '@difizen/libro-lsp';
|
|
8
|
+
import { DisposableCollection, inject, singleton } from '@difizen/mana-app';
|
|
9
|
+
import * as monaco from '@difizen/monaco-editor-core';
|
|
10
|
+
|
|
11
|
+
import { LibroE2URIScheme } from '../../libro-e2-editor.js';
|
|
12
|
+
|
|
13
|
+
import { CompletionProvider } from './completion-provider.js';
|
|
14
|
+
import { DiagnosticProvider } from './diagnostic-provider.js';
|
|
15
|
+
import { HoverProvider } from './hover-provider.js';
|
|
16
|
+
import { SignatureHelpProvider } from './signature-help-provider.js';
|
|
17
|
+
|
|
18
|
+
@singleton({
|
|
19
|
+
contrib: [EditorHandlerContribution],
|
|
20
|
+
})
|
|
21
|
+
export class LSPContribution implements EditorHandlerContribution {
|
|
22
|
+
@inject(LanguageOptionsRegistry)
|
|
23
|
+
protected readonly optionsResgistry: LanguageOptionsRegistry;
|
|
24
|
+
|
|
25
|
+
@inject(LibroService) protected readonly libroService: LibroService;
|
|
26
|
+
|
|
27
|
+
@inject(ILSPDocumentConnectionManager)
|
|
28
|
+
protected readonly lspDocumentConnectionManager: ILSPDocumentConnectionManager;
|
|
29
|
+
|
|
30
|
+
protected toDispose = new DisposableCollection();
|
|
31
|
+
|
|
32
|
+
protected lspLangs = ['python'];
|
|
33
|
+
|
|
34
|
+
beforeCreate() {
|
|
35
|
+
//
|
|
36
|
+
}
|
|
37
|
+
afterCreate(editor: any) {
|
|
38
|
+
this.registerLSPFeature(editor as monaco.editor.IStandaloneCodeEditor);
|
|
39
|
+
}
|
|
40
|
+
canHandle(language: string) {
|
|
41
|
+
return this.lspLangs.includes(language);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getLanguageSelector(
|
|
45
|
+
model: monaco.editor.ITextModel,
|
|
46
|
+
): monaco.languages.LanguageFilter {
|
|
47
|
+
return {
|
|
48
|
+
scheme: LibroE2URIScheme,
|
|
49
|
+
pattern: model.uri.path,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async getVirtualDocument() {
|
|
54
|
+
const libroView = this.libroService.active;
|
|
55
|
+
if (!libroView) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
await this.lspDocumentConnectionManager.ready;
|
|
59
|
+
const adapter = this.lspDocumentConnectionManager.adapters.get(libroView.model.id);
|
|
60
|
+
if (!adapter) {
|
|
61
|
+
throw new Error('no adapter');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await adapter.ready;
|
|
65
|
+
|
|
66
|
+
// Get the associated virtual document of the opened document
|
|
67
|
+
const virtualDocument = adapter.virtualDocument;
|
|
68
|
+
return virtualDocument;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async getLSPConnection() {
|
|
72
|
+
const virtualDocument = await this.getVirtualDocument();
|
|
73
|
+
if (!virtualDocument) {
|
|
74
|
+
throw new Error('no virtualDocument');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Get the LSP connection of the virtual document.
|
|
78
|
+
const lspConnection = this.lspDocumentConnectionManager.connections.get(
|
|
79
|
+
virtualDocument.uri,
|
|
80
|
+
) as LSPConnection;
|
|
81
|
+
|
|
82
|
+
return lspConnection;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
registerLSPFeature(editor: monaco.editor.IStandaloneCodeEditor) {
|
|
86
|
+
const model = editor.getModel();
|
|
87
|
+
if (!model) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Promise.all([this.getVirtualDocument(), this.getLSPConnection()])
|
|
92
|
+
.then(([virtualDocument, lspConnection]) => {
|
|
93
|
+
if (!lspConnection || !virtualDocument) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this.toDispose.push(
|
|
97
|
+
monaco.languages.registerCompletionItemProvider(
|
|
98
|
+
this.getLanguageSelector(model),
|
|
99
|
+
new CompletionProvider(this.libroService, lspConnection, virtualDocument),
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
this.toDispose.push(
|
|
104
|
+
monaco.languages.registerHoverProvider(
|
|
105
|
+
this.getLanguageSelector(model),
|
|
106
|
+
new HoverProvider(this.libroService, lspConnection, virtualDocument),
|
|
107
|
+
),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
new DiagnosticProvider(this.libroService, lspConnection, virtualDocument);
|
|
111
|
+
|
|
112
|
+
this.toDispose.push(
|
|
113
|
+
monaco.languages.registerSignatureHelpProvider(
|
|
114
|
+
this.getLanguageSelector(model),
|
|
115
|
+
new SignatureHelpProvider(
|
|
116
|
+
this.libroService,
|
|
117
|
+
lspConnection,
|
|
118
|
+
virtualDocument,
|
|
119
|
+
),
|
|
120
|
+
),
|
|
121
|
+
);
|
|
122
|
+
// const formatProvider = new FormatProvider(
|
|
123
|
+
// this.libroService,
|
|
124
|
+
// lspConnection,
|
|
125
|
+
// virtualDocument,
|
|
126
|
+
// );
|
|
127
|
+
// monaco.languages.registerDocumentFormattingEditProvider(
|
|
128
|
+
// this.getLanguageSelector(model),
|
|
129
|
+
// formatProvider,
|
|
130
|
+
// );
|
|
131
|
+
// monaco.languages.registerDocumentRangeFormattingEditProvider(
|
|
132
|
+
// this.getLanguageSelector(model),
|
|
133
|
+
// formatProvider,
|
|
134
|
+
// );
|
|
135
|
+
return;
|
|
136
|
+
})
|
|
137
|
+
.catch(console.error);
|
|
138
|
+
|
|
139
|
+
// // SignatureHelp
|
|
140
|
+
// monaco.languages.registerSignatureHelpProvider(id, new SignatureHelpProvider(this._worker));
|
|
141
|
+
|
|
142
|
+
// // 定义跳转;
|
|
143
|
+
// monaco.languages.registerDefinitionProvider(id, new DefinitionAdapter(this._worker));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
protected isDisposed = false;
|
|
147
|
+
get disposed() {
|
|
148
|
+
return this.isDisposed;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
beforeDestory() {
|
|
152
|
+
this.toDispose.dispose();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
dispose() {
|
|
156
|
+
this.toDispose.dispose();
|
|
157
|
+
this.isDisposed = false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import type monaco from '@difizen/monaco-editor-core';
|
|
3
|
+
|
|
4
|
+
import { LangaugeFeatureProvider } from './language-feature-provider.js';
|
|
5
|
+
|
|
6
|
+
export class SemanticHighlightProvider
|
|
7
|
+
extends LangaugeFeatureProvider
|
|
8
|
+
implements monaco.languages.DocumentSemanticTokensProvider
|
|
9
|
+
{
|
|
10
|
+
onDidChange?: monaco.IEvent<void> | undefined;
|
|
11
|
+
getLegend(): monaco.languages.SemanticTokensLegend {
|
|
12
|
+
throw new Error('Method not implemented.');
|
|
13
|
+
}
|
|
14
|
+
provideDocumentSemanticTokens(
|
|
15
|
+
model: monaco.editor.ITextModel,
|
|
16
|
+
lastResultId: string | null,
|
|
17
|
+
token: monaco.CancellationToken,
|
|
18
|
+
): monaco.languages.ProviderResult<
|
|
19
|
+
monaco.languages.SemanticTokens | monaco.languages.SemanticTokensEdits
|
|
20
|
+
> {
|
|
21
|
+
throw new Error('Method not implemented.');
|
|
22
|
+
}
|
|
23
|
+
releaseDocumentSemanticTokens(resultId: string | undefined): void {
|
|
24
|
+
throw new Error('Method not implemented.');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type monaco from '@difizen/monaco-editor-core';
|
|
2
|
+
|
|
3
|
+
import { LangaugeFeatureProvider } from './language-feature-provider.js';
|
|
4
|
+
|
|
5
|
+
export class SignatureHelpProvider
|
|
6
|
+
extends LangaugeFeatureProvider
|
|
7
|
+
implements monaco.languages.SignatureHelpProvider
|
|
8
|
+
{
|
|
9
|
+
signatureHelpTriggerCharacters: ['(', ',', ')'];
|
|
10
|
+
signatureHelpRetriggerCharacters?: readonly string[] | undefined;
|
|
11
|
+
provideSignatureHelp = async (
|
|
12
|
+
model: monaco.editor.ITextModel,
|
|
13
|
+
position: monaco.Position,
|
|
14
|
+
token: monaco.CancellationToken,
|
|
15
|
+
context: monaco.languages.SignatureHelpContext,
|
|
16
|
+
): Promise<monaco.languages.SignatureHelpResult | undefined> => {
|
|
17
|
+
const editor = this.getEditorByModel(model);
|
|
18
|
+
if (!editor || editor.getOption('lspEnabled') !== true) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const provider = await this.getProvider(model);
|
|
22
|
+
if (!provider) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { lspConnection, editor: docEditor, virtualDocument: doc } = provider;
|
|
27
|
+
|
|
28
|
+
const virtualPos = doc.transformEditorToVirtual(docEditor, {
|
|
29
|
+
line: position.lineNumber - 1, // lsp is zero based, monaco is one based
|
|
30
|
+
ch: position.column - 1,
|
|
31
|
+
isEditor: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (!virtualPos) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const sigInfo = await lspConnection.clientRequests[
|
|
39
|
+
'textDocument/signatureHelp'
|
|
40
|
+
].request({
|
|
41
|
+
position: { line: virtualPos.line, character: virtualPos.ch },
|
|
42
|
+
textDocument: {
|
|
43
|
+
uri: doc.documentInfo.uri,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
value: {
|
|
49
|
+
signatures: sigInfo.signatures.map((sig: any) => {
|
|
50
|
+
return {
|
|
51
|
+
label: sig.label,
|
|
52
|
+
documentation: sig.documentation,
|
|
53
|
+
parameters: sig.parameters ?? [],
|
|
54
|
+
activeParameter: sig.activeParameter,
|
|
55
|
+
};
|
|
56
|
+
}),
|
|
57
|
+
activeSignature: sigInfo.activeSignature ?? 0,
|
|
58
|
+
activeParameter: sigInfo.activeParameter ?? 0,
|
|
59
|
+
},
|
|
60
|
+
dispose: () => {
|
|
61
|
+
//
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}
|