@@ -72,9 +72,9 @@ export class MonacoEditor extends React.Component<IMonacoEditorProps, IMonacoEdi
72
72
private styleObserver : MutationObserver | undefined ;
73
73
private watchingMargin : boolean = false ;
74
74
private throttledUpdateWidgetPosition = throttle ( this . updateWidgetPosition . bind ( this ) , 100 ) ;
75
- private throttledScrollOntoScreen = throttle ( this . scrollOntoScreen . bind ( this ) , 100 ) ;
75
+ private throttledScrollCurrentPosition = throttle ( this . scrollToCurrentPosition . bind ( this ) , 100 ) ;
76
76
private monacoContainer : HTMLDivElement | undefined ;
77
- private lineTops : number [ ] = [ ] ;
77
+ private lineTops : { top : number ; index : number } [ ] = [ ] ;
78
78
private debouncedComputeLineTops = debounce ( this . computeLineTops . bind ( this ) , 100 ) ;
79
79
80
80
/**
@@ -192,13 +192,17 @@ export class MonacoEditor extends React.Component<IMonacoEditorProps, IMonacoEdi
192
192
this . throttledUpdateWidgetPosition ( ) ;
193
193
this . updateWidgetParent ( editor ) ;
194
194
this . hideAllOtherHoverAndParameterWidgets ( ) ;
195
- this . throttledScrollOntoScreen ( editor ) ;
195
+
196
+ // Also update our scroll position, but do that after focus is established.
197
+ // This is necessary so that markdown can switch to edit mode before we
198
+ // try to scroll to it.
199
+ setTimeout ( ( ) => this . throttledScrollCurrentPosition ( editor ) , 0 ) ;
196
200
} ) ) ;
197
201
198
202
// Track cursor changes and make sure line is on the screen
199
203
this . subscriptions . push ( editor . onDidChangeCursorPosition ( ( ) => {
200
204
this . throttledUpdateWidgetPosition ( ) ;
201
- this . throttledScrollOntoScreen ( editor ) ;
205
+ this . throttledScrollCurrentPosition ( editor ) ;
202
206
} ) ) ;
203
207
204
208
// Update our margin to include the correct line number style
@@ -311,6 +315,14 @@ export class MonacoEditor extends React.Component<IMonacoEditorProps, IMonacoEdi
311
315
}
312
316
313
317
public getCurrentVisibleLine ( ) : number | undefined {
318
+ return this . getCurrentVisibleLinePosOrIndex ( ( pos , _i ) => pos ) ;
319
+ }
320
+
321
+ public getVisibleLineCount ( ) : number {
322
+ return this . getVisibleLines ( ) . length ;
323
+ }
324
+
325
+ private getCurrentVisibleLinePosOrIndex ( pickResult : ( pos : number , index : number ) => number ) : number | undefined {
314
326
// Convert the current cursor into a top and use that to find which visible
315
327
// line it is in.
316
328
if ( this . state . editor ) {
@@ -320,16 +332,16 @@ export class MonacoEditor extends React.Component<IMonacoEditorProps, IMonacoEdi
320
332
const count = this . getVisibleLineCount ( ) ;
321
333
const lineTops = count === this . lineTops . length ? this . lineTops : this . computeLineTops ( ) ;
322
334
for ( let i = 0 ; i < count ; i += 1 ) {
323
- if ( top <= lineTops [ i ] ) {
324
- return i ;
335
+ if ( top <= lineTops [ i ] . top ) {
336
+ return pickResult ( i , lineTops [ i ] . index ) ;
325
337
}
326
338
}
327
339
}
328
340
}
329
341
}
330
342
331
- public getVisibleLineCount ( ) : number {
332
- return this . getVisibleLines ( ) . length ;
343
+ private getCurrentVisibleLineIndex ( ) : number | undefined {
344
+ return this . getCurrentVisibleLinePosOrIndex ( ( _pos , i ) => i ) ;
333
345
}
334
346
335
347
private getVisibleLines ( ) : HTMLDivElement [ ] {
@@ -343,23 +355,24 @@ export class MonacoEditor extends React.Component<IMonacoEditorProps, IMonacoEdi
343
355
return [ ] ;
344
356
}
345
357
346
- private computeLineTops ( ) : number [ ] {
358
+ private computeLineTops ( ) {
347
359
const lines = this . getVisibleLines ( ) ;
348
360
349
361
// Lines are not sorted by monaco, so we have to sort them by their top value
350
- this . lineTops = lines . map ( l => {
362
+ this . lineTops = lines . map ( ( l , i ) => {
351
363
const match = l . style . top ? / ( .+ ) p x / . exec ( l . style . top ) : null ;
352
- return match ? parseInt ( match [ 0 ] , 10 ) : Infinity ;
353
- } ) . sort ( ( a , b ) => a - b ) ;
364
+ return { top : match ? parseInt ( match [ 0 ] , 10 ) : Infinity , index : i } ;
365
+ } ) . sort ( ( a , b ) => a . top - b . top ) ;
354
366
return this . lineTops ;
355
367
}
356
368
357
- private scrollOntoScreen ( _editor : monacoEditor . editor . IStandaloneCodeEditor ) {
358
- // Scroll to the visible line that has our current line
369
+ private scrollToCurrentPosition ( _editor : monacoEditor . editor . IStandaloneCodeEditor ) {
370
+ // Scroll to the visible line that has our current line. Note: Visible lines are not sorted by monaco
371
+ // so we have to retrieve the current line's index (not its visible position)
359
372
const visibleLineDivs = this . getVisibleLines ( ) ;
360
- const current = this . getCurrentVisibleLine ( ) ;
373
+ const current = this . getCurrentVisibleLineIndex ( ) ;
361
374
if ( current !== undefined && current >= 0 && visibleLineDivs [ current ] . scrollIntoView ) {
362
- visibleLineDivs [ current ] . scrollIntoView ( { behavior : 'auto ' , block : 'nearest' , inline : 'nearest' } ) ;
375
+ visibleLineDivs [ current ] . scrollIntoView ( { behavior : 'smooth ' , block : 'nearest' , inline : 'nearest' } ) ;
363
376
}
364
377
}
365
378
0 commit comments