From c0e17a6c61d558e033e264ea507d0b24d2e85190 Mon Sep 17 00:00:00 2001 From: Matt Ellis <m.t.ellis@gmail.com> Date: Sat, 26 Nov 2022 14:03:29 +0000 Subject: [PATCH] Fix issue with lastColumn not being invalidated --- .../com/maddyhome/idea/vim/EventFacade.java | 10 +++++++++ .../idea/vim/helper/UserDataManager.kt | 4 +++- .../idea/vim/listener/VimListenerManager.kt | 9 ++++++++ .../leftright/MotionLastColumnActionTest.kt | 22 +++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/maddyhome/idea/vim/EventFacade.java b/src/main/java/com/maddyhome/idea/vim/EventFacade.java index f301db34f..f08149a91 100644 --- a/src/main/java/com/maddyhome/idea/vim/EventFacade.java +++ b/src/main/java/com/maddyhome/idea/vim/EventFacade.java @@ -92,6 +92,16 @@ public class EventFacade { EditorFactory.getInstance().addEditorFactoryListener(listener, parentDisposable); } + public void addCaretListener(@NotNull Editor editor, + @NotNull CaretListener listener, + @NotNull Disposable disposable) { + editor.getCaretModel().addCaretListener(listener, disposable); + } + + public void removeCaretListener(@NotNull Editor editor, @NotNull CaretListener listener) { + editor.getCaretModel().removeCaretListener(listener); + } + public void addEditorMouseListener(@NotNull Editor editor, @NotNull EditorMouseListener listener, @NotNull Disposable disposable) { diff --git a/src/main/java/com/maddyhome/idea/vim/helper/UserDataManager.kt b/src/main/java/com/maddyhome/idea/vim/helper/UserDataManager.kt index 688afdebe..eee34c137 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/UserDataManager.kt +++ b/src/main/java/com/maddyhome/idea/vim/helper/UserDataManager.kt @@ -63,7 +63,9 @@ private var Caret._vimSelectionStart: Int? by userDataCaretToEditor() // Keep a track of the column that we intended to navigate to but were unable to. This might be because of inlays, // virtual indent or moving from the end of a long line to the end of a short line. Keep a track of the position when -// the value is set, if it's not the same during get, we've been moved by IJ and so no longer valid +// the value is set, if it's not the same during get, we've been moved by IJ and so no longer valid. We also invalidate +// the cached value through a caret listener handler, to prevent issues with the caret being moved and returned before +// the cache is checked/invalidated var Caret.vimLastColumn: Int get() { if (visualPosition != _vimLastColumnPos) { diff --git a/src/main/java/com/maddyhome/idea/vim/listener/VimListenerManager.kt b/src/main/java/com/maddyhome/idea/vim/listener/VimListenerManager.kt index 80dcd6f9f..f9e020dab 100644 --- a/src/main/java/com/maddyhome/idea/vim/listener/VimListenerManager.kt +++ b/src/main/java/com/maddyhome/idea/vim/listener/VimListenerManager.kt @@ -62,6 +62,7 @@ import com.maddyhome.idea.vim.helper.isEndAllowed import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere import com.maddyhome.idea.vim.helper.localEditors import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset +import com.maddyhome.idea.vim.helper.resetVimLastColumn import com.maddyhome.idea.vim.helper.subMode import com.maddyhome.idea.vim.helper.updateCaretsVisualAttributes import com.maddyhome.idea.vim.helper.vimDisabled @@ -157,6 +158,7 @@ object VimListenerManager { eventFacade.addEditorMouseMotionListener(editor, EditorMouseHandler, disposable) eventFacade.addEditorSelectionListener(editor, EditorSelectionHandler, disposable) eventFacade.addComponentMouseListener(editor.contentComponent, ComponentMouseListener, disposable) + eventFacade.addCaretListener(editor, EditorCaretHandler, disposable) VimPlugin.getEditor().editorCreated(editor) @@ -175,6 +177,7 @@ object VimListenerManager { eventFacade.removeEditorMouseMotionListener(editor, EditorMouseHandler) eventFacade.removeEditorSelectionListener(editor, EditorSelectionHandler) eventFacade.removeComponentMouseListener(editor.contentComponent, ComponentMouseListener) + eventFacade.removeCaretListener(editor, EditorCaretHandler) VimPlugin.getEditorIfCreated()?.editorDeinit(editor, isReleased) @@ -494,6 +497,12 @@ object VimListenerManager { } } + private object EditorCaretHandler : CaretListener { + override fun caretPositionChanged(event: CaretEvent) { + event.caret?.resetVimLastColumn() + } + } + enum class SelectionSource { MOUSE, OTHER diff --git a/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionLastColumnActionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionLastColumnActionTest.kt index 3e23a0204..902077ef1 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionLastColumnActionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionLastColumnActionTest.kt @@ -80,6 +80,28 @@ class MotionLastColumnActionTest : VimTestCase() { doTest(keys, before, after, VimStateMachine.Mode.VISUAL, VimStateMachine.SubMode.VISUAL_BLOCK) } + fun `test dollar motion resets intended location after motion`() { + doTest( + "\$hlj", + """ + A Discovery + + I ${c}found it in a legendary land + all rocks and lavender and tufted grass,[ additional symbols] + where it was settled on some sodden sand + hard by the torrent of a mountain pass. + """.trimIndent(), + """ + A Discovery + + I found it in a legendary land + all rocks and lavender and tu${c}fted grass,[ additional symbols] + where it was settled on some sodden sand + hard by the torrent of a mountain pass. + """.trimIndent() + ) + } + @VimBehaviorDiffers( originalVimAfter = """ A Discovery