@@ -2,19 +2,18 @@ import * as vscode from 'vscode';
2
2
import net = require( 'net' ) ;
3
3
import { spawn , ChildProcess } from 'child_process' ;
4
4
import { dirname } from 'path' ;
5
- import * as fs from 'fs' ;
6
5
7
6
interface RSessionRequest {
8
7
id : number ;
9
8
uri : string ;
10
9
type : 'eval' | 'cancel' ;
11
- args : any ;
10
+ expr ? : any ;
12
11
}
13
12
14
13
interface RSessionResponse {
15
14
id : number ;
16
15
uri : string ;
17
- type : 'text' | 'plot' | 'viewer' | 'browser' | 'error' | 'cancel' ;
16
+ type : 'text' | 'plot' | 'viewer' | 'browser' | 'error' ;
18
17
result : string ;
19
18
}
20
19
@@ -32,63 +31,13 @@ class RKernel {
32
31
this . doc = doc ;
33
32
}
34
33
35
- private request ( obj : any ) {
34
+ private request ( request : RSessionRequest ) {
36
35
if ( this . socket ) {
37
- const json = JSON . stringify ( obj ) ;
36
+ const json = JSON . stringify ( request ) ;
38
37
this . socket . write ( `Content-Length: ${ json . length } \n${ json } ` ) ;
39
38
}
40
39
}
41
40
42
- private async handleResponse ( response : RSessionResponse ) {
43
- const cell = this . doc . cells . find ( ( cell ) => cell . metadata . executionOrder == response . id ) ;
44
- if ( cell ) {
45
- cell . metadata . runState = vscode . NotebookCellRunState . Success ;
46
- cell . metadata . lastRunDuration = + new Date ( ) - cell . metadata . runStartTime ;
47
-
48
- console . log ( `uri: ${ cell . uri } , response.type: ${ response . type } , response.result: ${ response . result } ` ) ;
49
- switch ( response . type ) {
50
- case 'text' :
51
- cell . outputs = [ {
52
- outputKind : vscode . CellOutputKind . Text ,
53
- text : response . result ,
54
- } ] ;
55
- break ;
56
- case 'plot' :
57
- cell . outputs = [ {
58
- outputKind : vscode . CellOutputKind . Rich ,
59
- data : {
60
- 'image/svg+xml' : ( await vscode . workspace . fs . readFile ( vscode . Uri . parse ( response . result ) ) ) . toString ( ) ,
61
- } ,
62
- } ] ;
63
- break ;
64
- case 'viewer' :
65
- cell . outputs = [ {
66
- outputKind : vscode . CellOutputKind . Rich ,
67
- data : {
68
- 'application/json' : response . result ,
69
- } ,
70
- } ] ;
71
- break ;
72
- case 'browser' :
73
- cell . outputs = [ {
74
- outputKind : vscode . CellOutputKind . Rich ,
75
- data : {
76
- 'application/json' : response . result ,
77
- } ,
78
- } ] ;
79
- break ;
80
- case 'error' :
81
- cell . outputs = [ {
82
- outputKind : vscode . CellOutputKind . Error ,
83
- evalue : response . result ,
84
- ename : '' ,
85
- traceback : [ ] ,
86
- } ] ;
87
- break ;
88
- }
89
- }
90
- }
91
-
92
41
public async start ( ) {
93
42
if ( this . process ) {
94
43
return ;
@@ -103,6 +52,58 @@ class RKernel {
103
52
this . socket = socket ;
104
53
resolve ( undefined ) ;
105
54
55
+ socket . on ( 'data' , async ( data ) => {
56
+ const response : RSessionResponse = JSON . parse ( data . toString ( ) ) ;
57
+ const cell = this . doc . cells . find ( cell => cell . metadata . executionOrder === response . id ) ;
58
+ if ( cell ) {
59
+ cell . metadata . runState = vscode . NotebookCellRunState . Success ;
60
+ cell . metadata . lastRunDuration = + new Date ( ) - cell . metadata . runStartTime ;
61
+
62
+ console . log ( `id: ${ response . id } , uri: ${ response . uri } , type: ${ response . type } , result: ${ response . result } ` ) ;
63
+ switch ( response . type ) {
64
+ case 'text' :
65
+ cell . outputs = [ {
66
+ outputKind : vscode . CellOutputKind . Text ,
67
+ text : response . result ,
68
+ } ] ;
69
+ break ;
70
+ case 'plot' :
71
+ cell . outputs = [ {
72
+ outputKind : vscode . CellOutputKind . Rich ,
73
+ data : {
74
+ 'image/svg+xml' : ( await vscode . workspace . fs . readFile ( vscode . Uri . parse ( response . result ) ) ) . toString ( ) ,
75
+ } ,
76
+ } ] ;
77
+ break ;
78
+ case 'viewer' :
79
+ cell . outputs = [ {
80
+ outputKind : vscode . CellOutputKind . Rich ,
81
+ data : {
82
+ 'application/json' : response . result ,
83
+ } ,
84
+ } ] ;
85
+ break ;
86
+ case 'browser' :
87
+ cell . outputs = [ {
88
+ outputKind : vscode . CellOutputKind . Rich ,
89
+ data : {
90
+ 'application/json' : response . result ,
91
+ } ,
92
+ } ] ;
93
+ break ;
94
+ case 'error' :
95
+ cell . metadata . runState = vscode . NotebookCellRunState . Error ;
96
+ cell . outputs = [ {
97
+ outputKind : vscode . CellOutputKind . Error ,
98
+ evalue : response . result ,
99
+ ename : '' ,
100
+ traceback : [ ] ,
101
+ } ] ;
102
+ break ;
103
+ }
104
+ }
105
+ } ) ;
106
+
106
107
socket . on ( 'end' , ( ) => {
107
108
console . log ( 'socket disconnected' ) ;
108
109
this . socket = undefined ;
@@ -125,6 +126,7 @@ class RKernel {
125
126
} ) ;
126
127
childProcess . on ( 'exit' , ( code , signal ) => {
127
128
console . log ( `R exited with code ${ code } ` ) ;
129
+ reject ( undefined ) ;
128
130
} ) ;
129
131
this . process = childProcess ;
130
132
return childProcess ;
@@ -144,7 +146,7 @@ class RKernel {
144
146
await this . start ( ) ;
145
147
}
146
148
147
- public async eval ( cell : vscode . NotebookCell ) : Promise < void > {
149
+ public eval ( cell : vscode . NotebookCell ) {
148
150
if ( this . socket ) {
149
151
this . request ( {
150
152
id : cell . metadata . executionOrder ,
@@ -155,13 +157,13 @@ class RKernel {
155
157
}
156
158
}
157
159
158
- public async cancel ( cell : vscode . NotebookCell ) : Promise < void > {
159
- if ( this . socket && cell . metadata . runState === vscode . NotebookCellRunState . Running ) {
160
+ public cancel ( cell : vscode . NotebookCell ) {
161
+ if ( this . socket ) {
160
162
this . request ( {
161
163
id : cell . metadata . executionOrder ,
162
164
uri : cell . uri . toString ( ) ,
163
165
type : 'cancel' ,
164
- } )
166
+ } ) ;
165
167
}
166
168
}
167
169
}
@@ -187,12 +189,14 @@ class RNotebook implements vscode.Disposable {
187
189
await this . kernel . start ( ) ;
188
190
return this . kernel . eval ( cell ) ;
189
191
}
192
+
193
+ public async cancel ( cell : vscode . NotebookCell ) : Promise < void > {
194
+ return this . kernel . cancel ( cell ) ;
195
+ }
190
196
}
191
197
192
198
export class RNotebookProvider implements vscode . NotebookContentProvider , vscode . NotebookKernel {
193
199
public label = 'R Kernel' ;
194
- // public kernel = this;
195
-
196
200
private kernelScript : string ;
197
201
private disposables : vscode . Disposable [ ] = [ ] ;
198
202
private readonly notebooks = new Map < string , RNotebook > ( ) ;
@@ -406,7 +410,10 @@ export class RNotebookProvider implements vscode.NotebookContentProvider, vscode
406
410
}
407
411
408
412
async cancelCellExecution ( document : vscode . NotebookDocument , cell : vscode . NotebookCell ) {
409
-
413
+ if ( cell . metadata . runState === vscode . NotebookCellRunState . Running ) {
414
+ const notebook = this . notebooks . get ( document . uri . toString ( ) ) ;
415
+ await notebook . cancel ( cell ) ;
416
+ }
410
417
}
411
418
412
419
async cancelAllCellsExecution ( document : vscode . NotebookDocument ) {
0 commit comments