diff --git a/src/main/kotlin/org/acejump/action/AceEditorAction.kt b/src/main/kotlin/org/acejump/action/AceEditorAction.kt index ac0f544..b322972 100644 --- a/src/main/kotlin/org/acejump/action/AceEditorAction.kt +++ b/src/main/kotlin/org/acejump/action/AceEditorAction.kt @@ -5,10 +5,10 @@ import com.intellij.openapi.editor.Caret import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.actionSystem.EditorActionHandler import org.acejump.boundaries.StandardBoundaries +import org.acejump.interact.VisitDirection import org.acejump.search.Pattern import org.acejump.session.Session import org.acejump.session.SessionManager -import org.acejump.session.mode.VisitDirection /** * Base class for keyboard-activated overrides of existing editor actions, that have a different meaning during an AceJump [Session]. diff --git a/src/main/kotlin/org/acejump/action/AceKeyboardAction.kt b/src/main/kotlin/org/acejump/action/AceKeyboardAction.kt index ee35f14..bb9ff7a 100644 --- a/src/main/kotlin/org/acejump/action/AceKeyboardAction.kt +++ b/src/main/kotlin/org/acejump/action/AceKeyboardAction.kt @@ -5,11 +5,11 @@ import com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR import com.intellij.openapi.project.DumbAwareAction import org.acejump.boundaries.Boundaries import org.acejump.boundaries.StandardBoundaries +import org.acejump.interact.mode.DefaultMode +import org.acejump.interact.mode.MultiCaretMode import org.acejump.search.Pattern import org.acejump.session.Session import org.acejump.session.SessionManager -import org.acejump.session.mode.MultiCaretSessionMode -import org.acejump.session.mode.SingleCaretSessionMode /** * Base class for keyboard-activated actions that create or update an AceJump [Session]. @@ -36,14 +36,14 @@ sealed class AceKeyboardAction : DumbAwareAction() { * Starts or ends an AceJump session. */ object ActivateAceJump : AceKeyboardAction() { - override fun invoke(session: Session) = session.setMode(SingleCaretSessionMode()) + override fun invoke(session: Session) = session.toggleMode(DefaultMode) } /** * Starts or ends an AceJump session in multicaret mode. */ object ActivateAceJumpMultiCaret : AceKeyboardAction() { - override fun invoke(session: Session) = session.setMode(MultiCaretSessionMode()) + override fun invoke(session: Session) = session.toggleMode(MultiCaretMode()) } // @formatter:off diff --git a/src/main/kotlin/org/acejump/action/AceTagAction.kt b/src/main/kotlin/org/acejump/action/AceTagAction.kt index a120948..c398acd 100644 --- a/src/main/kotlin/org/acejump/action/AceTagAction.kt +++ b/src/main/kotlin/org/acejump/action/AceTagAction.kt @@ -7,8 +7,10 @@ import com.intellij.find.actions.FindUsagesAction import com.intellij.find.actions.ShowUsagesAction import com.intellij.openapi.actionSystem.ActionManager import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.command.UndoConfirmationPolicy +import com.intellij.openapi.command.WriteCommandAction import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.actionSystem.DocCommandGroupId @@ -196,6 +198,89 @@ internal sealed class AceTagAction { } } + object SelectQuery : AceTagAction() { + override fun invoke(editor: Editor, searchProcessor: SearchProcessor, offset: Int, shiftMode: Boolean) { + recordCaretPosition(editor) + + val startOffset = JumpToSearchStart.getCaretOffset(editor, searchProcessor, offset) + val endOffset = JumpPastSearchEnd.getCaretOffset(editor, searchProcessor, offset) + + selectRange(editor, startOffset, endOffset) + } + } + + object SelectWord : AceTagAction() { + override fun invoke(editor: Editor, searchProcessor: SearchProcessor, offset: Int, shiftMode: Boolean) { + val chars = editor.immutableText + val queryEndOffset = JumpToSearchEnd.getCaretOffset(editor, searchProcessor, offset) + + if (chars[queryEndOffset].isWordPart) { + recordCaretPosition(editor) + + val startOffset = JumpToWordStartTag.getCaretOffset(editor, offset, queryEndOffset, isInsideWord = true) + val endOffset = JumpToWordEndTag.getCaretOffset(editor, offset, queryEndOffset, isInsideWord = true) + + selectRange(editor, startOffset, endOffset) + } + else { + SelectQuery(editor, searchProcessor, offset, shiftMode) + } + } + } + + object SelectHump : AceTagAction() { + override fun invoke(editor: Editor, searchProcessor: SearchProcessor, offset: Int, shiftMode: Boolean) { + val chars = editor.immutableText + val queryEndOffset = JumpToSearchEnd.getCaretOffset(editor, searchProcessor, offset) + + if (chars[queryEndOffset].isWordPart) { + recordCaretPosition(editor) + + val startOffset = chars.humpStart(queryEndOffset) + val endOffset = chars.humpEnd(queryEndOffset) + 1 + + selectRange(editor, startOffset, endOffset) + } + else { + SelectQuery(editor, searchProcessor, offset, shiftMode) + } + } + } + + object SelectLine : AceTagAction() { + override fun invoke(editor: Editor, searchProcessor: SearchProcessor, offset: Int, shiftMode: Boolean) { + JumpToSearchEnd(editor, searchProcessor, offset, shiftMode = false) + editor.selectionModel.selectLineAtCaret() + } + } + + class SelectExtended(private val extendCount: Int) : AceTagAction() { + override fun invoke(editor: Editor, searchProcessor: SearchProcessor, offset: Int, shiftMode: Boolean) { + JumpToSearchEnd(editor, searchProcessor, offset, shiftMode = false) + + val action = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET) + + repeat(extendCount) { + performAction(action) + } + } + } + + class Delete(private val selector: AceTagAction) : AceTagAction() { + override fun invoke(editor: Editor, searchProcessor: SearchProcessor, offset: Int, shiftMode: Boolean) { + val oldCarets = editor.caretModel.caretsAndSelections + + selector(editor, searchProcessor, offset, shiftMode) + WriteCommandAction.writeCommandAction(editor.project).withName("AceJump Delete").run<Throwable> { + editor.selectionModel.let { editor.document.deleteString(it.selectionStart, it.selectionEnd) } + } + + if (shiftMode) { + editor.caretModel.caretsAndSelections = oldCarets + } + } + } + /** * On default action, performs the Go To Declaration action, available via `Navigate | Declaration or Usages`. * On shift action, performs the Go To Type Declaration action, available via `Navigate | Type Declaration`. diff --git a/src/main/kotlin/org/acejump/session/mode/TypeResult.kt b/src/main/kotlin/org/acejump/interact/TypeResult.kt similarity index 66% rename from src/main/kotlin/org/acejump/session/mode/TypeResult.kt rename to src/main/kotlin/org/acejump/interact/TypeResult.kt index 920d1d1..48b2bae 100644 --- a/src/main/kotlin/org/acejump/session/mode/TypeResult.kt +++ b/src/main/kotlin/org/acejump/interact/TypeResult.kt @@ -1,10 +1,12 @@ -package org.acejump.session.mode +package org.acejump.interact +import org.acejump.session.SessionMode import org.acejump.session.SessionSnapshot sealed class TypeResult { object Nothing : TypeResult() object UpdateResults : TypeResult() class LoadSnapshot(val snapshot: SessionSnapshot) : TypeResult() + class ChangeMode(val mode: SessionMode) : TypeResult() object EndSession : TypeResult() } diff --git a/src/main/kotlin/org/acejump/session/mode/VisitDirection.kt b/src/main/kotlin/org/acejump/interact/VisitDirection.kt similarity index 61% rename from src/main/kotlin/org/acejump/session/mode/VisitDirection.kt rename to src/main/kotlin/org/acejump/interact/VisitDirection.kt index b900eb3..29e1b75 100644 --- a/src/main/kotlin/org/acejump/session/mode/VisitDirection.kt +++ b/src/main/kotlin/org/acejump/interact/VisitDirection.kt @@ -1,4 +1,4 @@ -package org.acejump.session.mode +package org.acejump.interact enum class VisitDirection { BACKWARD, diff --git a/src/main/kotlin/org/acejump/session/mode/VisitResult.kt b/src/main/kotlin/org/acejump/interact/VisitResult.kt similarity index 82% rename from src/main/kotlin/org/acejump/session/mode/VisitResult.kt rename to src/main/kotlin/org/acejump/interact/VisitResult.kt index eaad3c1..5e0619d 100644 --- a/src/main/kotlin/org/acejump/session/mode/VisitResult.kt +++ b/src/main/kotlin/org/acejump/interact/VisitResult.kt @@ -1,4 +1,4 @@ -package org.acejump.session.mode +package org.acejump.interact sealed class VisitResult { object Nothing : VisitResult() diff --git a/src/main/kotlin/org/acejump/interact/mode/AbstractNavigableMode.kt b/src/main/kotlin/org/acejump/interact/mode/AbstractNavigableMode.kt new file mode 100644 index 0000000..e50930c --- /dev/null +++ b/src/main/kotlin/org/acejump/interact/mode/AbstractNavigableMode.kt @@ -0,0 +1,53 @@ +package org.acejump.interact.mode + +import com.intellij.openapi.editor.Editor +import org.acejump.action.AceTagAction +import org.acejump.action.TagVisitor +import org.acejump.interact.TypeResult +import org.acejump.interact.VisitDirection +import org.acejump.interact.VisitResult +import org.acejump.search.SearchProcessor +import org.acejump.search.Tagger +import org.acejump.session.SessionMode + +internal abstract class AbstractNavigableMode : SessionMode { + abstract val actionMap: Map<Char, AceTagAction> + abstract val modeMap: Map<Char, () -> SessionMode> + + override fun type(editor: Editor, processor: SearchProcessor, tagger: Tagger, charTyped: Char, acceptedTag: Int?): TypeResult { + if (acceptedTag != null) { + val action = actionMap[charTyped.toUpperCase()] + if (action != null) { + action(editor, processor, acceptedTag, charTyped.isUpperCase()) + return TypeResult.EndSession + } + + val mode = modeMap[charTyped.toUpperCase()] + if (mode != null) { + return TypeResult.ChangeMode(mode()) + } + + return TypeResult.Nothing + } + + if (processor.type(charTyped, tagger)) { + return TypeResult.UpdateResults + } + + return TypeResult.Nothing + } + + override fun visit(editor: Editor, processor: SearchProcessor, direction: VisitDirection, acceptedTag: Int?): VisitResult { + if (acceptedTag != null) { + AceTagAction.JumpToSearchStart(editor, processor, acceptedTag, shiftMode = false) + return VisitResult.EndSession + } + + val onlyTagOffset = when (direction) { + VisitDirection.BACKWARD -> TagVisitor(editor, processor).visitPrevious() + VisitDirection.FORWARD -> TagVisitor(editor, processor).visitNext() + } + + return onlyTagOffset?.let(VisitResult::SetAcceptedTag) ?: VisitResult.Nothing + } +} diff --git a/src/main/kotlin/org/acejump/interact/mode/DefaultMode.kt b/src/main/kotlin/org/acejump/interact/mode/DefaultMode.kt new file mode 100644 index 0000000..227b25a --- /dev/null +++ b/src/main/kotlin/org/acejump/interact/mode/DefaultMode.kt @@ -0,0 +1,33 @@ +package org.acejump.interact.mode + +import org.acejump.action.AceTagAction +import org.acejump.config.AceConfig + +internal object DefaultMode : AbstractNavigableMode() { + override val actionMap = mapOf( + 'J' to AceTagAction.JumpToSearchStart, + 'K' to AceTagAction.JumpToSearchEnd, + 'L' to AceTagAction.JumpPastSearchEnd, + 'W' to AceTagAction.JumpToWordStartTag, + 'E' to AceTagAction.JumpToWordEndTag, + 'B' to AceTagAction.GoToDeclaration, + 'U' to AceTagAction.ShowUsages, + 'I' to AceTagAction.ShowIntentions, + 'R' to AceTagAction.Refactor + ) + + override val modeMap = mapOf( + 'S' to { SelectMode }, + 'D' to { DeleteMode } + ) + + override val caretColor + get() = AceConfig.singleCaretModeColor + + override val actionHint = arrayOf( + "<f>[J]</f>ump to Tag / <f>[K]</f> to Query / <f>[L]</f> past Query", + "<f>[W]</f>ord Start / Word <f>[E]</f>nd", + "<f>[S]</f>elect... / <f>[D]</f>elete...", + "<f>[B]</f> Declaration / <f>[U]</f>sages / <f>[I]</f>ntentions / <f>[R]</f>efactor" + ) +} diff --git a/src/main/kotlin/org/acejump/interact/mode/DeleteMode.kt b/src/main/kotlin/org/acejump/interact/mode/DeleteMode.kt new file mode 100644 index 0000000..e13afec --- /dev/null +++ b/src/main/kotlin/org/acejump/interact/mode/DeleteMode.kt @@ -0,0 +1,17 @@ +package org.acejump.interact.mode + +import org.acejump.action.AceTagAction +import org.acejump.config.AceConfig + +internal object DeleteMode : AbstractNavigableMode() { + override val actionMap = SelectMode.actionMap.mapValues { AceTagAction.Delete(it.value) } + + override val modeMap + get() = SelectMode.modeMap + + override val caretColor + get() = AceConfig.singleCaretModeColor + + override val actionHint + get() = SelectMode.actionHint +} diff --git a/src/main/kotlin/org/acejump/session/mode/MultiCaretSessionMode.kt b/src/main/kotlin/org/acejump/interact/mode/MultiCaretMode.kt similarity index 91% rename from src/main/kotlin/org/acejump/session/mode/MultiCaretSessionMode.kt rename to src/main/kotlin/org/acejump/interact/mode/MultiCaretMode.kt index d6bee68..38879ab 100644 --- a/src/main/kotlin/org/acejump/session/mode/MultiCaretSessionMode.kt +++ b/src/main/kotlin/org/acejump/interact/mode/MultiCaretMode.kt @@ -1,13 +1,16 @@ -package org.acejump.session.mode +package org.acejump.interact.mode import com.intellij.openapi.editor.Editor import org.acejump.action.AceTagAction import org.acejump.config.AceConfig +import org.acejump.interact.TypeResult +import org.acejump.interact.VisitDirection +import org.acejump.interact.VisitResult import org.acejump.search.SearchProcessor import org.acejump.search.Tagger import org.acejump.session.SessionMode import org.acejump.session.SessionSnapshot -internal class MultiCaretSessionMode : SessionMode { +internal class MultiCaretMode : SessionMode { private companion object { private val actionMap = mapOf( 'J' to AceTagAction.JumpToSearchStart, diff --git a/src/main/kotlin/org/acejump/interact/mode/SelectMode.kt b/src/main/kotlin/org/acejump/interact/mode/SelectMode.kt new file mode 100644 index 0000000..f90bc73 --- /dev/null +++ b/src/main/kotlin/org/acejump/interact/mode/SelectMode.kt @@ -0,0 +1,27 @@ +package org.acejump.interact.mode + +import org.acejump.action.AceTagAction +import org.acejump.config.AceConfig +import org.acejump.session.SessionMode + +internal object SelectMode : AbstractNavigableMode() { + override val actionMap = mapOf( + 'Q' to AceTagAction.SelectQuery, + 'W' to AceTagAction.SelectWord, + 'H' to AceTagAction.SelectHump, + 'L' to AceTagAction.SelectLine, + *('1'..'9').mapIndexed { index, char -> char to AceTagAction.SelectExtended(index + 1) }.toTypedArray() + ) + + override val modeMap + get() = emptyMap<Char, () -> SessionMode>() + + override val caretColor + get() = AceConfig.singleCaretModeColor + + override val actionHint = arrayOf( + "<f>[Q]</f>uery / <f>[L]</f>ine", + "<f>[W]</f>ord / <f>[H]</f>ump", + "<f>[1-9] Extend Selection</f>" + ) +} diff --git a/src/main/kotlin/org/acejump/session/EditorSettings.kt b/src/main/kotlin/org/acejump/session/EditorSettings.kt index 592a54c..0d8cadd 100644 --- a/src/main/kotlin/org/acejump/session/EditorSettings.kt +++ b/src/main/kotlin/org/acejump/session/EditorSettings.kt @@ -26,6 +26,14 @@ internal data class EditorSettings(private val isBlockCursor: Boolean, private v } } + fun startEditing(editor: Editor) { + editor.document.setReadOnly(isReadOnly) + } + + fun stopEditing(editor: Editor) { + editor.document.setReadOnly(true) + } + fun onTagAccepted(editor: Editor) = editor.let { it.settings.isBlockCursor = isBlockCursor } diff --git a/src/main/kotlin/org/acejump/session/Session.kt b/src/main/kotlin/org/acejump/session/Session.kt index c6f9b05..6400147 100644 --- a/src/main/kotlin/org/acejump/session/Session.kt +++ b/src/main/kotlin/org/acejump/session/Session.kt @@ -18,11 +18,11 @@ import org.acejump.boundaries.StandardBoundaries import org.acejump.config.AceConfig import org.acejump.input.EditorKeyListener import org.acejump.input.KeyLayoutCache +import org.acejump.interact.TypeResult +import org.acejump.interact.VisitDirection +import org.acejump.interact.VisitResult +import org.acejump.interact.mode.DefaultMode import org.acejump.search.* -import org.acejump.session.mode.SingleCaretSessionMode -import org.acejump.session.mode.TypeResult -import org.acejump.session.mode.VisitDirection -import org.acejump.session.mode.VisitResult import org.acejump.view.TagCanvas import org.acejump.view.TextHighlighter @@ -53,17 +53,7 @@ class Session(private val editor: Editor) { if (processor != null) { textHighlighter.renderFinal(value, processor.query) - - val hintText = mode.actionHint - .joinToString("\n") - .replace("<f>", "<span style=\"font-family:'${editor.colorsScheme.editorFontName}';font-weight:bold\">") - .replace("</f>", "</span>") - - val hint = LightweightHint(HintUtil.createInformationLabel(hintText)) - val pos = HintManagerImpl.getHintPosition(hint, editor, editor.offsetToLogicalPosition(value), HintManager.ABOVE) - val info = HintManagerImpl.createHintHint(editor, pos, hint, HintManager.ABOVE).setShowImmediately(true) - val flags = HintManager.UPDATE_BY_SCROLLING or HintManager.HIDE_BY_ESCAPE - HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, pos, flags, 0, true, info) + setMode(DefaultMode) } } } @@ -88,11 +78,18 @@ class Session(private val editor: Editor) { if (processor == null) { processor = SearchProcessor.fromChar(editor, charTyped, defaultBoundaries).also { searchProcessor = it } updateSearch(processor) + return } - else when (val result = mode.type(editor, processor, tagger, charTyped, acceptedTag)) { + + editorSettings.startEditing(editor) + val result = mode.type(editor, processor, tagger, charTyped, acceptedTag) + editorSettings.stopEditing(editor) + + when (result) { TypeResult.UpdateResults -> updateSearch(processor) TypeResult.EndSession -> end() is TypeResult.LoadSnapshot -> loadSnapshot(result.snapshot) + is TypeResult.ChangeMode -> setMode(result.mode) else -> return } } @@ -136,13 +133,31 @@ class Session(private val editor: Editor) { searchProcessor = snapshot.savedProcessor?.also(::updateSearch) } + private fun setMode(mode: SessionMode) { + this.mode = mode + editor.colorsScheme.setColor(EditorColors.CARET_COLOR, mode.caretColor) + + val acceptedTag = acceptedTag + if (acceptedTag != null) { + val hintText = mode.actionHint + .joinToString("\n") + .replace("<f>", "<span style=\"font-family:'${editor.colorsScheme.editorFontName}';font-weight:bold\">") + .replace("</f>", "</span>") + + val hint = LightweightHint(HintUtil.createInformationLabel(hintText)) + val pos = HintManagerImpl.getHintPosition(hint, editor, editor.offsetToLogicalPosition(acceptedTag), HintManager.ABOVE) + val info = HintManagerImpl.createHintHint(editor, pos, hint, HintManager.ABOVE).setShowImmediately(true) + val flags = HintManager.UPDATE_BY_SCROLLING or HintManager.HIDE_BY_ESCAPE + HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, pos, flags, 0, true, info) + } + } + /** * Sets AceJump mode or ends the session if the mode is the same. */ - fun setMode(mode: SessionMode) { + fun toggleMode(mode: SessionMode) { if (!this::mode.isInitialized) { - this.mode = mode - editor.colorsScheme.setColor(EditorColors.CARET_COLOR, mode.caretColor) + setMode(mode) } else if (!this.mode.isSame(mode)) { this.mode = mode @@ -157,7 +172,7 @@ class Session(private val editor: Editor) { * Starts a regular expression search. If a search was already active, it will be reset alongside its tags and highlights. */ fun startRegexSearch(pattern: String, boundaries: Boundaries) { - setMode(SingleCaretSessionMode()) + toggleMode(DefaultMode) tagger = Tagger(editor) tagCanvas.setMarkers(emptyList(), isRegex = true) updateSearch(SearchProcessor.fromRegex(editor, pattern, boundaries.intersection(defaultBoundaries)).also { searchProcessor = it }) diff --git a/src/main/kotlin/org/acejump/session/SessionMode.kt b/src/main/kotlin/org/acejump/session/SessionMode.kt index b158fcf..ba29fad 100644 --- a/src/main/kotlin/org/acejump/session/SessionMode.kt +++ b/src/main/kotlin/org/acejump/session/SessionMode.kt @@ -1,11 +1,11 @@ package org.acejump.session import com.intellij.openapi.editor.Editor +import org.acejump.interact.TypeResult +import org.acejump.interact.VisitDirection +import org.acejump.interact.VisitResult import org.acejump.search.SearchProcessor import org.acejump.search.Tagger -import org.acejump.session.mode.TypeResult -import org.acejump.session.mode.VisitDirection -import org.acejump.session.mode.VisitResult import java.awt.Color interface SessionMode { diff --git a/src/main/kotlin/org/acejump/session/mode/SingleCaretSessionMode.kt b/src/main/kotlin/org/acejump/session/mode/SingleCaretSessionMode.kt deleted file mode 100644 index cd4ee64..0000000 --- a/src/main/kotlin/org/acejump/session/mode/SingleCaretSessionMode.kt +++ /dev/null @@ -1,62 +0,0 @@ -package org.acejump.session.mode - -import com.intellij.openapi.editor.Editor -import org.acejump.action.AceTagAction -import org.acejump.action.TagVisitor -import org.acejump.config.AceConfig -import org.acejump.search.SearchProcessor -import org.acejump.search.Tagger -import org.acejump.session.SessionMode - -internal class SingleCaretSessionMode : SessionMode { - private companion object { - private val actionMap = mapOf( - 'J' to AceTagAction.JumpToSearchStart, - 'K' to AceTagAction.JumpToSearchEnd, - 'L' to AceTagAction.JumpPastSearchEnd, - 'W' to AceTagAction.JumpToWordStartTag, - 'E' to AceTagAction.JumpToWordEndTag, - 'S' to AceTagAction.SelectWordOrHump, - 'D' to AceTagAction.GoToDeclaration, - 'U' to AceTagAction.ShowUsages, - 'I' to AceTagAction.ShowIntentions, - 'R' to AceTagAction.Refactor - ) - } - - override val caretColor - get() = AceConfig.singleCaretModeColor - - override val actionHint = arrayOf( - "<f>[J]</f>ump to Tag / <f>[K]</f> to Query / <f>[L]</f> past Query", - "<f>[W]</f>ord Start / Word <f>[E]</f>nd / <f>[S]</f>elect Word", - "<f>[D]</f>eclaration / <f>[U]</f>sages / <f>[I]</f>ntentions / <f>[R]</f>efactor" - ) - - override fun type(editor: Editor, processor: SearchProcessor, tagger: Tagger, charTyped: Char, acceptedTag: Int?): TypeResult { - if (acceptedTag != null) { - val action = actionMap[charTyped.toUpperCase()] ?: return TypeResult.Nothing - action(editor, processor, acceptedTag, charTyped.isUpperCase()) - return TypeResult.EndSession - } - else if (processor.type(charTyped, tagger)) { - return TypeResult.UpdateResults - } - - return TypeResult.Nothing - } - - override fun visit(editor: Editor, processor: SearchProcessor, direction: VisitDirection, acceptedTag: Int?): VisitResult { - if (acceptedTag != null) { - AceTagAction.JumpToSearchStart(editor, processor, acceptedTag, shiftMode = false) - return VisitResult.EndSession - } - - val onlyTagOffset = when (direction) { - VisitDirection.BACKWARD -> TagVisitor(editor, processor).visitPrevious() - VisitDirection.FORWARD -> TagVisitor(editor, processor).visitNext() - } - - return onlyTagOffset?.let(VisitResult::SetAcceptedTag) ?: VisitResult.Nothing - } -}