-
Notifications
You must be signed in to change notification settings - Fork 0
/
extension.ts
85 lines (76 loc) · 2.8 KB
/
extension.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Attention that this import of vscode is provided by vscode extension host.
// There's no real code when running in node,
// that all test inside current file will fail because of this import.
// So don't test directly inside this file.
import {CompletionList, ExtensionContext, commands, workspace} from "vscode"
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind,
} from "vscode-languageclient/node"
import {detectDocCodeLanguage, resolveSuffix} from "./language"
/**
* The language service client is handled as a global variable
* in order to be canceled safely when the extension deactivated.
*/
let client: LanguageClient | undefined
export function activate(context: ExtensionContext) {
/**
* Handle all registered virtual documents:
* - key: virtual document uri.
* - value: content string of virtual document.
*/
const virtualDocumentHandler = new Map<string, string>()
workspace.registerTextDocumentContentProvider("doc-code", {
provideTextDocumentContent: function (uri) {
return virtualDocumentHandler.get(uri.toString())
},
})
// Introduce the server code into vscode server host.
const serverOptions: ServerOptions = {
command: "",
// module: context.asAbsolutePath("middleware.js"),
transport: TransportKind.ipc,
}
// Register the middleware to hijack language service and
// create virtual documents for embedded code in docs
// for all supported file types (language id).
const clientOptions: LanguageClientOptions = {
documentSelector: [{scheme: "file", language: "typescript"}],
middleware: {
/**
* Parse embedded code area, and if it is,
* register them inside {@link virtualDocumentHandler}.
* Then it will call the build-in command to provide completion
* using default language service of current vscode environment.
*/
async provideCompletionItem(document, position, context, token, next) {
const lang = detectDocCodeLanguage(
document.languageId,
document.getText(),
document.offsetAt(position),
)
if (!lang) return next(document, position, context, token)
const virtualDocumentURI =
"doc-code:" +
encodeURIComponent(document.uri.toString(true)) +
resolveSuffix(lang.languageId)
virtualDocumentHandler.set(virtualDocumentURI, lang.content)
return await commands.executeCommand<CompletionList>(
"vscode.executeCompletionItemProvider",
virtualDocumentURI,
position,
context.triggerCharacter,
token,
)
},
},
}
// Launch the client with configured options.
client = new LanguageClient("doc-code", serverOptions, clientOptions)
client?.start()
}
export function deactivate() {
return client?.stop()
}