1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-08-16 22:31:47 +02:00
Files
.github
.idea
.teamcity
assets
config
doc
gradle
src
main
antlr
java
com
maddyhome
idea
vim
action
command
common
config
ex
extension
group
handler
ActionBeanClass.kt
IdeActionHandler.kt
helper
icons
key
listener
mark
newapi
option
regexp
statistic
troubleshooting
ui
vimscript
DynamicLoaderStopper.kt
EventFacade.java
PluginStartup.kt
RegisterActions.java
VimBundledDictionaryProvider.kt
VimPlugin.java
VimProjectService.kt
VimTypedActionHandler.kt
VimTypedDelegateHandler.kt
package-info.java
resources
test
verifier
vim-engine
vimscript-info
.editorconfig
.gitignore
AUTHORS.md
CHANGES.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE.txt
README.md
build.gradle.kts
gradle.properties
gradlew
gradlew.bat
qodana.sarif.json
qodana.yaml
settings.gradle
IntelliJ-IdeaVim/src/main/java/com/maddyhome/idea/vim/handler/ActionBeanClass.kt
Alex Plate f5b6ca50f4 Update IdeaVim license to MIT
VIM-2782
2022-11-01 20:00:07 +02:00

100 lines
3.2 KiB
Kotlin

/*
* Copyright 2022 The IdeaVim authors
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE.txt file or at
* https://opensource.org/licenses/MIT.
*/
package com.maddyhome.idea.vim.handler
import com.intellij.serviceContainer.BaseKeyedLazyInstance
import com.intellij.util.SmartList
import com.intellij.util.xmlb.annotations.Attribute
import com.maddyhome.idea.vim.command.MappingMode
import javax.swing.KeyStroke
/**
* Action holder for IdeaVim actions.
*
* [implementation] should be subclass of [EditorActionHandlerBase]
*
* [modes] ("mappingModes") defines the action modes. E.g. "NO" - action works in normal and op-pending modes.
* Warning: V - Visual and Select mode. X - Visual mode. (like vmap and xmap).
* Use "ALL" to enable action for all modes.
*
* [keys] comma-separated list of keys for the action. E.g. `gt,gT` - action gets executed on `gt` or `gT`
* Since xml doesn't allow using raw `<` character, use « and » symbols for mappings with modifiers.
* E.g. `«C-U»` - CTRL-U (<C-U> in vim notation)
* If you want to use exactly `<` character, replace it with `&lt;`. E.g. `i&lt;` - i<
* If you want to use comma in mapping, use `«COMMA»`
* Do not place a whitespace around the comma!
*
*
* !! IMPORTANT !!
* You may wonder why the extension points are used instead of any other approach to register actions.
* The reason is startup performance. Using the extension points you don't even have to load classes of actions.
* So, all actions are loaded on demand, including classes in classloader.
*/
class ActionBeanClass : BaseKeyedLazyInstance<EditorActionHandlerBase>() {
@Attribute("implementation")
var implementation: String? = null
@Attribute("mappingModes")
var modes: String? = null
@Attribute("keys")
var keys: String? = null
val actionId: String get() = implementation?.let { EditorActionHandlerBase.getActionId(it) } ?: ""
fun getParsedKeys(): Set<List<KeyStroke>>? {
val myKeys = keys ?: return null
val escapedKeys = myKeys.splitByComma()
return EditorActionHandlerBase.parseKeysSet(escapedKeys)
}
override fun getImplementationClassName(): String? = implementation
fun getParsedModes(): Set<MappingMode>? {
val myModes = modes ?: return null
if ("ALL" == myModes) return MappingMode.ALL
val res = mutableListOf<MappingMode>()
for (c in myModes) {
when (c) {
'N' -> res += MappingMode.NORMAL
'X' -> res += MappingMode.VISUAL
'V' -> {
res += MappingMode.VISUAL
res += MappingMode.SELECT
}
'S' -> res += MappingMode.SELECT
'O' -> res += MappingMode.OP_PENDING
'I' -> res += MappingMode.INSERT
'C' -> res += MappingMode.CMD_LINE
else -> error("Wrong mapping mode: $c")
}
}
return res.toSet()
}
private fun String.splitByComma(): List<String> {
if (this.isEmpty()) return ArrayList()
val res = SmartList<String>()
var start = 0
var current = 0
while (current < this.length) {
if (this[current] == ',') {
res += this.substring(start, current)
current++
start = current
}
current++
}
res += this.substring(start, current)
return res
}
}