1
0
mirror of https://github.com/chylex/IntelliJ-AceJump.git synced 2025-04-23 03:15:43 +02:00
This commit is contained in:
chylex 2020-11-18 07:01:58 +01:00
parent ee1ce3c37e
commit b73e5f1ae5
4 changed files with 137 additions and 89 deletions
src/main
kotlin/org/acejump
resources/META-INF

View File

@ -1,90 +1,132 @@
package org.acejump.control
import com.intellij.codeInsight.editorActions.SelectWordUtil
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.editor.CaretState
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.util.TextRange
import org.acejump.control.Handler.regexSearch
import org.acejump.label.Pattern
import org.acejump.label.Pattern.ALL_WORDS
import org.acejump.search.Finder
import org.acejump.search.JumpMode
import org.acejump.search.Jumper
import org.acejump.search.getNameOfFileInEditor
import org.acejump.view.Boundary.*
import org.acejump.view.Model
import org.acejump.view.Model.boundaries
import org.acejump.view.Model.defaultBoundary
import org.acejump.view.Model.editor
import org.acejump.view.Model.viewBounds
/**
* Entry point for all actions. The IntelliJ Platform calls AceJump here.
*/
open class AceAction: DumbAwareAction() {
open val logger = Logger.getInstance(javaClass)
override fun update(action: AnActionEvent) {
sealed class AceAction: DumbAwareAction() {
val logger = Logger.getInstance(javaClass)
final override fun update(action: AnActionEvent) {
action.presentation.isEnabled = action.getData(EDITOR) != null
}
override fun actionPerformed(e: AnActionEvent) {
final override fun actionPerformed(e: AnActionEvent) {
editor = e.getData(EDITOR) ?: return
boundaries = defaultBoundary
val textLength = editor.document.textLength
logger.info("Invoked on ${editor.getNameOfFileInEditor()} ($textLength)")
logger.debug { "Invoked on ${FileDocumentManager.getInstance().getFile(editor.document)?.presentableName} (${editor.document.textLength})" }
Handler.activate()
customize()
invoke()
}
open fun customize() = Jumper.cycleMode()
abstract fun invoke()
object ActivateOrCycleMode : AceAction() {
override fun invoke() = Jumper.cycleMode()
}
object ToggleJumpMode: AceAction() {
override fun invoke() = Jumper.toggleMode(JumpMode.JUMP)
}
object ToggleJumpEndMode: AceAction() {
override fun invoke() = Jumper.toggleMode(JumpMode.JUMP_END)
}
object ToggleSelectWordMode: AceAction() {
override fun invoke() = Jumper.toggleMode(JumpMode.TARGET)
}
object ToggleDefinitionMode: AceAction() {
override fun invoke() = Jumper.toggleMode(JumpMode.DEFINE)
}
object ToggleAllLinesMode: AceAction() {
override fun invoke() = regexSearch(Pattern.LINE_MARK)
}
object ToggleAllWordsMode: AceAction() {
override fun invoke() = regexSearch(ALL_WORDS, SCREEN_BOUNDARY)
}
object ToggleAllWordsForwardMode: AceAction() {
override fun invoke() = regexSearch(ALL_WORDS, AFTER_CARET_BOUNDARY)
}
object ToggleAllWordsBackwardsMode: AceAction() {
override fun invoke() = regexSearch(ALL_WORDS, BEFORE_CARET_BOUNDARY)
}
object ActOnHighlightedWords: AceAction() {
override fun invoke() = when(JumpMode.mode) {
JumpMode.DISABLED -> {}
JumpMode.JUMP -> if (editor.caretModel.supportsMultipleCarets()) jumpToAll() else Unit
JumpMode.JUMP_END -> if (editor.caretModel.supportsMultipleCarets()) jumpToWordEnds() else Unit
JumpMode.TARGET -> if (editor.caretModel.supportsMultipleCarets()) selectAllWords() else Unit
JumpMode.DEFINE -> {}
}
private fun jumpToAll() {
val carets = Finder.allResults().map {
CaretState(editor.offsetToLogicalPosition(it), null, null)
}
if (carets.isEmpty()) return
Handler.reset()
editor.caretModel.caretsAndSelections = carets
editor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE)
}
private fun jumpToWordEnds() {
val ranges = ArrayList<TextRange>()
for (offset in Finder.allResults()) {
SelectWordUtil.addWordSelection(editor.settings.isCamelWords, Model.editorText, offset, ranges)
}
if (ranges.isEmpty()) return
Handler.reset()
editor.caretModel.caretsAndSelections = ranges.map {
CaretState(editor.offsetToLogicalPosition(it.endOffset), null, null)
}
editor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE)
}
private fun selectAllWords() {
val ranges = ArrayList<TextRange>()
for (offset in Finder.allResults()) {
SelectWordUtil.addWordSelection(editor.settings.isCamelWords, Model.editorText, offset, ranges)
}
if (ranges.isEmpty()) return
Handler.reset()
editor.caretModel.caretsAndSelections = ranges.map {
val start = editor.offsetToLogicalPosition(it.startOffset)
val end = editor.offsetToLogicalPosition(it.endOffset)
CaretState(end, start, end)
}
editor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE)
}
}
}
/**
* When target mode is activated, selecting a tag will highlight an entire word.
*/
class AceTargetAction: AceAction() {
override fun customize() = Jumper.toggleMode(JumpMode.TARGET)
}
/*
* When line mode is activated, we will tag the beginning and end of each line.
*
* TODO: https://github.com/acejump/AceJump/issues/327
* TODO: https://github.com/acejump/AceJump/issues/340
*/
class AceLineAction: AceAction() {
override fun customize() = regexSearch(Pattern.LINE_MARK)
}
/**
* When declaration mode is activated, selecting a tag will take us to the
* definition (i.e. declaration) of the token in the editor, if it exists.
*/
class AceDefinitionAction: AceAction() {
override fun customize() = Jumper.toggleMode(JumpMode.DEFINE)
}
/**
* When word mode is activated, we will tag all words on the screen.
*/
class AceWordAction: AceAction() {
override fun customize() = regexSearch(ALL_WORDS, SCREEN_BOUNDARY)
}
/**
* Search for words from the start of the screen to the caret
*/
class AceWordForwardAction: AceAction() {
override fun customize() = regexSearch(ALL_WORDS, AFTER_CARET_BOUNDARY)
}
/**
* Search for words from the caret position to the start of the screen
*/
class AceWordBackwardsAction: AceAction() {
override fun customize() = regexSearch(ALL_WORDS, BEFORE_CARET_BOUNDARY)
}

