@@ -2,19 +2,18 @@ import * as vscode from 'vscode';
22import net = require( 'net' ) ;
33import { spawn , ChildProcess } from 'child_process' ;
44import { dirname } from 'path' ;
5- import * as fs from 'fs' ;
65
76interface RSessionRequest {
87 id : number ;
98 uri : string ;
109 type : 'eval' | 'cancel' ;
11- args : any ;
10+ expr ? : any ;
1211}
1312
1413interface RSessionResponse {
1514 id : number ;
1615 uri : string ;
17- type : 'text' | 'plot' | 'viewer' | 'browser' | 'error' | 'cancel' ;
16+ type : 'text' | 'plot' | 'viewer' | 'browser' | 'error' ;
1817 result : string ;
1918}
2019
@@ -32,63 +31,13 @@ class RKernel {
3231 this . doc = doc ;
3332 }
3433
35- private request ( obj : any ) {
34+ private request ( request : RSessionRequest ) {
3635 if ( this . socket ) {
37- const json = JSON . stringify ( obj ) ;
36+ const json = JSON . stringify ( request ) ;
3837 this . socket . write ( `Content-Length: ${ json . length } \n${ json } ` ) ;
3938 }
4039 }
4140
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-
9241 public async start ( ) {
9342 if ( this . process ) {
9443 return ;
@@ -103,6 +52,58 @@ class RKernel {
10352 this . socket = socket ;
10453 resolve ( undefined ) ;
10554
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+
106107 socket . on ( 'end' , ( ) => {
107108 console . log ( 'socket disconnected' ) ;
108109 this . socket = undefined ;
@@ -125,6 +126,7 @@ class RKernel {
125126 } ) ;
126127 childProcess . on ( 'exit' , ( code , signal ) => {
127128 console . log ( `R exited with code ${ code } ` ) ;
129+ reject ( undefined ) ;
128130 } ) ;
129131 this . process = childProcess ;
130132 return childProcess ;
@@ -144,7 +146,7 @@ class RKernel {
144146 await this . start ( ) ;
145147 }
146148
147- public async eval ( cell : vscode . NotebookCell ) : Promise < void > {
149+ public eval ( cell : vscode . NotebookCell ) {
148150 if ( this . socket ) {
149151 this . request ( {
150152 id : cell . metadata . executionOrder ,
@@ -155,13 +157,13 @@ class RKernel {
155157 }
156158 }
157159
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 ) {
160162 this . request ( {
161163 id : cell . metadata . executionOrder ,
162164 uri : cell . uri . toString ( ) ,
163165 type : 'cancel' ,
164- } )
166+ } ) ;
165167 }
166168 }
167169}
@@ -187,12 +189,14 @@ class RNotebook implements vscode.Disposable {
187189 await this . kernel . start ( ) ;
188190 return this . kernel . eval ( cell ) ;
189191 }
192+
193+ public async cancel ( cell : vscode . NotebookCell ) : Promise < void > {
194+ return this . kernel . cancel ( cell ) ;
195+ }
190196}
191197
192198export class RNotebookProvider implements vscode . NotebookContentProvider , vscode . NotebookKernel {
193199 public label = 'R Kernel' ;
194- // public kernel = this;
195-
196200 private kernelScript : string ;
197201 private disposables : vscode . Disposable [ ] = [ ] ;
198202 private readonly notebooks = new Map < string , RNotebook > ( ) ;
@@ -406,7 +410,10 @@ export class RNotebookProvider implements vscode.NotebookContentProvider, vscode
406410 }
407411
408412 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+ }
410417 }
411418
412419 async cancelAllCellsExecution ( document : vscode . NotebookDocument ) {
0 commit comments