mirror of
https://github.com/chylex/IntelliJ-AceJump.git
synced 2025-05-31 09:34:06 +02:00
[WIP] Add interactive modes for selection and deletion
This commit is contained in:
parent
402517c412
commit
658c2062a7
src/main/kotlin/org/acejump
@ -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].
|
||||
|
@ -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
|
||||
|
@ -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`.
|
||||
|
@ -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()
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.acejump.session.mode
|
||||
package org.acejump.interact
|
||||
|
||||
enum class VisitDirection {
|
||||
BACKWARD,
|
@ -1,4 +1,4 @@
|
||||
package org.acejump.session.mode
|
||||
package org.acejump.interact
|
||||
|
||||
sealed class VisitResult {
|
||||
object Nothing : VisitResult()
|
@ -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
|
||||
}
|
||||
}
|
33
src/main/kotlin/org/acejump/interact/mode/DefaultMode.kt
Normal file
33
src/main/kotlin/org/acejump/interact/mode/DefaultMode.kt
Normal file
@ -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"
|
||||
)
|
||||
}
|
17
src/main/kotlin/org/acejump/interact/mode/DeleteMode.kt
Normal file
17
src/main/kotlin/org/acejump/interact/mode/DeleteMode.kt
Normal file
@ -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
|
||||
}
|
@ -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,
|
27
src/main/kotlin/org/acejump/interact/mode/SelectMode.kt
Normal file
27
src/main/kotlin/org/acejump/interact/mode/SelectMode.kt
Normal file
@ -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>"
|
||||
)
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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 })
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user