44 *--------------------------------------------------------------------------------------------*/
55
66import { 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' ;
88import { Range } from 'vs/editor/common/core/range' ;
99import { FindDecorations } from 'vs/editor/contrib/find/browser/findDecorations' ;
1010import { ModelDecorationOptions } from 'vs/editor/common/model/textModel' ;
@@ -20,9 +20,45 @@ import { CancellationToken } from 'vs/base/common/cancellation';
2020import { NotebookFindFilters } from 'vs/workbench/contrib/notebook/browser/contrib/find/findFilters' ;
2121import { overviewRulerFindMatchForeground , overviewRulerSelectionHighlightForeground } from 'vs/platform/theme/common/colorRegistry' ;
2222
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+ }
2359
2460export class FindModel extends Disposable {
25- private _findMatches : CellFindMatch [ ] = [ ] ;
61+ private _findMatches : CellFindMatchWithIndex [ ] = [ ] ;
2662 protected _findMatchesStarts : PrefixSumComputer | null = null ;
2763 private _currentMatch : number = - 1 ;
2864 private _allMatchesDecorations : ICellModelDecorations [ ] = [ ] ;
@@ -79,12 +115,12 @@ export class FindModel extends Disposable {
79115 getCurrentMatch ( ) {
80116 const nextIndex = this . _findMatchesStarts ! . getIndexOf ( this . _currentMatch ) ;
81117 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 ) ;
83119
84120 return {
85121 cell,
86122 match,
87- isModelMatch : nextIndex . remainder < this . _findMatches [ nextIndex . index ] . modelMatchCount
123+ isModelMatch : nextIndex . remainder < this . _findMatches [ nextIndex . index ] . contentMatches . length
88124 } ;
89125 }
90126
@@ -96,7 +132,7 @@ export class FindModel extends Disposable {
96132 }
97133
98134 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 ) ;
100136
101137 if ( index === undefined ) {
102138 return ;
@@ -110,7 +146,7 @@ export class FindModel extends Disposable {
110146
111147 this . _state . changeMatchInfo (
112148 this . _currentMatch ,
113- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
149+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
114150 undefined
115151 ) ;
116152 } ) ;
@@ -149,15 +185,15 @@ export class FindModel extends Disposable {
149185
150186 this . _state . changeMatchInfo (
151187 this . _currentMatch ,
152- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
188+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
153189 undefined
154190 ) ;
155191 } ) ;
156192 }
157193
158194 private revealCellRange ( cellIndex : number , matchIndex : number , outputOffset : number | null ) {
159195 const findMatch = this . _findMatches [ cellIndex ] ;
160- if ( matchIndex >= findMatch . modelMatchCount ) {
196+ if ( matchIndex >= findMatch . contentMatches . length ) {
161197 // reveal output range
162198 this . _notebookEditor . focusElement ( findMatch . cell ) ;
163199 const index = this . _notebookEditor . getCellIndex ( findMatch . cell ) ;
@@ -166,7 +202,7 @@ export class FindModel extends Disposable {
166202 this . _notebookEditor . revealCellOffsetInCenterAsync ( findMatch . cell , outputOffset ?? 0 ) ;
167203 }
168204 } else {
169- const match = findMatch . matches [ matchIndex ] as FindMatch ;
205+ const match = findMatch . getMatch ( matchIndex ) as FindMatch ;
170206 findMatch . cell . updateEditState ( CellEditState . Editing , 'find' ) ;
171207 findMatch . cell . isInputCollapsed = false ;
172208 this . _notebookEditor . focusElement ( findMatch . cell ) ;
@@ -290,14 +326,14 @@ export class FindModel extends Disposable {
290326 // there are still some search results in current cell
291327 let currMatchRangeInEditor = cell . editorAttached && currentMatchDecorationId . decorations [ 0 ] ? cell . getCellDecorationRange ( currentMatchDecorationId . decorations [ 0 ] ) : null ;
292328
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 ;
295331 }
296332
297333 if ( currMatchRangeInEditor !== null ) {
298334 // we find a range for the previous current match, let's find the nearest one after it (can overlap)
299335 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 ) ;
301337 this . _updateCurrentMatch ( findMatches , this . _matchesCountBeforeIndex ( findMatches , matchAfterSelection ) + matchAfterOldSelection ) ;
302338 } else {
303339 // no range found, let's fall back to finding the nearest match
@@ -312,7 +348,7 @@ export class FindModel extends Disposable {
312348 }
313349 }
314350
315- private set ( cellFindMatches : CellFindMatch [ ] | null , autoStart : boolean ) : void {
351+ private set ( cellFindMatches : CellFindMatchWithIndex [ ] | null , autoStart : boolean ) : void {
316352 if ( ! cellFindMatches || ! cellFindMatches . length ) {
317353 this . _findMatches = [ ] ;
318354 this . setAllFindMatchesDecorations ( [ ] ) ;
@@ -323,7 +359,7 @@ export class FindModel extends Disposable {
323359
324360 this . _state . changeMatchInfo (
325361 this . _currentMatch ,
326- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
362+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
327363 undefined
328364 ) ;
329365 return ;
@@ -343,7 +379,7 @@ export class FindModel extends Disposable {
343379
344380 this . _state . changeMatchInfo (
345381 this . _currentMatch ,
346- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
382+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
347383 undefined
348384 ) ;
349385 }
@@ -385,15 +421,15 @@ export class FindModel extends Disposable {
385421
386422 this . _state . changeMatchInfo (
387423 this . _currentMatch ,
388- this . _findMatches . reduce ( ( p , c ) => p + c . matches . length , 0 ) ,
424+ this . _findMatches . reduce ( ( p , c ) => p + c . length , 0 ) ,
389425 undefined
390426 ) ;
391427 }
392428
393429 private _matchesCountBeforeIndex ( findMatches : CellFindMatchWithIndex [ ] , index : number ) {
394430 let prevMatchesCount = 0 ;
395431 for ( let i = 0 ; i < index ; i ++ ) {
396- prevMatchesCount += findMatches [ i ] . matches . length ;
432+ prevMatchesCount += findMatches [ i ] . length ;
397433 }
398434
399435 return prevMatchesCount ;
@@ -403,7 +439,7 @@ export class FindModel extends Disposable {
403439 if ( this . _findMatches && this . _findMatches . length ) {
404440 const values = new Uint32Array ( this . _findMatches . length ) ;
405441 for ( let i = 0 ; i < this . _findMatches . length ; i ++ ) {
406- values [ i ] = this . _findMatches [ i ] . matches . length ;
442+ values [ i ] = this . _findMatches [ i ] . length ;
407443 }
408444
409445 this . _findMatchesStarts = new PrefixSumComputer ( values ) ;
@@ -415,10 +451,10 @@ export class FindModel extends Disposable {
415451 private async highlightCurrentFindMatchDecoration ( cellIndex : number , matchIndex : number ) : Promise < number | null > {
416452 const cell = this . _findMatches [ cellIndex ] . cell ;
417453
418- if ( matchIndex < this . _findMatches [ cellIndex ] . modelMatchCount ) {
454+ if ( matchIndex < this . _findMatches [ cellIndex ] . contentMatches . length ) {
419455 this . clearCurrentFindMatchDecoration ( ) ;
420456
421- const match = this . _findMatches [ cellIndex ] . matches [ matchIndex ] as FindMatch ;
457+ const match = this . _findMatches [ cellIndex ] . getMatch ( matchIndex ) as FindMatch ;
422458 // match is an editor FindMatch, we update find match decoration in the editor
423459 // we will highlight the match in the webview
424460 this . _notebookEditor . changeModelDecorations ( accessor => {
@@ -454,7 +490,7 @@ export class FindModel extends Disposable {
454490 } else {
455491 this . clearCurrentFindMatchDecoration ( ) ;
456492
457- const match = this . _findMatches [ cellIndex ] . matches [ matchIndex ] as OutputFindMatch ;
493+ const match = this . _findMatches [ cellIndex ] . getMatch ( matchIndex ) as CellWebviewFindMatch ;
458494 const offset = await this . _notebookEditor . highlightFind ( cell , match . index ) ;
459495 this . _currentMatchDecorations = { kind : 'output' , index : match . index } ;
460496
@@ -487,19 +523,17 @@ export class FindModel extends Disposable {
487523 this . _currentMatchCellDecorations = this . _notebookEditor . deltaCellDecorations ( this . _currentMatchCellDecorations , [ ] ) ;
488524 }
489525
490- private setAllFindMatchesDecorations ( cellFindMatches : CellFindMatch [ ] ) {
526+ private setAllFindMatchesDecorations ( cellFindMatches : CellFindMatchWithIndex [ ] ) {
491527 this . _notebookEditor . changeModelDecorations ( ( accessor ) => {
492528
493529 const findMatchesOptions : ModelDecorationOptions = FindDecorations . _FIND_MATCH_DECORATION ;
494530
495531 const deltaDecorations : ICellModelDeltaDecorations [ ] = cellFindMatches . map ( cellFindMatch => {
496- const findMatches = cellFindMatch . matches ;
497-
498532 // 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 ++ ) {
501535 newFindMatchesDecorations [ i ] = {
502- range : ( findMatches [ i ] as FindMatch ) . range ,
536+ range : cellFindMatch . contentMatches [ i ] . range ,
503537 options : findMatchesOptions
504538 } ;
505539 }
@@ -517,8 +551,8 @@ export class FindModel extends Disposable {
517551 options : {
518552 overviewRuler : {
519553 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
522556 }
523557 }
524558 } ;
0 commit comments