@@ -370,7 +370,7 @@ public void ViGlobMovement_EmptyBuffer_Defect1195()
370370 TestSetup ( KeyMode . Vi ) ;
371371
372372 TestMustDing ( "" , Keys (
373- _ . Escape , "W"
373+ _ . Escape , "W"
374374 ) ) ;
375375 }
376376
@@ -423,6 +423,11 @@ public void ViCursorMovement()
423423 [ SkippableFact ]
424424 public void ViGotoBrace ( )
425425 {
426+ // NOTE: When the input has unmatched braces, in order to avoid an
427+ // exception caused by AcceptLineImpl waiting for incomplete input,
428+ // the test needs to end with the Vi command "ddi" and assert that
429+ // the result is an empty string.
430+
426431 TestSetup ( KeyMode . Vi ) ;
427432
428433 Test ( "0[2(4{6]8)a}c" , Keys (
@@ -450,10 +455,60 @@ public void ViGotoBrace()
450455 CheckThat ( ( ) => AssertCursorLeftIs ( 4 ) ) ,
451456 _ . Percent ,
452457 CheckThat ( ( ) => AssertCursorLeftIs ( 4 ) ) ,
453- "ddi"
458+ "ddi" // Unmatched brace
454459 ) ) ;
455460 }
456461
462+ // Tests when the cursor is not on any paren
463+ foreach ( var ( opening , closing ) in new [ ] { ( '(' , ')' ) , ( '{' , '}' ) , ( '[' , ']' ) } )
464+ {
465+ // Closing paren with backward match
466+ string input1 = $ "0{ opening } 2{ opening } 4foo{ closing } ";
467+ Test ( "" , Keys (
468+ input1 ,
469+ CheckThat ( ( ) => AssertCursorLeftIs ( 9 ) ) ,
470+ _ . Escape , CheckThat ( ( ) => AssertCursorLeftIs ( 8 ) ) ,
471+ "0ff" , CheckThat ( ( ) => AssertCursorLeftIs ( 5 ) ) ,
472+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 3 ) ) ,
473+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 8 ) ) ,
474+ "ddi" // Unmatched closing brace
475+ ) ) ;
476+
477+ // Closing paren without backward match
478+ string input2 = $ "0]2)4foo{ closing } ";
479+ TestMustDing ( input2 , Keys (
480+ input2 ,
481+ CheckThat ( ( ) => AssertCursorLeftIs ( 9 ) ) ,
482+ _ . Escape , CheckThat ( ( ) => AssertCursorLeftIs ( 8 ) ) ,
483+ "0ff" , CheckThat ( ( ) => AssertCursorLeftIs ( 5 ) ) ,
484+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 5 ) ) , // stay still
485+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 5 ) )
486+ ) ) ;
487+
488+ // Opening paren with forward match
489+ string input3 = $ "0{ opening } 2foo6{ closing } ";
490+ Test ( input3 , Keys (
491+ input3 ,
492+ CheckThat ( ( ) => AssertCursorLeftIs ( 8 ) ) ,
493+ _ . Escape , CheckThat ( ( ) => AssertCursorLeftIs ( 7 ) ) ,
494+ "0ff" , CheckThat ( ( ) => AssertCursorLeftIs ( 3 ) ) ,
495+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 1 ) ) ,
496+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 7 ) )
497+ ) ) ;
498+
499+ // Opening paren without forward match
500+ string input4 = $ "0)2]4foo{ opening } (";
501+ TestMustDing ( "" , Keys (
502+ input4 ,
503+ CheckThat ( ( ) => AssertCursorLeftIs ( 10 ) ) ,
504+ _ . Escape , CheckThat ( ( ) => AssertCursorLeftIs ( 9 ) ) ,
505+ "0ff" , CheckThat ( ( ) => AssertCursorLeftIs ( 5 ) ) ,
506+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 5 ) ) , // stay still
507+ _ . Percent , CheckThat ( ( ) => AssertCursorLeftIs ( 5 ) ) ,
508+ "ddi" // Unmatched brace
509+ ) ) ;
510+ }
511+
457512 // <%> with empty text buffer should work fine.
458513 Test ( "" , Keys (
459514 _ . Escape , _ . Percent ,
0 commit comments