1
1
import * as vscode from 'vscode'
2
+ import { TextEdit } from 'vscode'
2
3
3
4
import {
4
- asWorksheetRunParams , WorksheetRunRequest , WorksheetRunParams ,
5
+ asWorksheetRunParams , WorksheetRunRequest , WorksheetRunParams , WorksheetRunResult ,
5
6
WorksheetPublishOutputParams , WorksheetPublishOutputNotification
6
7
} from './protocol'
7
8
import { BaseLanguageClient , DocumentSelector } from 'vscode-languageclient'
@@ -41,23 +42,35 @@ class Worksheet {
41
42
42
43
/**
43
44
* Reset the "worksheet state" (margin and number of inserted lines), and
44
- * removes redundant blank lines that have been inserted by a previous
45
- * run.
45
+ * return an array of TextEdit that remove the redundant blank lines that have
46
+ * been inserted by a previous run.
46
47
*/
47
- prepareForRunning ( ) : void {
48
- this . removeRedundantBlankLines ( ) . then ( _ => this . reset ( ) )
48
+ prepareRun ( ) : TextEdit [ ] {
49
+ const edits = this . removeRedundantBlankLinesEdits ( )
50
+ this . reset ( )
51
+ return edits
49
52
}
50
53
51
54
/**
52
55
* Run the worksheet in `document`, display a progress bar during the run.
53
56
*/
54
- run ( ) : Thenable < { } > {
55
- return vscode . window . withProgress ( {
56
- location : vscode . ProgressLocation . Notification ,
57
- title : "Run the worksheet" ,
58
- cancellable : true
59
- } , ( _ , token ) => {
60
- return this . client . sendRequest ( WorksheetRunRequest . type , asWorksheetRunParams ( this . document ) , token )
57
+ run ( ) : Promise < WorksheetRunResult > {
58
+ return new Promise ( ( resolve , reject ) => {
59
+ const textEdits = this . prepareRun ( )
60
+ const edit = new vscode . WorkspaceEdit ( )
61
+ edit . set ( this . document . uri , textEdits )
62
+ vscode . workspace . applyEdit ( edit ) . then ( editSucceeded => {
63
+ if ( editSucceeded ) {
64
+ return resolve ( vscode . window . withProgress ( {
65
+ location : vscode . ProgressLocation . Notification ,
66
+ title : "Run the worksheet" ,
67
+ cancellable : true
68
+ } , ( _ , token ) => this . client . sendRequest (
69
+ WorksheetRunRequest . type , asWorksheetRunParams ( this . document ) , token
70
+ ) ) )
71
+ } else
72
+ reject ( )
73
+ } )
61
74
} )
62
75
}
63
76
@@ -143,16 +156,16 @@ class Worksheet {
143
156
}
144
157
145
158
/**
146
- * Remove the repeated blank lines in the source.
159
+ * TextEdits to remove the repeated blank lines in the source.
147
160
*
148
161
* Running a worksheet can insert new lines in the worksheet so that the
149
162
* output of a line fits below the line. Before a run, we remove blank
150
163
* lines in the worksheet to keep its length under control.
151
164
*
152
165
* @param worksheet The worksheet where blank lines must be removed.
153
- * @return A `Thenable` removing the blank lines upon completion .
166
+ * @return An array of `TextEdit` that remove the blank lines.
154
167
*/
155
- private removeRedundantBlankLines ( ) {
168
+ private removeRedundantBlankLinesEdits ( ) : TextEdit [ ] {
156
169
157
170
const document = this . document
158
171
const lineCount = document . lineCount
@@ -188,13 +201,7 @@ class Worksheet {
188
201
addRange ( )
189
202
}
190
203
191
- return rangesToRemove . reverse ( ) . reduce ( ( chain : Thenable < boolean > , range ) => {
192
- return chain . then ( _ => {
193
- const edit = new vscode . WorkspaceEdit ( )
194
- edit . delete ( document . uri , range )
195
- return vscode . workspace . applyEdit ( edit )
196
- } )
197
- } , Promise . resolve ( true ) )
204
+ return rangesToRemove . reverse ( ) . map ( range => vscode . TextEdit . delete ( range ) )
198
205
}
199
206
200
207
private hasDecoration ( line : number ) : boolean {
@@ -213,14 +220,14 @@ export class WorksheetProvider implements Disposable {
213
220
vscode . workspace . onWillSaveTextDocument ( event => {
214
221
const worksheet = this . worksheetFor ( event . document )
215
222
if ( worksheet ) {
216
- // Block file saving until the worksheet is ready to be run.
217
- worksheet . prepareForRunning ( )
223
+ event . waitUntil ( Promise . resolve ( worksheet . prepareRun ( ) ) )
218
224
}
219
225
} ) ,
220
226
vscode . workspace . onDidSaveTextDocument ( document => {
227
+ const runWorksheetOnSave = vscode . workspace . getConfiguration ( "dotty" ) . get ( "runWorksheetOnSave" )
221
228
const worksheet = this . worksheetFor ( document )
222
- if ( worksheet ) {
223
- return worksheet . run ( )
229
+ if ( runWorksheetOnSave && worksheet ) {
230
+ worksheet . run ( )
224
231
}
225
232
} ) ,
226
233
vscode . workspace . onDidCloseTextDocument ( document => {
@@ -264,28 +271,13 @@ export class WorksheetProvider implements Disposable {
264
271
265
272
/**
266
273
* The VSCode command executed when the user select `Run worksheet`.
267
- *
268
- * We check whether the buffer is dirty, and if it is, we save it. Running the worksheet will then be
269
- * triggered by file save.
270
- * If the buffer is clean, we do the necessary preparation for worksheet (compute margin,
271
- * remove blank lines, etc.) and check if the buffer has been changed by that. If it is, we save
272
- * and the run will be triggered by file save.
273
- * If the buffer is still clean, call `Worksheet#run`.
274
274
*/
275
275
private runWorksheetCommand ( ) {
276
276
const editor = vscode . window . activeTextEditor
277
277
if ( editor ) {
278
- const document = editor . document
279
- const worksheet = this . worksheetFor ( document )
278
+ const worksheet = this . worksheetFor ( editor . document )
280
279
if ( worksheet ) {
281
- if ( document . isDirty ) document . save ( ) // This will trigger running the worksheet
282
- else {
283
- worksheet . prepareForRunning ( )
284
- if ( document . isDirty ) document . save ( ) // This will trigger running the worksheet
285
- else {
286
- worksheet . run ( )
287
- }
288
- }
280
+ worksheet . run ( )
289
281
}
290
282
}
291
283
}
0 commit comments