Skip to content

Commit 843d595

Browse files
committed
Always run the worksheet after all changes have been applied
In 23785e6, we moved worksheet.run() from didSave to willSave since didSave is not called when the document is not dirty, unfortunately this gives the wrong behavior when the document _is_ dirty: it means we're going to send a run worksheet request to the server before the server has seen all the changes to the document, in particular with multi-line output this means that the server will see the output with the added empty lines, which means the line numbers in worksheet/publishOutput will be wrong. To avoid this issue we now run the worksheet either on willSave or didSave depending on whether the document is dirty or not. To reproduce the issue, you can create a worksheet with: ``` val x = """ """ "hi" ``` in it, then save the document multiple times.
1 parent 3f28c07 commit 843d595

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

vscode-dotty/src/worksheet.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ export const worksheetRunKey = "dotty.worksheet.run"
2323
*/
2424
export const worksheetCancelKey = "dotty.worksheet.cancel"
2525

26+
/**
27+
* If true, the setting for running the worksheet on save is enabled.
28+
*/
29+
function runWorksheetOnSave(): boolean {
30+
return vscode.workspace.getConfiguration("dotty").get("runWorksheetOnSave") as boolean
31+
}
32+
2633
/**
2734
* A wrapper around the information that VSCode needs to display text decorations.
2835
*
@@ -338,11 +345,25 @@ export class WorksheetProvider implements Disposable {
338345
codeLensProvider,
339346
vscode.languages.registerCodeLensProvider(documentSelector, codeLensProvider),
340347
vscode.workspace.onWillSaveTextDocument(event => {
341-
const runWorksheetOnSave = vscode.workspace.getConfiguration("dotty").get("runWorksheetOnSave")
342-
const worksheet = this.worksheetFor(event.document)
348+
const document = event.document
349+
const worksheet = this.worksheetFor(document)
343350
if (worksheet) {
344351
event.waitUntil(Promise.resolve(worksheet.prepareRun()))
345-
if (runWorksheetOnSave) worksheet.run()
352+
// If the document is not dirty, then `onDidSaveTextDocument` will not
353+
// be called so we need to run the worksheet now.
354+
// On the other hand, if the document _is_ dirty, we should _not_ run
355+
// the worksheet now because the server state will not be synchronized
356+
// with the client state, instead we let `onDidSaveTextDocument`
357+
// handle it.
358+
if (runWorksheetOnSave() && !document.isDirty) {
359+
worksheet.run()
360+
}
361+
}
362+
}),
363+
vscode.workspace.onDidSaveTextDocument(document => {
364+
const worksheet = this.worksheetFor(document)
365+
if (worksheet && runWorksheetOnSave()) {
366+
worksheet.run()
346367
}
347368
}),
348369
vscode.workspace.onDidCloseTextDocument(document => {

0 commit comments

Comments
 (0)