mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-05-07 05:34:02 +02:00
Remove Visual when updating incsearch for a command
This commit is contained in:
parent
1f68b756d5
commit
308996c4c1
src
main/java/com/maddyhome/idea/vim/ui/ex
test/java/org/jetbrains/plugins/ideavim/group/search
vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper
@ -28,6 +28,7 @@ import com.maddyhome.idea.vim.api.VimCommandLineCaret;
|
||||
import com.maddyhome.idea.vim.api.VimEditor;
|
||||
import com.maddyhome.idea.vim.api.VimKeyGroupBase;
|
||||
import com.maddyhome.idea.vim.ex.ranges.LineRange;
|
||||
import com.maddyhome.idea.vim.helper.EngineModeExtensionsKt;
|
||||
import com.maddyhome.idea.vim.helper.SearchHighlightsHelper;
|
||||
import com.maddyhome.idea.vim.helper.UiHelper;
|
||||
import com.maddyhome.idea.vim.key.interceptors.VimInputInterceptor;
|
||||
@ -362,6 +363,15 @@ public class ExEntryPanel extends JPanel implements VimCommandLine {
|
||||
SearchHighlightsHelper.updateIncsearchHighlights(editor, pattern, count1, forwards, caretOffset,
|
||||
searchRange);
|
||||
if (matchOffset != -1) {
|
||||
// Moving the caret will update the Visual selection, which is only valid while performing a search. We want
|
||||
// to remove the Visual selection when the incsearch is for a command, as this is always unrelated to the
|
||||
// current selection.
|
||||
// E.g. `V/foo` should update the selection to the location of the search result. But `V` followed by
|
||||
// `:<C-U>%s/foo` should remove the selection first.
|
||||
// We're actually in Command-line with Visual pending. Exiting Visual replaces this with just Command-line
|
||||
if (searchCommand) {
|
||||
EngineModeExtensionsKt.exitVisualMode(new IjVimEditor(editor));
|
||||
}
|
||||
new IjVimCaret(editor.getCaretModel().getPrimaryCaret()).moveToOffset(matchOffset);
|
||||
}
|
||||
else {
|
||||
|
@ -987,4 +987,34 @@ class IncsearchTests : VimTestCase() {
|
||||
enterCommand("set hlsearch incsearch")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test incsearch removes Visual when searching with no Visual range`() {
|
||||
doTest(
|
||||
listOf("v", ":<C-U>%s/dolor"),
|
||||
"""
|
||||
|Lorem ipsum dolor sit amet,
|
||||
|consectetur adipiscing elit
|
||||
|Sed in orci mauris.
|
||||
|Cras id tellus in ex imperdiet egestas.
|
||||
""".trimMargin(),
|
||||
"""
|
||||
|Lorem ipsum ${c}dolor sit amet,
|
||||
|consectetur adipiscing elit
|
||||
|Sed in orci mauris.
|
||||
|Cras id tellus in ex imperdiet egestas.
|
||||
""".trimMargin(),
|
||||
Mode.CMD_LINE(Mode.NORMAL())
|
||||
) {
|
||||
enterCommand("set hlsearch incsearch")
|
||||
}
|
||||
assertSearchHighlights("dolor",
|
||||
"""
|
||||
|Lorem ipsum ‷dolor‴ sit amet,
|
||||
|consectetur adipiscing elit
|
||||
|Sed in orci mauris.
|
||||
|Cras id tellus in ex imperdiet egestas.
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
||||
import com.maddyhome.idea.vim.state.mode.Mode
|
||||
import com.maddyhome.idea.vim.state.mode.SelectionType
|
||||
import com.maddyhome.idea.vim.state.mode.inBlockSelection
|
||||
import com.maddyhome.idea.vim.state.mode.inCommandLineModeWithVisual
|
||||
import com.maddyhome.idea.vim.state.mode.inVisualMode
|
||||
import com.maddyhome.idea.vim.state.mode.selectionType
|
||||
|
||||
@ -26,7 +27,7 @@ fun VimEditor.exitVisualMode() {
|
||||
}
|
||||
nativeCarets().forEach(VimCaret::removeSelection)
|
||||
}
|
||||
if (inVisualMode) {
|
||||
if (inVisualMode || inCommandLineModeWithVisual) {
|
||||
vimLastSelectionType = selectionType
|
||||
injector.markService.setVisualSelectionMarks(this)
|
||||
nativeCarets().forEach { it.vimSelectionStartClear() }
|
||||
@ -34,9 +35,12 @@ fun VimEditor.exitVisualMode() {
|
||||
// We usually want to return to the mode that we were in before we started Visual. Typically, this will be NORMAL,
|
||||
// but can be INSERT for "Insert Visual" (`i<C-O>v`). For "Select Visual" (`gh<C-O>`) we can't return to SELECT,
|
||||
// because we've just removed the selection. We have to return to NORMAL.
|
||||
// We might also be in Visual while working with the command line, i.e. Command-line with Visual pending. In this
|
||||
// case, we need to get rid of Visual, but keep the Command-line
|
||||
val mode = this.mode
|
||||
this.mode = when {
|
||||
mode is Mode.VISUAL && mode.isSelectPending -> Mode.NORMAL()
|
||||
mode is Mode.CMD_LINE && mode.isVisualPending -> Mode.CMD_LINE(Mode.NORMAL())
|
||||
else -> mode.returnTo
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user