4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import { CancelablePromise , createCancelablePromise , Delayer } from 'vs/base/common/async' ;
7
- import { INotebookEditor , CellFindMatch , CellEditState , CellFindMatchWithIndex , OutputFindMatch , ICellModelDecorations , ICellModelDeltaDecorations , INotebookDeltaDecoration , ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser' ;
7
+ import { INotebookEditor , CellEditState , CellFindMatchWithIndex , CellWebviewFindMatch , ICellModelDecorations , ICellModelDeltaDecorations , INotebookDeltaDecoration , ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser' ;
8
8
import { Range } from 'vs/editor/common/core/range' ;
9
9
import { FindDecorations } from 'vs/editor/contrib/find/browser/findDecorations' ;
10
10
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel' ;
@@ -20,9 +20,45 @@ import { CancellationToken } from 'vs/base/common/cancellation';
20
20
import { NotebookFindFilters } from 'vs/workbench/contrib/notebook/browser/contrib/find/findFilters' ;
21
21
import { overviewRulerFindMatchForeground , overviewRulerSelectionHighlightForeground } from 'vs/platform/theme/common/colorRegistry' ;
22
22
23
+ export class CellFindMatchModel implements CellFindMatchWithIndex {
24
+ readonly cell : ICellViewModel ;
25
+ readonly index : number ;
26
+ private _contentMatches : FindMatch [ ] ;
27
+ private _webviewMatches : CellWebviewFindMatch [ ] ;
28
+ get length ( ) {
29
+ return this . _contentMatches . length + this . _webviewMatches . length ;
30
+ }
31
+
32
+ get contentMatches ( ) : FindMatch [ ] {
33
+ return this . _contentMatches ;
34
+ }
35
+
36
+ get webviewMatches ( ) : CellWebviewFindMatch [ ] {
37
+ return this . _webviewMatches ;
38
+ }
39
+
40
+ constructor ( cell : ICellViewModel , index : number , contentMatches : FindMatch [ ] , webviewMatches : CellWebviewFindMatch [ ] ) {
41
+ this . cell = cell ;
42
+ this . index = index ;
43
+ this . _contentMatches = contentMatches ;
44
+ this . _webviewMatches = webviewMatches ;
45
+ }
46
+
47
+ getMatch ( index : number ) {
48
+ if ( index >= this . length ) {
49
+ throw new Error ( 'NotebookCellFindMatch: index out of range' ) ;
50
+ }
51
+
52
+ if ( index < this . _contentMatches . length ) {
53
+ return this . _contentMatches [ index ] ;
54
+ }
55
+
56
+ return this . _webviewMatches [ index - this . _contentMatches . length ] ;
57
+ }
58
+ }
23
59
24
60
export class FindModel extends Disposable {
25
- private _findMatches : CellFindMatch [ ] = [ ] ;
61
+ private _findMatches : CellFindMatchWithIndex [ ] = [ ] ;
26
62
protected _findMatchesStarts : PrefixSumComputer | null = null ;
27
63
private _currentMatch : number = - 1 ;
28
64
private _allMatchesDecorations : ICellModelDecorations [ ] = [ ] ;
@@ -79,12 +115,12 @@ export class FindModel extends Disposable {
79
115
getCurrentMatch ( ) {
80
116
const nextIndex = this . _findMatchesStarts ! . getIndexOf ( this . _currentMatch ) ;
81
117
const cell = this . _findMatches [ nextIndex . index ] . cell ;
82
- const match = this . _findMatches [ nextIndex . index ] . matches [ nextIndex . remainder ] ;
118
+ const match = this . _findMatches [ nextIndex . index ] . getMatch ( nextIndex . remainder ) ;
83
119
84
120
return {
85
121
cell,
86
122
match,
87
- isModelMatch : nextIndex . remainder < this . _findMatches [ nextIndex . index ] . modelMatchCount
123
+ isModelMatch : nextIndex . remainder < this . _findMatches [ nextIndex . index ] . contentMatches . length
88
124
} ;
89
125
}
90
126
@@ -96,7 +132,7 @@ export class FindModel extends Disposable {
96
132
}
97
133
98
134
const findMatch = this . findMatches [ findMatchIndex ] ;
99
- const index = findMatch . matches . slice ( 0 , findMatch . modelMatchCount ) . findIndex ( match => ( match as FindMatch ) . range . intersectRanges ( focus . range ) !== null ) ;
135
+ const index = findMatch . contentMatches . findIndex ( match => match . range . intersectRanges ( focus . range ) !== null ) ;
100
136
101
137
if ( index === undefined ) {
102
138
return ;
@@ -110,7 +146,7 @@ export class FindModel extends Disposable {
110
146
111
147
this . _state . changeMatchInfo (
112
148
this . _currentMatch ,
113
- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
149
+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
114
150
undefined
115
151
) ;
116
152
} ) ;
@@ -149,15 +185,15 @@ export class FindModel extends Disposable {
149
185
150
186
this . _state . changeMatchInfo (
151
187
this . _currentMatch ,
152
- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
188
+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
153
189
undefined
154
190
) ;
155
191
} ) ;
156
192
}
157
193
158
194
private revealCellRange ( cellIndex : number , matchIndex : number , outputOffset : number | null ) {
159
195
const findMatch = this . _findMatches [ cellIndex ] ;
160
- if ( matchIndex >= findMatch . modelMatchCount ) {
196
+ if ( matchIndex >= findMatch . contentMatches . length ) {
161
197
// reveal output range
162
198
this . _notebookEditor . focusElement ( findMatch . cell ) ;
163
199
const index = this . _notebookEditor . getCellIndex ( findMatch . cell ) ;
@@ -166,7 +202,7 @@ export class FindModel extends Disposable {
166
202
this . _notebookEditor . revealCellOffsetInCenterAsync ( findMatch . cell , outputOffset ?? 0 ) ;
167
203
}
168
204
} else {
169
- const match = findMatch . matches [ matchIndex ] as FindMatch ;
205
+ const match = findMatch . getMatch ( matchIndex ) as FindMatch ;
170
206
findMatch . cell . updateEditState ( CellEditState . Editing , 'find' ) ;
171
207
findMatch . cell . isInputCollapsed = false ;
172
208
this . _notebookEditor . focusElement ( findMatch . cell ) ;
@@ -290,14 +326,14 @@ export class FindModel extends Disposable {
290
326
// there are still some search results in current cell
291
327
let currMatchRangeInEditor = cell . editorAttached && currentMatchDecorationId . decorations [ 0 ] ? cell . getCellDecorationRange ( currentMatchDecorationId . decorations [ 0 ] ) : null ;
292
328
293
- if ( currMatchRangeInEditor === null && oldCurrIndex . remainder < this . _findMatches [ oldCurrIndex . index ] . modelMatchCount ) {
294
- currMatchRangeInEditor = ( this . _findMatches [ oldCurrIndex . index ] . matches [ oldCurrIndex . remainder ] as FindMatch ) . range ;
329
+ if ( currMatchRangeInEditor === null && oldCurrIndex . remainder < this . _findMatches [ oldCurrIndex . index ] . contentMatches . length ) {
330
+ currMatchRangeInEditor = ( this . _findMatches [ oldCurrIndex . index ] . getMatch ( oldCurrIndex . remainder ) as FindMatch ) . range ;
295
331
}
296
332
297
333
if ( currMatchRangeInEditor !== null ) {
298
334
// we find a range for the previous current match, let's find the nearest one after it (can overlap)
299
335
const cellMatch = findMatches [ matchAfterSelection ] ;
300
- const matchAfterOldSelection = findFirstInSorted ( cellMatch . matches . slice ( 0 , cellMatch . modelMatchCount ) , match => Range . compareRangesUsingStarts ( ( match as FindMatch ) . range , currMatchRangeInEditor ) >= 0 ) ;
336
+ const matchAfterOldSelection = findFirstInSorted ( cellMatch . contentMatches , match => Range . compareRangesUsingStarts ( ( match as FindMatch ) . range , currMatchRangeInEditor ) >= 0 ) ;
301
337
this . _updateCurrentMatch ( findMatches , this . _matchesCountBeforeIndex ( findMatches , matchAfterSelection ) + matchAfterOldSelection ) ;
302
338
} else {
303
339
// no range found, let's fall back to finding the nearest match
@@ -312,7 +348,7 @@ export class FindModel extends Disposable {
312
348
}
313
349
}
314
350
315
- private set ( cellFindMatches : CellFindMatch [ ] | null , autoStart : boolean ) : void {
351
+ private set ( cellFindMatches : CellFindMatchWithIndex [ ] | null , autoStart : boolean ) : void {
316
352
if ( ! cellFindMatches || ! cellFindMatches . length ) {
317
353
this . _findMatches = [ ] ;
318
354
this . setAllFindMatchesDecorations ( [ ] ) ;
@@ -323,7 +359,7 @@ export class FindModel extends Disposable {
323
359
324
360
this . _state . changeMatchInfo (
325
361
this . _currentMatch ,
326
- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
362
+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
327
363
undefined
328
364
) ;
329
365
return ;
@@ -343,7 +379,7 @@ export class FindModel extends Disposable {
343
379
344
380
this . _state . changeMatchInfo (
345
381
this . _currentMatch ,
346
- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
382
+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
347
383
undefined
348
384
) ;
349
385
}
@@ -385,15 +421,15 @@ export class FindModel extends Disposable {
385
421
386
422
this . _state . changeMatchInfo (
387
423
this . _currentMatch ,
388
- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
424
+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
389
425
undefined
390
426
) ;
391
427
}
392
428
393
429
private _matchesCountBeforeIndex ( findMatches : CellFindMatchWithIndex [ ] , index : number ) {
394
430
let prevMatchesCount = 0 ;
395
431
for ( let i = 0 ; i < index ; i ++ ) {
396
- prevMatchesCount += findMatches [ i ] . matches . length ;
432
+ prevMatchesCount += findMatches [ i ] . length ;
397
433
}
398
434
399
435
return prevMatchesCount ;
@@ -403,7 +439,7 @@ export class FindModel extends Disposable {
403
439
if ( this . _findMatches && this . _findMatches . length ) {
404
440
const values = new Uint32Array ( this . _findMatches . length ) ;
405
441
for ( let i = 0 ; i < this . _findMatches . length ; i ++ ) {
406
- values [ i ] = this . _findMatches [ i ] . matches . length ;
442
+ values [ i ] = this . _findMatches [ i ] . length ;
407
443
}
408
444
409
445
this . _findMatchesStarts = new PrefixSumComputer ( values ) ;
@@ -415,10 +451,10 @@ export class FindModel extends Disposable {
415
451
private async highlightCurrentFindMatchDecoration ( cellIndex : number , matchIndex : number ) : Promise < number | null > {
416
452
const cell = this . _findMatches [ cellIndex ] . cell ;
417
453
418
- if ( matchIndex < this . _findMatches [ cellIndex ] . modelMatchCount ) {
454
+ if ( matchIndex < this . _findMatches [ cellIndex ] . contentMatches . length ) {
419
455
this . clearCurrentFindMatchDecoration ( ) ;
420
456
421
- const match = this . _findMatches [ cellIndex ] . matches [ matchIndex ] as FindMatch ;
457
+ const match = this . _findMatches [ cellIndex ] . getMatch ( matchIndex ) as FindMatch ;
422
458
// match is an editor FindMatch, we update find match decoration in the editor
423
459
// we will highlight the match in the webview
424
460
this . _notebookEditor . changeModelDecorations ( accessor => {
@@ -454,7 +490,7 @@ export class FindModel extends Disposable {
454
490
} else {
455
491
this . clearCurrentFindMatchDecoration ( ) ;
456
492
457
- const match = this . _findMatches [ cellIndex ] . matches [ matchIndex ] as OutputFindMatch ;
493
+ const match = this . _findMatches [ cellIndex ] . getMatch ( matchIndex ) as CellWebviewFindMatch ;
458
494
const offset = await this . _notebookEditor . highlightFind ( cell , match . index ) ;
459
495
this . _currentMatchDecorations = { kind : 'output' , index : match . index } ;
460
496
@@ -487,19 +523,17 @@ export class FindModel extends Disposable {
487
523
this . _currentMatchCellDecorations = this . _notebookEditor . deltaCellDecorations ( this . _currentMatchCellDecorations , [ ] ) ;
488
524
}
489
525
490
- private setAllFindMatchesDecorations ( cellFindMatches : CellFindMatch [ ] ) {
526
+ private setAllFindMatchesDecorations ( cellFindMatches : CellFindMatchWithIndex [ ] ) {
491
527
this . _notebookEditor . changeModelDecorations ( ( accessor ) => {
492
528
493
529
const findMatchesOptions : ModelDecorationOptions = FindDecorations . _FIND_MATCH_DECORATION ;
494
530
495
531
const deltaDecorations : ICellModelDeltaDecorations [ ] = cellFindMatches . map ( cellFindMatch => {
496
- const findMatches = cellFindMatch . matches ;
497
-
498
532
// Find matches
499
- const newFindMatchesDecorations : IModelDeltaDecoration [ ] = new Array < IModelDeltaDecoration > ( findMatches . length ) ;
500
- for ( let i = 0 , len = Math . min ( findMatches . length , cellFindMatch . modelMatchCount ) ; i < len ; i ++ ) {
533
+ const newFindMatchesDecorations : IModelDeltaDecoration [ ] = new Array < IModelDeltaDecoration > ( cellFindMatch . length ) ;
534
+ for ( let i = 0 ; i < cellFindMatch . contentMatches . length ; i ++ ) {
501
535
newFindMatchesDecorations [ i ] = {
502
- range : ( findMatches [ i ] as FindMatch ) . range ,
536
+ range : cellFindMatch . contentMatches [ i ] . range ,
503
537
options : findMatchesOptions
504
538
} ;
505
539
}
@@ -517,8 +551,8 @@ export class FindModel extends Disposable {
517
551
options : {
518
552
overviewRuler : {
519
553
color : overviewRulerFindMatchForeground ,
520
- modelRanges : cellFindMatch . matches . slice ( 0 , cellFindMatch . modelMatchCount ) . map ( match => ( match as FindMatch ) . range ) ,
521
- includeOutput : cellFindMatch . modelMatchCount < cellFindMatch . matches . length
554
+ modelRanges : cellFindMatch . contentMatches . map ( match => match . range ) ,
555
+ includeOutput : cellFindMatch . webviewMatches . length > 0
522
556
}
523
557
}
524
558
} ;
0 commit comments