From 96dbbcff3e25653a548c5333ef83238bb6742e2c Mon Sep 17 00:00:00 2001 From: michal Date: Mon, 19 Apr 2021 22:23:32 +0200 Subject: [PATCH] VIM-1476 Store last inserted text in ". register --- .../maddyhome/idea/vim/group/ChangeGroup.java | 65 ++++++++++++++----- .../ideavim/action/SpecialRegistersTest.java | 20 ++++-- 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/com/maddyhome/idea/vim/group/ChangeGroup.java b/src/com/maddyhome/idea/vim/group/ChangeGroup.java index e2b2b0659e..d34b2a8f28 100644 --- a/src/com/maddyhome/idea/vim/group/ChangeGroup.java +++ b/src/com/maddyhome/idea/vim/group/ChangeGroup.java @@ -196,7 +196,7 @@ public void insertNewLineAbove(final @NotNull Editor editor, @NotNull DataContex for (Caret caret : editor.getCaretModel().getAllCarets()) { if (firstLiners.contains(caret)) { - final int offset = VimPlugin.getMotion().moveCaretToLineEnd(editor, 0,true); + final int offset = VimPlugin.getMotion().moveCaretToLineEnd(editor, 0, true); MotionGroup.moveCaret(editor, caret, offset); } } @@ -323,7 +323,7 @@ public boolean insertRegister(@NotNull Editor editor, @NotNull DataContext conte final Register register = VimPlugin.getRegister().getRegister(key); if (register != null) { final List keys = register.getKeys(); - for (KeyStroke k:keys) { + for (KeyStroke k : keys) { processKey(editor, context, k); } return true; @@ -540,6 +540,10 @@ public void processEscape(@NotNull Editor editor, @Nullable DataContext context) repeatInsert(editor, context, cnt == 0 ? 0 : cnt - 1, true); } + if (CommandState.getInstance(editor).getMode() == CommandState.Mode.INSERT) { + updateLastInsertedTextRegister(); + } + // The change pos '.' mark is the offset AFTER processing escape, and after switching to overtype offset = editor.getCaretModel().getPrimaryCaret().getOffset(); markGroup.setMark(editor, MarkGroup.MARK_CHANGE_POS, offset); @@ -738,13 +742,15 @@ public boolean deleteCharacter(@NotNull Editor editor, @NotNull Caret caret, int final int pos = caret.getOffset(); final int norm = EditorHelper.normalizeOffset(editor, caret.getLogicalPosition().line, pos, isChange); - if (norm != pos || editor.offsetToVisualPosition(norm) != EditorUtil.inlayAwareOffsetToVisualPosition(editor, norm)) { + if (norm != pos || + editor.offsetToVisualPosition(norm) != EditorUtil.inlayAwareOffsetToVisualPosition(editor, norm)) { MotionGroup.moveCaret(editor, caret, norm); } // Always move the caret. Our position might or might not have changed, but an inlay might have been moved to our // location, or deleting the character(s) might have caused us to scroll sideways in long files. Moving the caret // will make sure it's in the right place, and visible - final int offset = EditorHelper.normalizeOffset(editor, caret.getLogicalPosition().line, caret.getOffset(), isChange); + final int offset = + EditorHelper.normalizeOffset(editor, caret.getLogicalPosition().line, caret.getOffset(), isChange); MotionGroup.moveCaret(editor, caret, offset); return res; @@ -990,7 +996,8 @@ private boolean deleteJoinNLines(@NotNull Editor editor, deleteText(editor, new TextRange(caret.getOffset(), offset), null); if (spaces && !hasTrailingWhitespace) { insertText(editor, caret, " "); - MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().getOffsetOfHorizontalMotion(editor, caret, -1, true)); + MotionGroup + .moveCaret(editor, caret, VimPlugin.getMotion().getOffsetOfHorizontalMotion(editor, caret, -1, true)); } } @@ -1177,7 +1184,8 @@ public boolean deleteRange(@NotNull Editor editor, if (res) { int pos = EditorHelper.normalizeOffset(editor, range.getStartOffset(), isChange); if (type == SelectionType.LINE_WISE) { - pos = VimPlugin.getMotion().moveCaretToLineWithStartOfLineOption(editor, editor.offsetToLogicalPosition(pos).line, caret); + pos = VimPlugin.getMotion() + .moveCaretToLineWithStartOfLineOption(editor, editor.offsetToLogicalPosition(pos).line, caret); } MotionGroup.moveCaret(editor, caret, pos); } @@ -1187,7 +1195,7 @@ public boolean deleteRange(@NotNull Editor editor, private boolean removeLastNewLine(@NotNull Editor editor, @NotNull TextRange range, @Nullable SelectionType type) { int endOffset = range.getEndOffset(); int fileSize = EditorHelperRt.getFileSize(editor); - if (endOffset > fileSize){ + if (endOffset > fileSize) { StrictMode.INSTANCE.fail("Incorrect offset. File size: " + fileSize + ", offset: " + endOffset); endOffset = fileSize; } @@ -1454,10 +1462,10 @@ private void changeCase(@NotNull Editor editor, int start, int end, char type) { /** * Deletes the range of text and enters insert mode * - * @param editor The editor to change - * @param caret The caret to be moved after range deletion - * @param range The range to change - * @param type The type of the range + * @param editor The editor to change + * @param caret The caret to be moved after range deletion + * @param range The range to change + * @param type The type of the range * @return true if able to delete the range, false if not */ public boolean changeRange(@NotNull Editor editor, @@ -1633,7 +1641,10 @@ public void insertText(@NotNull Editor editor, @NotNull Caret caret, @NotNull St insertText(editor, caret, caret.getOffset(), str); } - public void insertText(@NotNull Editor editor, @NotNull Caret caret, @NotNull LogicalPosition start, @NotNull String str) { + public void insertText(@NotNull Editor editor, + @NotNull Caret caret, + @NotNull LogicalPosition start, + @NotNull String str) { insertText(editor, caret, editor.logicalPositionToOffset(start), str); } @@ -1740,7 +1751,8 @@ public void indentRange(@NotNull Editor editor, if (!CommandStateHelper.inInsertMode(editor)) { if (!range.isMultiple()) { - MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineWithStartOfLineOption(editor, sline, caret)); + MotionGroup + .moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineWithStartOfLineOption(editor, sline, caret)); } else { MotionGroup.moveCaret(editor, caret, range.getStartOffset()); @@ -1875,8 +1887,8 @@ public boolean changeNumberVisualMode(final @NotNull Editor editor, boolean hex = nf.contains("hex"); boolean octal = nf.contains("octal"); - @NotNull List> - numberRanges = SearchHelper.findNumbersInRange(editor, selectedRange, alpha, hex, octal); + @NotNull List> numberRanges = + SearchHelper.findNumbersInRange(editor, selectedRange, alpha, hex, octal); List newNumbers = new ArrayList<>(); for (int i = 0; i < numberRanges.size(); i++) { @@ -1890,7 +1902,8 @@ public boolean changeNumberVisualMode(final @NotNull Editor editor, // Replace text bottom up. In other direction ranges will be desynchronized after inc numbers like 99 Pair rangeToReplace = numberRanges.get(i); String newNumber = newNumbers.get(i); - replaceText(editor, rangeToReplace.getFirst().getStartOffset(), rangeToReplace.getFirst().getEndOffset(), newNumber); + replaceText(editor, rangeToReplace.getFirst().getStartOffset(), rangeToReplace.getFirst().getEndOffset(), + newNumber); } InlayHelperKt.moveToInlayAwareOffset(caret, selectedRange.getStartOffset()); @@ -1916,7 +1929,8 @@ public boolean changeNumber(final @NotNull Editor editor, @NotNull Caret caret, final boolean hex = nf.contains("hex"); final boolean octal = nf.contains("octal"); - @Nullable Pair range = SearchHelper.findNumberUnderCursor(editor, caret, alpha, hex, octal); + @Nullable Pair range = + SearchHelper.findNumberUnderCursor(editor, caret, alpha, hex, octal); if (range == null) { logger.debug("no number on line"); return false; @@ -1966,7 +1980,9 @@ public void reset() { char ch = text.charAt(0); if (hex && SearchHelper.NumberType.HEX.equals(numberType)) { - if (!text.toLowerCase().startsWith(HEX_START)) throw new RuntimeException("Hex number should start with 0x: " + text); + if (!text.toLowerCase().startsWith(HEX_START)) { + throw new RuntimeException("Hex number should start with 0x: " + text); + } for (int i = text.length() - 1; i >= 2; i--) { int index = "abcdefABCDEF".indexOf(text.charAt(i)); if (index >= 0) { @@ -2047,6 +2063,19 @@ private void notifyListeners(Editor editor) { insertListeners.forEach(listener -> listener.insertModeStarted(editor)); } + private void updateLastInsertedTextRegister() { + StringBuilder textToPutRegister = new StringBuilder(); + if (lastStrokes != null) { + for (Object lastStroke : lastStrokes) { + if (lastStroke instanceof char[]) { + final char[] chars = (char[])lastStroke; + textToPutRegister.append(new String(chars)); + } + } + } + VimPlugin.getRegister().storeTextSpecial(RegisterGroup.LAST_INSERTED_TEXT_REGISTER, textToPutRegister.toString()); + } + private int oldOffset = -1; private class InsertActionsDocumentListener implements DocumentListener { diff --git a/test/org/jetbrains/plugins/ideavim/action/SpecialRegistersTest.java b/test/org/jetbrains/plugins/ideavim/action/SpecialRegistersTest.java index 152a244a0f..cc48d1e4be 100644 --- a/test/org/jetbrains/plugins/ideavim/action/SpecialRegistersTest.java +++ b/test/org/jetbrains/plugins/ideavim/action/SpecialRegistersTest.java @@ -176,25 +176,36 @@ public void testNumberedRegistersShifting() { public void testSearchRegisterAfterSearch() { configureByText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten\n"); enterSearch("three", true); - assertEquals("three",getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); + assertEquals("three", getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); } public void testSearchRegisterAfterSubstitute() { configureByText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten\n"); enterCommand("%s/three/3/g"); - assertEquals("three",getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); + assertEquals("three", getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); } public void testSearchRegisterAfterSearchRange() { configureByText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten\n"); enterCommand("/three/d"); - assertEquals("three",getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); + assertEquals("three", getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); } public void testSearchRegisterAfterMultipleSearchRanges() { configureByText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten\n"); enterCommand("/one/;/three/d"); - assertEquals("three",getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); + assertEquals("three", getRegisterText(RegisterGroup.LAST_SEARCH_REGISTER)); + } + + public void testLastInsertedTextRegister() { + configureByText(""); + + typeText(parseKeys("i", "abc", "")); + + assertEquals("abc", getRegisterText('.')); + + assertRegisterChanged(RegisterGroup.LAST_INSERTED_TEXT_REGISTER); + } private void assertRegisterChanged(char registerName) { @@ -214,4 +225,5 @@ private String getRegisterText(char registerName) { return register.getText(); } + }