Skip to content

Commit 0f465e5

Browse files
committed
Refactor worksheet support, make it a dynamic feature
- Only enable worksheet features on the client if the server supports them using the LSP support for dynamic feature registration. - Replace the global functions and state in worksheet.ts by a WorksheetProvider class, move some of the global functions specific to one worksheet into Worksheet
1 parent 214d1fe commit 0f465e5

File tree

5 files changed

+324
-281
lines changed

5 files changed

+324
-281
lines changed

language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ class DottyLanguageServer extends LanguageServer
153153
rootUri = params.getRootUri
154154
assert(rootUri != null)
155155

156-
val c = new ServerCapabilities
156+
class DottyServerCapabilities(val worksheetRunProvider: Boolean = true) extends lsp4j.ServerCapabilities
157+
158+
val c = new DottyServerCapabilities
157159
c.setTextDocumentSync(TextDocumentSyncKind.Full)
158160
c.setDocumentHighlightProvider(true)
159161
c.setDocumentSymbolProvider(true)

vscode-dotty/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@
4343
"commands": [
4444
{
4545
"command": "worksheet.evaluate",
46-
"title": "Run worksheet"
46+
"title": "Run worksheet",
47+
"category": "Scala"
4748
},
4849
{
4950
"command": "worksheet.cancel",
50-
"title": "Cancel worksheet evaluation"
51+
"title": "Cancel worksheet evaluation",
52+
"category": "Scala"
5153
}
5254
],
5355
"configurationDefaults": {

vscode-dotty/src/extension.ts

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import { LanguageClient, LanguageClientOptions, RevealOutputChannelOn,
1313
import { enableOldServerWorkaround } from './compat'
1414
import { WorksheetPublishOutputNotification } from './protocol'
1515
import * as worksheet from './worksheet'
16+
import * as features from './features'
1617

18+
export let client: LanguageClient
1719

1820
let extensionContext: ExtensionContext
1921
let outputChannel: vscode.OutputChannel
20-
export let client: LanguageClient
2122

2223
export function activate(context: ExtensionContext) {
2324
extensionContext = context
@@ -31,18 +32,6 @@ export function activate(context: ExtensionContext) {
3132
const languageServerDefaultConfigFile = path.join(extensionContext.extensionPath, './out/default-dotty-ide-config')
3233
const coursierPath = path.join(extensionContext.extensionPath, './out/coursier');
3334

34-
vscode.workspace.onWillSaveTextDocument(worksheet.prepareWorksheet)
35-
vscode.workspace.onDidSaveTextDocument(document => {
36-
if (worksheet.isWorksheet(document)) {
37-
worksheet.evaluateWorksheet(document)
38-
}
39-
})
40-
vscode.workspace.onDidCloseTextDocument(document => {
41-
if (worksheet.isWorksheet(document)) {
42-
worksheet.removeWorksheet(document)
43-
}
44-
})
45-
4635
if (process.env['DLS_DEV_MODE']) {
4736
const portFile = `${vscode.workspace.rootPath}/.dotty-ide-dev-port`
4837
fs.readFile(portFile, (err, port) => {
@@ -203,20 +192,12 @@ function run(serverOptions: ServerOptions, isOldServer: boolean) {
203192
}
204193

205194
client = new LanguageClient("dotty", "Dotty", serverOptions, clientOptions)
195+
client.registerFeature(new features.WorksheetExecFeature(client))
196+
206197
if (isOldServer)
207198
enableOldServerWorkaround(client)
208199

209-
client.onReady().then(() => {
210-
client.onNotification(WorksheetPublishOutputNotification.type, params => {
211-
worksheet.handleMessage(params)
212-
})
213-
})
214-
215-
vscode.commands.registerCommand(worksheet.worksheetEvaluateKey, () => {
216-
worksheet.evaluateWorksheetCommand()
217-
})
218-
219200
// Push the disposable to the context's subscriptions so that the
220201
// client can be deactivated on extension deactivation
221-
extensionContext.subscriptions.push(client.start());
202+
extensionContext.subscriptions.push(client.start())
222203
}

vscode-dotty/src/features.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as vscode from 'vscode'
2+
import {
3+
BaseLanguageClient, ClientCapabilities, DynamicFeature, ServerCapabilities,
4+
TextDocumentFeature, TextDocumentRegistrationOptions,
5+
} from 'vscode-languageclient'
6+
import { generateUuid } from 'vscode-languageclient/lib/utils/uuid'
7+
import { DocumentSelector } from 'vscode-languageserver-protocol'
8+
import { Disposable } from 'vscode-jsonrpc'
9+
10+
import { WorksheetExecRequest } from './protocol'
11+
import { WorksheetProvider } from './worksheet'
12+
13+
// Remove this if
14+
// https://github.com/Microsoft/vscode-languageserver-node/issues/423 is fixed.
15+
function ensure<T, K extends keyof T>(target: T, key: K): T[K] {
16+
if (target[key] === void 0) {
17+
target[key] = {} as any;
18+
}
19+
return target[key];
20+
}
21+
22+
export interface WorksheetClientCapabilities {
23+
worksheet?: {
24+
exec?: {
25+
dynamicRegistration?: boolean
26+
}
27+
}
28+
}
29+
30+
export interface WorksheetServerCapabilities {
31+
/**
32+
* The server provides support for running worksheets.
33+
*/
34+
worksheetRunProvider?: boolean
35+
}
36+
37+
export class WorksheetExecFeature extends TextDocumentFeature<TextDocumentRegistrationOptions> {
38+
constructor(client: BaseLanguageClient) {
39+
super(client, WorksheetExecRequest.type)
40+
}
41+
42+
public fillClientCapabilities(capabilities: ClientCapabilities & WorksheetClientCapabilities): void {
43+
ensure(ensure(capabilities, "worksheet")!, "exec")!.dynamicRegistration = true
44+
}
45+
46+
public initialize(capabilities: ServerCapabilities & WorksheetServerCapabilities, documentSelector: DocumentSelector): void {
47+
if (!capabilities.worksheetRunProvider) {
48+
return
49+
}
50+
51+
const selector: DocumentSelector = documentSelector || [ { language: 'scala', pattern: '**/*.sc' } ]
52+
this.register(this.messages, {
53+
id: generateUuid(),
54+
registerOptions: { documentSelector: selector }
55+
})
56+
}
57+
58+
protected registerLanguageProvider(options: TextDocumentRegistrationOptions): Disposable {
59+
let client = this._client
60+
return new WorksheetProvider(client, options.documentSelector!)
61+
}
62+
}

0 commit comments

Comments
 (0)