View File

@ -201,6 +201,8 @@ object Finder : Resettable {
return kept
}
fun allResults() = results
fun visibleResults() = results.filter { it in viewBounds }
private fun String.isValidQuery() =

View File

@ -13,8 +13,9 @@ enum class JumpMode {
companion object: Resettable {
private var modeIndex = 0
private var mode: JumpMode = DISABLED
set(value) {
var mode: JumpMode = DISABLED
private set(value) {
field = value
setCaretColor(when (field) {
JUMP -> AceConfig.jumpModeColor

View File

@ -22,44 +22,47 @@
<actions>
<action id="AceAction"
class="org.acejump.control.AceAction"
text="Activate AceJump Mode"
description="Targets a character in AceJump">
class="org.acejump.control.AceAction$ActivateOrCycleMode"
text="Activate / Cycle AceJump Mode">
<keyboard-shortcut keymap="Mac OS X" first-keystroke="ctrl SEMICOLON"/>
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="ctrl SEMICOLON"/>
<keyboard-shortcut keymap="$default" first-keystroke="ctrl SEMICOLON"/>
</action>
<action id="AceWordStartAction"
class="org.acejump.control.AceAction$ToggleJumpMode"
text="Start AceJump in Word Start Mode"/>
<action id="AceWordEndAction"
class="org.acejump.control.AceAction$ToggleJumpEndMode"
text="Start AceJump in Word End Mode"/>
<action id="AceTargetAction"
class="org.acejump.control.AceAction$ToggleSelectWordMode"
text="Start AceJump in Word Select Mode">
<keyboard-shortcut keymap="Mac OS X" first-keystroke="ctrl alt SEMICOLON"/>
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="ctrl alt SEMICOLON"/>
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt SEMICOLON"/>
</action>
<action id="AceDeclarationAction"
class="org.acejump.control.AceAction$ToggleDefinitionMode"
text="Start AceJump in Declaration Mode"/>
<action id="AceLineAction"
class="org.acejump.control.AceLineAction"
text="Display Line Markers"
class="org.acejump.control.AceAction$ToggleAllLinesMode"
text="Start AceJump in All Lines Mode"
description="Targets line markers in AceJump">
<keyboard-shortcut keymap="Mac OS X" first-keystroke="ctrl shift SEMICOLON"/>
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="ctrl shift SEMICOLON"/>
<keyboard-shortcut keymap="$default" first-keystroke="ctrl shift SEMICOLON"/>
</action>
<action id="AceTargetAction"
class="org.acejump.control.AceTargetAction"
text="Start in Target Mode"
description="Targets a whole word in AceJump">
<keyboard-shortcut keymap="Mac OS X" first-keystroke="ctrl alt SEMICOLON"/>
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="ctrl alt SEMICOLON"/>
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt SEMICOLON"/>
</action>
<action id="AceWordAction"
class="org.acejump.control.AceWordAction"
text="Start in Word Mode"
description="Searches for all words on the screen in AceJump"/>
class="org.acejump.control.AceAction$ToggleAllWordsMode"
text="Start AceJump in All Words Mode"/>
<action id="AceWordForwardAction"
class="org.acejump.control.AceWordForwardAction"
text="Start in Word Forward Mode"
description="Searches for all visible words after the caret in AceJump"/>
class="org.acejump.control.AceAction$ToggleAllWordsForwardMode"
text="Start in All Words After Caret Mode"/>
<action id="AceWordBackwardsAction"
class="org.acejump.control.AceWordBackwardsAction"
text="Start in Word Backward Mode"
description="Searches for all visible words before the caret in AceJump"/>
<action id="AceDeclarationAction"
class="org.acejump.control.AceDefinitionAction"
text="Start in Declaration Mode"
description="AceJump will invoke the 'Navigate To' action after jumping"/>
class="org.acejump.control.AceAction$ToggleAllWordsBackwardsMode"
text="Start in All Words Before Caret Mode"/>
<action id="AceActOnHighlightedWords"
class="org.acejump.control.AceAction$ActOnHighlightedWords"
text="Act on Highlighted Words"/>
</actions>
</idea-plugin>