in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimSearchGroupBase.kt [576:667]
override fun processSubstituteCommand(
editor: VimEditor,
caret: VimCaret,
context: ExecutionContext,
range: LineRange,
excmd: String,
exarg: String,
parent: VimLContext,
): Boolean {
// Explicitly exit visual mode here, so that visual mode marks don't change when we move the cursor to a match.
val exceptions: MutableList<ExException> = ArrayList()
if (editor.inVisualMode) editor.exitVisualMode()
// Parse Ex command and arguments to extract the pattern, substitute string, and line range
val substituteCommandParse = parseSubstituteCommand(editor, range, excmd, exarg) ?: return false
val pattern = substituteCommandParse.pattern
val substituteString = substituteCommandParse.substituteString
val line1 = substituteCommandParse.range.startLine
val line2 = substituteCommandParse.range.endLine
val options = enumSetOf<VimRegexOptions>()
if (injector.globalOptions().smartcase) options.add(VimRegexOptions.SMART_CASE)
if (injector.globalOptions().ignorecase) options.add(VimRegexOptions.IGNORE_CASE)
val regex: VimRegex = try {
VimRegex(pattern)
} catch (e: VimRegexException) {
injector.messages.showStatusBarMessage(editor, e.message)
return false
}
val hasExpression = substituteString.length >= 2 && substituteString[0] == '\\' && substituteString[1] == '='
val oldLastSubstituteString: String = lastSubstituteString ?: ""
if (substituteString != "~") {
lastSubstituteString = substituteString
}
setShouldShowSearchHighlights()
updateSearchHighlights(true)
if (!doAsk) {
performSubstituteInLines(
editor,
caret,
context,
parent,
regex,
pattern,
oldLastSubstituteString,
line1,
line2,
0,
hasExpression,
substituteString,
exceptions,
options
)
} else {
val lineToNextSubstitute = getNextSubstitute(
editor,
regex,
oldLastSubstituteString,
line1,
line2,
0,
hasExpression,
substituteString,
options
)
if (lineToNextSubstitute == null) {
injector.messages.indicateError()
injector.messages.showStatusBarMessage(null, "E486: Pattern not found: $pattern")
return true
}
val (line, nextSubstitute) = lineToNextSubstitute
val matchRange = nextSubstitute.first.range
caret.moveToOffset(matchRange.startOffset)
val highlight = addSubstitutionConfirmationHighlight(editor, matchRange.startOffset, matchRange.endOffset)
injector.modalInput.create(
editor, context, injector.messages.message("command.substitute.replace.with.prompt", lineToNextSubstitute.second.second),
SubstituteWithAskInputInterceptor(
editor, caret, nextSubstitute, highlight, line, 0, parent, pattern, regex,
oldLastSubstituteString, line2, hasExpression, substituteString, options,
-1, mutableListOf(),
)
)
}
// TODO: Support reporting number of changes (:help 'report')
return true
}