10
10
*/
11
11
12
12
import * as assert from 'assert' ;
13
- import { createCellFrom } from '../../../../datascience-ui/common/cellFactory' ;
14
13
import {
15
14
NotebookCellLanguageChangeEvent ,
16
15
NotebookCellOutputsChangeEvent ,
17
16
NotebookCellsChangeEvent
18
17
} from '../../../common/application/types' ;
19
- import { MARKDOWN_LANGUAGE } from '../../../common/constants' ;
20
18
import { traceError } from '../../../common/logger' ;
21
19
import { sendTelemetryEvent } from '../../../telemetry' ;
22
20
import { VSCodeNativeTelemetry } from '../../constants' ;
23
- import { INotebookModel } from '../../types ' ;
21
+ import { VSCodeNotebookModel } from '../../notebookStorage/vscNotebookModel ' ;
24
22
import { findMappedNotebookCellModel } from './cellMappers' ;
25
- import {
26
- createCellFromVSCNotebookCell ,
27
- createVSCCellOutputsFromOutputs ,
28
- updateVSCNotebookCellMetadata
29
- } from './helpers' ;
23
+ import { createCellFromVSCNotebookCell , updateVSCNotebookCellMetadata } from './helpers' ;
30
24
// tslint:disable-next-line: no-var-requires no-require-imports
31
- const vscodeNotebookEnums = require ( 'vscode' ) as typeof import ( 'vscode-proposed' ) ;
32
25
33
26
/**
34
27
* If a VS Code cell changes, then ensure we update the corresponding cell in our INotebookModel.
@@ -37,13 +30,17 @@ const vscodeNotebookEnums = require('vscode') as typeof import('vscode-proposed'
37
30
*/
38
31
export function updateCellModelWithChangesToVSCCell (
39
32
change : NotebookCellsChangeEvent | NotebookCellOutputsChangeEvent | NotebookCellLanguageChangeEvent ,
40
- model : INotebookModel
33
+ model : VSCodeNotebookModel
41
34
) : boolean | undefined | void {
42
35
switch ( change . type ) {
43
36
case 'changeCellOutputs' :
44
37
return clearCellOutput ( change , model ) ;
45
38
case 'changeCellLanguage' :
46
- return changeCellLanguage ( change , model ) ;
39
+ // VSC Fires this event only when changing code cells from one language to another.
40
+ // If you change markdown to code &/or vice versa, thats treated as a cell being deleted and added.
41
+ // In the case of Jupyter cells, we don't care of the language changes from python to csharp.
42
+ // Why? Because today its not possible, hence there's nothing we need to do for now.
43
+ return false ;
47
44
case 'changeCells' :
48
45
return handleChangesToCells ( change , model ) ;
49
46
default :
@@ -58,7 +55,7 @@ export function updateCellModelWithChangesToVSCCell(
58
55
* However we are interested in cell output being cleared (when user clears output).
59
56
* @returns {boolean } Return `true` if NotebookDocument was updated/edited.
60
57
*/
61
- function clearCellOutput ( change : NotebookCellOutputsChangeEvent , model : INotebookModel ) : boolean {
58
+ function clearCellOutput ( change : NotebookCellOutputsChangeEvent , model : VSCodeNotebookModel ) : boolean {
62
59
if ( ! change . cells . every ( ( cell ) => cell . outputs . length === 0 ) ) {
63
60
return false ;
64
61
}
@@ -73,65 +70,14 @@ function clearCellOutput(change: NotebookCellOutputsChangeEvent, model: INoteboo
73
70
// If a cell has been cleared, then clear the corresponding ICell (cell in INotebookModel).
74
71
change . cells . forEach ( ( vscCell ) => {
75
72
const cell = findMappedNotebookCellModel ( vscCell , model . cells ) ;
76
- // tslint:disable-next-line: no-console
77
- console . log ( cell ) ;
78
- if ( vscCell . cellKind === vscodeNotebookEnums . CellKind . Code ) {
79
- cell . data . execution_count = null ;
80
- }
81
- if ( cell . data . metadata . vscode ) {
82
- cell . data . metadata . vscode . start_execution_time = undefined ;
83
- cell . data . metadata . vscode . end_execution_time = undefined ;
84
- }
85
- cell . data . outputs = [ ] ;
73
+ model . clearCellOutput ( cell ) ;
86
74
updateVSCNotebookCellMetadata ( vscCell . metadata , cell ) ;
87
- model . update ( {
88
- source : 'user' ,
89
- kind : 'clear' ,
90
- oldDirty : model . isDirty ,
91
- newDirty : true ,
92
- oldCells : [ cell ]
93
- } ) ;
94
75
} ) ;
95
76
96
77
return true ;
97
78
}
98
79
99
- /**
100
- * VS Code doesn't seem to fire this when changing between markdown & code.
101
- * Its only fired when changing the language from python to csharp.
102
- * https://github.com/microsoft/vscode/issues/100042
103
- */
104
- function changeCellLanguage ( change : NotebookCellLanguageChangeEvent , model : INotebookModel ) {
105
- const cellModel = findMappedNotebookCellModel ( change . cell , model . cells ) ;
106
- if (
107
- ( change . cell . cellKind === vscodeNotebookEnums . CellKind . Markdown && cellModel . data . cell_type === 'markdown' ) ||
108
- ( change . cell . cellKind === vscodeNotebookEnums . CellKind . Code && cellModel . data . cell_type === 'code' )
109
- ) {
110
- // This is when user changes from python to csharp or similar.
111
- return ;
112
- }
113
- // Here we have changed from a code cell to markdown or vice versa.
114
- const cellData = createCellFrom ( cellModel . data , change . language === MARKDOWN_LANGUAGE ? 'markdown' : 'code' ) ;
115
- // tslint:disable-next-line: no-any
116
- change . cell . outputs = createVSCCellOutputsFromOutputs ( cellData . outputs as any ) ;
117
- change . cell . metadata . executionOrder = undefined ;
118
- change . cell . metadata . hasExecutionOrder = change . language !== MARKDOWN_LANGUAGE ; // Do not check for Python, to support other languages
119
- change . cell . metadata . runnable = change . language !== MARKDOWN_LANGUAGE ; // Do not check for Python, to support other languages
120
-
121
- // Create a new cell & replace old one.
122
- const oldCellIndex = model . cells . indexOf ( cellModel ) ;
123
- // tslint:disable-next-line: no-suspicious-comment
124
- // TODO: CHANGE.
125
- // tslint:disable-next-line: no-any
126
- ( model . cells as any ) [ oldCellIndex ] = createCellFromVSCNotebookCell ( change . cell , model ) ;
127
- sendTelemetryEvent (
128
- change . cell . cellKind === vscodeNotebookEnums . CellKind . Markdown
129
- ? VSCodeNativeTelemetry . ChangeToMarkdown
130
- : VSCodeNativeTelemetry . ChangeToCode
131
- ) ;
132
- }
133
-
134
- function handleChangesToCells ( change : NotebookCellsChangeEvent , model : INotebookModel ) {
80
+ function handleChangesToCells ( change : NotebookCellsChangeEvent , model : VSCodeNotebookModel ) {
135
81
if ( isCellMoveChange ( change ) ) {
136
82
handleCellMove ( change , model ) ;
137
83
sendTelemetryEvent ( VSCodeNativeTelemetry . MoveCell ) ;
@@ -171,59 +117,26 @@ function isCellInsertion(change: NotebookCellsChangeEvent) {
171
117
return change . changes . length === 1 && change . changes [ 0 ] . deletedCount === 0 && change . changes [ 0 ] . items . length > 0 ;
172
118
}
173
119
174
- function handleCellMove ( change : NotebookCellsChangeEvent , model : INotebookModel ) {
120
+ function handleCellMove ( change : NotebookCellsChangeEvent , model : VSCodeNotebookModel ) {
175
121
assert . equal ( change . changes . length , 2 , 'When moving cells we must have only 2 changes' ) ;
176
122
const [ , insertChange ] = change . changes ;
177
123
const cellToSwap = findMappedNotebookCellModel ( insertChange . items [ 0 ] ! , model . cells ) ;
178
124
const cellToSwapWith = model . cells [ insertChange . start ] ;
179
125
assert . notEqual ( cellToSwap , cellToSwapWith , 'Cannot swap cell with the same cell' ) ;
180
-
181
- const indexOfCellToSwap = model . cells . indexOf ( cellToSwap ) ;
182
- // tslint:disable-next-line: no-any
183
- ( model . cells as any ) [ insertChange . start ] = cellToSwap ;
184
- // tslint:disable-next-line: no-any
185
- ( model . cells as any ) [ indexOfCellToSwap ] = cellToSwapWith ;
186
- // Get model to fire events.
187
- model . update ( {
188
- source : 'user' ,
189
- kind : 'swap' ,
190
- firstCellId : cellToSwap . id ,
191
- secondCellId : cellToSwapWith . id ,
192
- oldDirty : model . isDirty ,
193
- newDirty : true
194
- } ) ;
126
+ model . swapCells ( cellToSwap , cellToSwapWith ) ;
195
127
}
196
- function handleCellInsertion ( change : NotebookCellsChangeEvent , model : INotebookModel ) {
128
+ function handleCellInsertion ( change : NotebookCellsChangeEvent , model : VSCodeNotebookModel ) {
197
129
assert . equal ( change . changes . length , 1 , 'When inserting cells we must have only 1 change' ) ;
198
130
assert . equal ( change . changes [ 0 ] . items . length , 1 , 'Insertion of more than 1 cell is not supported' ) ;
199
131
const insertChange = change . changes [ 0 ] ;
200
132
const cell = change . changes [ 0 ] . items [ 0 ] ;
201
133
const newCell = createCellFromVSCNotebookCell ( cell , model ) ;
202
- // tslint:disable-next-line: no-any
203
- ( model . cells as any ) . splice ( insertChange . start , 0 , newCell ) ;
204
- // Get model to fire events.
205
- model . update ( {
206
- source : 'user' ,
207
- kind : 'insert' ,
208
- cell : newCell ,
209
- index : insertChange . start ,
210
- oldDirty : model . isDirty ,
211
- newDirty : true
212
- } ) ;
134
+ model . addCell ( newCell , insertChange . start ) ;
213
135
}
214
- function handleCellDelete ( change : NotebookCellsChangeEvent , model : INotebookModel ) {
136
+ function handleCellDelete ( change : NotebookCellsChangeEvent , model : VSCodeNotebookModel ) {
215
137
assert . equal ( change . changes . length , 1 , 'When deleting cells we must have only 1 change' ) ;
216
138
const deletionChange = change . changes [ 0 ] ;
217
139
assert . equal ( deletionChange . deletedCount , 1 , 'Deleting more than one cell is not supported' ) ;
218
- // tslint:disable-next-line: no-any
219
- const cellToRemove = ( model . cells as any ) . splice ( deletionChange . start , 1 ) ;
220
- // Get model to fire events.
221
- model . update ( {
222
- source : 'user' ,
223
- kind : 'remove' ,
224
- cell : cellToRemove [ 0 ] ,
225
- index : deletionChange . start ,
226
- oldDirty : model . isDirty ,
227
- newDirty : true
228
- } ) ;
140
+ const cellToRemove = model . cells [ deletionChange . start ] ;
141
+ model . deleteCell ( cellToRemove ) ;
229
142
}
0 commit comments