@@ -347,15 +347,16 @@ export function getSelectionState(host) {
347347 return state ? createSelectionState ( state ) : createEmptySelectionState ( ) ;
348348}
349349
350- export function setSelection ( host , start , end , revealSelection = true , focusEditor = true ) {
350+ export async function setSelection ( host , start , end , revealSelection = true , focusEditor = true ) {
351351 const state = hostStates . get ( host ) ;
352352 if ( ! state ) {
353353 return createEmptySelectionState ( ) ;
354354 }
355355
356356 applySelection ( state , start ?? 0 , end ?? 0 , revealSelection !== false , undefined , undefined , focusEditor !== false ) ;
357- notifySelectionChanged ( state , false ) ;
358- return createSelectionState ( state ) ;
357+ await waitForSelectionState ( state , start ?? 0 , end ?? 0 ) ;
358+ await notifySelectionChangedAsync ( state , false ) ;
359+ return await waitForSelectionState ( state , start ?? 0 , end ?? 0 ) ;
359360}
360361
361362export function setFindMatches ( host , matches , activeMatchIndex = - 1 ) {
@@ -519,11 +520,12 @@ function ensureHarness(options) {
519520 }
520521 : null ;
521522 } ,
522- setSelection : ( testId , start , end , revealSelection = true ) => {
523+ setSelection : async ( testId , start , end , revealSelection = true ) => {
523524 const state = getRequiredHarnessState ( testId ) ;
524525 applySelection ( state , start ?? 0 , end ?? 0 , revealSelection !== false ) ;
525- notifySelectionChanged ( state , false ) ;
526- return createSelectionState ( state ) ;
526+ await waitForSelectionState ( state , start ?? 0 , end ?? 0 ) ;
527+ await notifySelectionChangedAsync ( state , false ) ;
528+ return await waitForSelectionState ( state , start ?? 0 , end ?? 0 ) ;
527529 } ,
528530 centerSelectionLine : testId => {
529531 const state = getRequiredHarnessState ( testId ) ;
@@ -746,10 +748,14 @@ function onEditorContentChanged(state) {
746748}
747749
748750function notifySelectionChanged ( state , dismissMenus ) {
751+ void notifySelectionChangedAsync ( state , dismissMenus ) ;
752+ }
753+
754+ async function notifySelectionChangedAsync ( state , dismissMenus ) {
749755 syncProxyFromEditor ( state ) ;
750756 if ( ! state . suppressSelectionNotification ) {
751757 const selectionState = createSelectionState ( state ) ;
752- void state . dotNetRef . invokeMethodAsync (
758+ await state . dotNetRef . invokeMethodAsync (
753759 state . options . selectionChangedCallbackName ,
754760 selectionState . start ,
755761 selectionState . end ,
@@ -761,6 +767,42 @@ function notifySelectionChanged(state, dismissMenus) {
761767 }
762768}
763769
770+ function waitForAnimationFrames ( frameCount = 1 ) {
771+ return new Promise ( resolve => {
772+ const pump = remaining => {
773+ if ( remaining <= 0 ) {
774+ resolve ( ) ;
775+ return ;
776+ }
777+
778+ requestAnimationFrame ( ( ) => pump ( remaining - 1 ) ) ;
779+ } ;
780+
781+ pump ( frameCount ) ;
782+ } ) ;
783+ }
784+
785+ function selectionMatchesOffsets ( state , start , end ) {
786+ const selection = createSelectionState ( state ) ;
787+ const orderedStart = Math . min ( start , end ) ;
788+ const orderedEnd = Math . max ( start , end ) ;
789+ return Math . min ( selection . start , selection . end ) === orderedStart &&
790+ Math . max ( selection . start , selection . end ) === orderedEnd ;
791+ }
792+
793+ async function waitForSelectionState ( state , start , end ) {
794+ const attempts = 12 ;
795+ for ( let attempt = 0 ; attempt < attempts ; attempt ++ ) {
796+ if ( selectionMatchesOffsets ( state , start , end ) ) {
797+ return createSelectionState ( state ) ;
798+ }
799+
800+ await waitForAnimationFrames ( 2 ) ;
801+ }
802+
803+ return createSelectionState ( state ) ;
804+ }
805+
764806function notifyHistoryRequested ( state , command ) {
765807 void state . dotNetRef . invokeMethodAsync ( state . options . historyRequestedCallbackName , command ) ;
766808}
0 commit comments