@@ -1470,6 +1470,10 @@ - (void)testIPCSelectedText {
14701470 NSString *regcontents = [vc evaluateVimExpression: @" getreg()" ];
14711471 XCTAssertEqualObjects (regcontents, @" abcd\n " );
14721472
1473+ // Visual mode
1474+
1475+ NSString *changedtick1 = [vc evaluateVimExpression: @" b:changedtick" ];
1476+
14731477 // Get selected texts in visual mode
14741478 XCTAssertFalse ([vc hasSelectedText ]);
14751479 XCTAssertNil ([vc selectedText ]);
@@ -1491,30 +1495,79 @@ - (void)testIPCSelectedText {
14911495 XCTAssertEqualObjects ([vc selectedText ], @" bc\n fg" );
14921496
14931497 // Set selected texts in visual block mode
1494- NSString *changedtick = [vc evaluateVimExpression: @" b:changedtick" ];
1495- [vc replaceSelectedText: @" xyz\n 1234" ];
1496- NSString *changedtick2 = [vc evaluateVimExpression: @" b:changedtick" ];
1498+ [vc insertOrReplaceSelectedText: @" xyz\n 1234" ];
14971499 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(1)" ], @" axyz d" );
14981500 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(2)" ], @" e1234h" );
14991501 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(3)" ], @" ijkl" );
1500- XCTAssertNotEqualObjects (changedtick, changedtick2);
1501-
1502- // Make sure replacing texts when nothing is selected won't set anything
1503- [vc replaceSelectedText: @" foobar" ];
1504- NSString *changedtick3 = [vc evaluateVimExpression: @" b:changedtick" ];
1505- XCTAssertEqualObjects (changedtick2, changedtick3);
15061502
15071503 // Select in visual block again but send a different number of lines, make sure we intentionaly won't treat it as block text
15081504 [self sendStringToVim: @" ggjjvll" withMods: 0 ];
15091505 [self sendKeyToVim: @" v" withMods: NSEventModifierFlagControl];
15101506 [self waitForEventHandlingAndVimProcess ];
1511- [vc replaceSelectedText :@" xyz\n 1234\n " ]; // ending in newline means it gets interpreted as line-wise
1507+ [vc insertOrReplaceSelectedText :@" xyz\n 1234\n " ]; // ending in newline means it gets interpreted as line-wise
15121508 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(1)" ], @" axyz d" );
15131509 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(2)" ], @" e1234h" );
15141510 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(3)" ], @" xyz" );
15151511 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(4)" ], @" 1234" );
15161512 XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(5)" ], @" l" );
15171513
1514+ // Normal mode
1515+
1516+ // When nothing is selected this will simply insert the text and not replace anything
1517+ [self sendStringToVim: @" ggll" withMods: 0 ];
1518+ [self waitForEventHandlingAndVimProcess ];
1519+ [vc insertOrReplaceSelectedText: @" _normtext_" ];
1520+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(1)" ], @" ax_normtext_yz d" );
1521+
1522+ // Insert mode
1523+
1524+ [self sendStringToVim: @" ggjja" withMods: 0 ];
1525+ [self waitForEventHandlingAndVimProcess ];
1526+ // Should insert the text at the cursor
1527+ [vc insertOrReplaceSelectedText: @" _inserttext_" ];
1528+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(3)" ], @" x_inserttext_yz" );
1529+ // Should leave the cursor past the inserted text
1530+ [self sendStringToVim: @" additional_text" withMods: 0 ];
1531+ [self waitForEventHandlingAndVimProcess ];
1532+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getline(3)" ], @" x_inserttext_additional_textyz" );
1533+ [self sendKeyToVim: @" [" withMods: NSEventModifierFlagControl]; // escape insert mode
1534+ [self waitForEventHandlingAndVimProcess ];
1535+
1536+ // Cmdline mode
1537+
1538+ NSString *changedtick2 = [vc evaluateVimExpression: @" b:changedtick" ];
1539+ XCTAssertNotEqualObjects (changedtick1, changedtick2);
1540+
1541+ [self sendStringToVim: @" :cnoremap z <Left>\n " withMods: 0 ];
1542+ [self sendStringToVim: @" :123" withMods: 0 ];
1543+ [self waitForEventHandlingAndVimProcess ];
1544+ [vc insertOrReplaceSelectedText: @" a\n b\n " ];
1545+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getcmdline()" ], @" 123a\r b\r " ); // Vim does internal \n to \r conversion
1546+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getcmdpos()" ], @" 8" );
1547+ [self sendKeyToVim: @" [" withMods: NSEventModifierFlagControl]; // escape cmdline
1548+ [self waitForEventHandlingAndVimProcess ];
1549+
1550+ [self sendStringToVim: @" :123zzz" withMods: 0 ];
1551+ [self waitForEventHandlingAndVimProcess ];
1552+ [vc insertOrReplaceSelectedText: @" foobar" ];
1553+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getcmdline()" ], @" foobar123" );
1554+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getcmdpos()" ], @" 7" );
1555+ [self sendKeyToVim: @" [" withMods: NSEventModifierFlagControl]; // escape cmdline
1556+
1557+ [self waitForEventHandlingAndVimProcess ];
1558+ [self sendStringToVim: @" :123z" withMods: 0 ];
1559+ [self waitForEventHandlingAndVimProcess ];
1560+ [vc insertOrReplaceSelectedText: @" foobar" ];
1561+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getcmdline()" ], @" 12foobar3" );
1562+ XCTAssertEqualObjects ([vc evaluateVimExpression: @" getcmdpos()" ], @" 9" );
1563+ [self sendKeyToVim: @" [" withMods: NSEventModifierFlagControl]; // escape cmdline
1564+ [self waitForEventHandlingAndVimProcess ];
1565+
1566+ // Make sure that the actual buffer wasn't changed at all during these insertions as they all
1567+ // went to the cmdline.
1568+ NSString *changedtick3 = [vc evaluateVimExpression: @" b:changedtick" ];
1569+ XCTAssertEqualObjects (changedtick2, changedtick3);
1570+
15181571 // Make sure registers didn't get stomped (internally the implementation uses register and manually restores it)
15191572 regcontents = [[app keyVimController ] evaluateVimExpression: @" getreg()" ];
15201573 XCTAssertEqualObjects (regcontents, @" abcd\n " );
0 commit comments