in src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.kt [243:317]
override fun textChanged(e: DocumentEvent) {
try {
val editor: Editor = ijEditor ?: return
val labelText: String = myLabel.text // Either '/', '?' or ':'boolean searchCommand = false;
var searchCommand = false
var searchRange: LineRange? = null
var separator = labelText[0]
var searchText = text
if (labelText == ":") {
if (searchText.isEmpty()) return
val command = getIncsearchCommand(searchText) ?: return
searchCommand = true
searchText = ""
val argument = command.commandArgument
if (argument.length > 1) { // E.g. skip '/' in `:%s/`. `%` is range, `s` is command, `/` is argument
separator = argument[0]
searchText = argument.substring(1)
}
if (!searchText.isEmpty()) {
searchRange = command.getLineRangeSafe(IjVimEditor(editor))
}
if (searchText.isEmpty() || searchRange == null) {
// Reset back to the original search highlights after deleting a search from a substitution command.Or if
// there is no search range (because the user entered an invalid range, e.g. mark not set).
// E.g. Highlight `whatever`, type `:%s/foo` + highlight `foo`, delete back to `:%s/` and reset highlights
// back to `whatever`
VimPlugin.getSearch().resetIncsearchHighlights()
resetCaretOffset(editor)
return
}
}
// Get a snapshot of the count for the in progress command, and coerce it to 1. This value will include all
// count components - selecting register(s), operator and motions. E.g. `2"a3"b4"c5d6/` will return 720.
// If we're showing highlights for an Ex command like `:s`, the command builder will be empty, but we'll still
// get a valid value.
val count1 = max(
1, getInstance().keyHandlerState.editorCommandBuilder
.calculateCount0Snapshot()
)
if (labelText == "/" || labelText == "?" || searchCommand) {
val forwards = labelText != "?" // :s, :g, :v are treated as forwards
val patternEnd: Int = injector.searchGroup.findEndOfPattern(searchText, separator, 0)
val pattern = searchText.take(patternEnd)
VimPlugin.getEditor().closeEditorSearchSession(editor)
val matchOffset =
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) {
IjVimEditor(editor).exitVisualMode()
}
IjVimCaret(editor.caretModel.primaryCaret).moveToOffset(matchOffset)
} else {
resetCaretOffset(editor)
}
}
} catch (ex: Throwable) {
// Make sure the exception doesn't leak out of the handler, because it can break the text entry field and
// require the editor to be closed/reopened. The worst that will happen is no incsearch highlights
logger.error("Error while trying to show incsearch highlights", ex)
}
}