@@ -73,9 +73,11 @@ interface IOccurenceAtPositionRequest {
73
73
}
74
74
75
75
interface IWordHighlighterQuery {
76
- readonly model : ITextModel ;
77
- readonly selection : Selection ;
78
- readonly word : IWordAtPosition ;
76
+ modelInfo : {
77
+ model : ITextModel ;
78
+ selection : Selection ;
79
+ } | null ;
80
+ readonly word : IWordAtPosition | null ;
79
81
}
80
82
81
83
abstract class OccurenceAtPositionRequest implements IOccurenceAtPositionRequest {
@@ -93,7 +95,6 @@ abstract class OccurenceAtPositionRequest implements IOccurenceAtPositionRequest
93
95
this . _result = createCancelablePromise ( token => this . _compute ( this . _model , this . _selection , this . _wordSeparators , token ) ) ;
94
96
}
95
97
return this . _result ;
96
-
97
98
}
98
99
99
100
protected abstract _compute ( model : ITextModel , selection : Selection , wordSeparators : string , token : CancellationToken ) : Promise < ResourceMap < DocumentHighlight [ ] > > ;
@@ -177,18 +178,27 @@ class TextualOccurenceRequest extends OccurenceAtPositionRequest {
177
178
178
179
private readonly _otherModels : ITextModel [ ] ;
179
180
private readonly _selectionIsEmpty : boolean ;
181
+ private readonly _word : IWordAtPosition | null ;
180
182
181
- constructor ( model : ITextModel , selection : Selection , wordSeparators : string , otherModels : ITextModel [ ] ) {
183
+ constructor ( model : ITextModel , selection : Selection , word : IWordAtPosition | null , wordSeparators : string , otherModels : ITextModel [ ] ) {
182
184
super ( model , selection , wordSeparators ) ;
183
185
this . _otherModels = otherModels ;
184
186
this . _selectionIsEmpty = selection . isEmpty ( ) ;
187
+ this . _word = word ;
185
188
}
186
189
187
190
protected _compute ( model : ITextModel , selection : Selection , wordSeparators : string , token : CancellationToken ) : Promise < ResourceMap < DocumentHighlight [ ] > > {
188
191
return timeout ( 250 , token ) . then ( ( ) => {
189
192
const result = new ResourceMap < DocumentHighlight [ ] > ( ) ;
190
- const word = model . getWordAtPosition ( selection . getPosition ( ) ) ;
191
- if ( ! word ) {
193
+
194
+ let wordResult ;
195
+ if ( this . _word ) {
196
+ wordResult = this . _word ;
197
+ } else {
198
+ wordResult = model . getWordAtPosition ( selection . getPosition ( ) ) ;
199
+ }
200
+
201
+ if ( ! wordResult ) {
192
202
return new ResourceMap < DocumentHighlight [ ] > ( ) ;
193
203
}
194
204
@@ -199,7 +209,7 @@ class TextualOccurenceRequest extends OccurenceAtPositionRequest {
199
209
continue ;
200
210
}
201
211
202
- const matches = otherModel . findMatches ( word . word , true , false , true , wordSeparators , false ) ;
212
+ const matches = otherModel . findMatches ( wordResult . word , true , false , true , wordSeparators , false ) ;
203
213
const highlights = matches . map ( m => ( {
204
214
range : m . range ,
205
215
kind : DocumentHighlightKind . Text
@@ -222,18 +232,18 @@ class TextualOccurenceRequest extends OccurenceAtPositionRequest {
222
232
}
223
233
}
224
234
225
- function computeOccurencesAtPosition ( registry : LanguageFeatureRegistry < DocumentHighlightProvider > , model : ITextModel , selection : Selection , wordSeparators : string ) : IOccurenceAtPositionRequest {
235
+ function computeOccurencesAtPosition ( registry : LanguageFeatureRegistry < DocumentHighlightProvider > , model : ITextModel , selection : Selection , word : IWordAtPosition | null , wordSeparators : string ) : IOccurenceAtPositionRequest {
226
236
if ( registry . has ( model ) ) {
227
237
return new SemanticOccurenceAtPositionRequest ( model , selection , wordSeparators , registry ) ;
228
238
}
229
- return new TextualOccurenceRequest ( model , selection , wordSeparators , [ ] ) ;
239
+ return new TextualOccurenceRequest ( model , selection , word , wordSeparators , [ ] ) ;
230
240
}
231
241
232
- function computeOccurencesMultiModel ( registry : LanguageFeatureRegistry < MultiDocumentHighlightProvider > , model : ITextModel , selection : Selection , wordSeparators : string , otherModels : ITextModel [ ] ) : IOccurenceAtPositionRequest {
242
+ function computeOccurencesMultiModel ( registry : LanguageFeatureRegistry < MultiDocumentHighlightProvider > , model : ITextModel , selection : Selection , word : IWordAtPosition | null , wordSeparators : string , otherModels : ITextModel [ ] ) : IOccurenceAtPositionRequest {
233
243
if ( registry . has ( model ) ) {
234
244
return new MultiModelOccurenceRequest ( model , selection , wordSeparators , registry , otherModels ) ;
235
245
}
236
- return new TextualOccurenceRequest ( model , selection , wordSeparators , otherModels ) ;
246
+ return new TextualOccurenceRequest ( model , selection , word , wordSeparators , otherModels ) ;
237
247
}
238
248
239
249
registerModelAndPositionCommand ( '_executeDocumentHighlights' , ( accessor , model , position ) => {
@@ -326,9 +336,9 @@ class WordHighlighter {
326
336
this . renderDecorationsTimer = - 1 ;
327
337
328
338
// if there is a query already, highlight off that query
329
- // if (WordHighlighter.query) {
330
- // this._run();
331
- // }
339
+ if ( WordHighlighter . query ) {
340
+ this . _run ( ) ;
341
+ }
332
342
}
333
343
334
344
public hasDecorations ( ) : boolean {
@@ -396,14 +406,6 @@ class WordHighlighter {
396
406
}
397
407
398
408
private _removeSingleDecorations ( ) : void {
399
- // Clear current query if editor is focused
400
- // if (this.editor.hasWidgetFocus() && this.editor.getModel()?.uri.scheme !== Schemas.vscodeNotebookCell) {
401
- if ( this . editor . hasWidgetFocus ( ) && ! ( WordHighlighter . query ?. model . uri . scheme === Schemas . vscodeNotebookCell || this . editor . getModel ( ) ?. uri . scheme === Schemas . vscodeNotebookCell ) ) {
402
- // if (this.editor.hasWidgetFocus()) {
403
- // ! WordHighlighter.query?.model.dispose();
404
- WordHighlighter . query = null ;
405
- }
406
-
407
409
// return if no model
408
410
if ( ! this . editor . hasModel ( ) ) {
409
411
return ;
@@ -455,9 +457,15 @@ class WordHighlighter {
455
457
// Remove any existing decorations + a possible query, and re - run to update decorations
456
458
this . _removeSingleDecorations ( ) ;
457
459
458
- // don't re-run notebooks
459
- if ( this . editor . getModel ( ) ?. uri . scheme !== Schemas . vscodeNotebookCell ) {
460
- this . _run ( ) ;
460
+ if ( this . editor . hasWidgetFocus ( ) ) {
461
+ if ( this . editor . getModel ( ) ?. uri . scheme !== Schemas . vscodeNotebookCell && WordHighlighter . query ?. modelInfo ?. model . uri . scheme !== Schemas . vscodeNotebookCell ) { // clear query if focused non-nb editor
462
+ WordHighlighter . query = null ;
463
+ this . _run ( ) ;
464
+ } else { // remove modelInfo to account for nb cell being disposed
465
+ if ( WordHighlighter . query ?. modelInfo ) {
466
+ WordHighlighter . query . modelInfo = null ;
467
+ }
468
+ }
461
469
}
462
470
463
471
// Cancel any renderDecorationsTimer
@@ -594,7 +602,6 @@ class WordHighlighter {
594
602
if ( ! this . editor . hasWidgetFocus ( ) ) { // no focus (new nb cell, etc)
595
603
if ( WordHighlighter . query === null ) {
596
604
// no previous query, nothing to highlight
597
- this . _stopAll ( ) ;
598
605
return ;
599
606
}
600
607
} else {
@@ -625,8 +632,10 @@ class WordHighlighter {
625
632
workerRequestIsValid = ( this . workerRequest && this . workerRequest . isValid ( this . model , editorSelection , this . decorations ) ) ;
626
633
627
634
WordHighlighter . query = {
628
- model : this . model ,
629
- selection : editorSelection ,
635
+ modelInfo : {
636
+ model : this . model ,
637
+ selection : editorSelection ,
638
+ } ,
630
639
word : word
631
640
} ;
632
641
}
@@ -660,13 +669,21 @@ class WordHighlighter {
660
669
661
670
const otherModelsToHighlight = this . getOtherModelsToHighlight ( this . editor . getModel ( ) ) ;
662
671
663
- if ( ! otherModelsToHighlight . length ) {
664
- this . workerRequest = computeOccurencesAtPosition ( this . providers , WordHighlighter . query . model , WordHighlighter . query . selection , this . editor . getOption ( EditorOption . wordSeparators ) ) ;
665
- } else {
666
- this . workerRequest = computeOccurencesMultiModel ( this . multiDocumentProviders , WordHighlighter . query . model , WordHighlighter . query . selection , this . editor . getOption ( EditorOption . wordSeparators ) , otherModelsToHighlight ) ;
672
+ // 2 cases where we want to send the word
673
+ // a) there is no stored query model, but there is a word. This signals the editor that drove the highlight is disposed (cell out of viewport, etc)
674
+ // b) the queried model is not the current model. This signals that the editor that drove the highlight is still in the viewport, but we are highlighting a different cell
675
+ // otherwise, we send null in place of the word, and the model and selection are used to compute the word
676
+ const sendWord = ( ! WordHighlighter . query . modelInfo && WordHighlighter . query . word ) ||
677
+ ( WordHighlighter . query . modelInfo ?. model . uri !== this . model . uri )
678
+ ? true : false ;
679
+
680
+ if ( ! WordHighlighter . query . modelInfo || ( WordHighlighter . query . modelInfo . model . uri !== this . model . uri ) ) { // use this.model
681
+ this . workerRequest = this . computeWithModel ( this . model , this . editor . getSelection ( ) , sendWord ? WordHighlighter . query . word : null , otherModelsToHighlight ) ;
682
+ } else { // use stored query model + selection
683
+ this . workerRequest = this . computeWithModel ( WordHighlighter . query . modelInfo . model , WordHighlighter . query . modelInfo . selection , WordHighlighter . query . word , otherModelsToHighlight ) ;
667
684
}
668
685
669
- this . workerRequest . result . then ( data => {
686
+ this . workerRequest ? .result . then ( data => {
670
687
if ( myRequestId === this . workerRequestTokenId ) {
671
688
this . workerRequestCompleted = true ;
672
689
this . workerRequestValue = data || [ ] ;
@@ -676,6 +693,14 @@ class WordHighlighter {
676
693
}
677
694
}
678
695
696
+ private computeWithModel ( model : ITextModel , selection : Selection , word : IWordAtPosition | null , otherModels : ITextModel [ ] ) : IOccurenceAtPositionRequest | null {
697
+ if ( ! otherModels . length ) {
698
+ return computeOccurencesAtPosition ( this . providers , model , selection , word , this . editor . getOption ( EditorOption . wordSeparators ) ) ;
699
+ } else {
700
+ return computeOccurencesMultiModel ( this . multiDocumentProviders , model , selection , word , this . editor . getOption ( EditorOption . wordSeparators ) , otherModels ) ;
701
+ }
702
+ }
703
+
679
704
private _beginRenderDecorations ( ) : void {
680
705
const currentTime = ( new Date ( ) ) . getTime ( ) ;
681
706
const minimumRenderTime = this . lastCursorPositionChangeTime + 250 ;
0 commit comments