diff --git a/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java b/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java index c39c3d5697..a2e5465fc2 100644 --- a/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java +++ b/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java @@ -330,10 +330,8 @@ protected void textChanged(@NotNull DocumentEvent e) { if (labelText.equals("/") || labelText.equals("?") || searchCommand) { final boolean forwards = !labelText.equals("?"); // :s, :g, :v are treated as forwards - final String pattern; - final CharPointer p = new CharPointer(searchText); - final CharPointer end = RegExp.skip_regexp(new CharPointer(searchText), separator, true); - pattern = p.substring(end.pointer() - p.pointer()); + int pattenEnd = injector.getSearchGroup().findEndOfPattern(searchText, separator, 0); + final String pattern = searchText.substring(0, pattenEnd); VimPlugin.getEditor().closeEditorSearchSession(editor); final int matchOffset = diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroup.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroup.kt index 029e25c7d5..e3c5f53315 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroup.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroup.kt @@ -142,6 +142,17 @@ public interface VimSearchGroup { */ public fun searchWord(editor: VimEditor, caret: ImmutableVimCaret, count: Int, whole: Boolean, dir: Direction): Int + /** + * If [command] contains a pattern, this function finds the end of it that is marked with [delimiter]. + * + * This is useful for commands like `:%s/123/321/s` to detect the end of `123` pattern. `/` will be a [delimiter]. + */ + public fun findEndOfPattern( + command: String, + delimiter: Char, + startIndex: Int = 0 + ): Int + /** * Parse and execute the substitute command * diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt index 4533a36553..fcab70a9b3 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt @@ -473,6 +473,36 @@ public abstract class VimSearchGroupBase : VimSearchGroup { return if (offset == -1) range.startOffset else offset } + public override fun findEndOfPattern( + command: String, + delimiter: Char, + startIndex: Int, + ): Int { + var magic = true + + var i = startIndex + while (i < command.length) { + // delimiter found + if (command[i] == delimiter) break + + // collection start found, ignore until end of collection + if (magic && command[i] == '[' || + !magic && command[i] == '\\' && i + 1 < command.length && command[i + 1] == '[') { + + i = findEndOfCollection(command, i) + // skip escaped char + } else if (command[i] == '\\' && i + 1 < command.length) { + i++ + // update magic + if (command[i] == 'v' || command[i] == 'm') magic = true + if (command[i] == 'V' || command[i] == 'M') magic = false + } + i++ + } + return i + } + + private fun findNextSearchForGn( editor: VimEditor, count: Int, @@ -526,35 +556,6 @@ public abstract class VimSearchGroupBase : VimSearchGroup { return offset } - private fun findEndOfPattern( - command: String, - delimiter: Char, - startIndex: Int = 0 - ): Int { - var magic = true - - var i = startIndex - while (i < command.length) { - // delimiter found - if (command[i] == delimiter) break - - // collection start found, ignore until end of collection - if (magic && command[i] == '[' || - !magic && command[i] == '\\' && i + 1 < command.length && command[i + 1] == '[') { - - i = findEndOfCollection(command, i) - // skip escaped char - } else if (command[i] == '\\' && i + 1 < command.length) { - i++ - // update magic - if (command[i] == 'v' || command[i] == 'm') magic = true - if (command[i] == 'V' || command[i] == 'M') magic = false - } - i++ - } - return i - } - private fun findEndOfCollection( command: String, startIndex: Int