1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-05-04 16:34:02 +02:00

Add LazyVimCommand and CommandProvider

This commit is contained in:
Filipp Vakhitov 2023-11-10 11:32:00 +02:00
parent 30165f5047
commit fe6c1ae452
10 changed files with 116 additions and 2 deletions
annotation-processors/src/main/kotlin/com/intellij/vim/processors
src/main/java/com/maddyhome/idea/vim
vim-engine/src/main/kotlin/com/maddyhome/idea/vim

View File

@ -56,5 +56,5 @@ class CommandOrMotionProcessor(private val environment: SymbolProcessorEnvironme
}
@Serializable
private data class CommandBean(val keys: String, val `class`: String, val modes: String)
data class CommandBean(val keys: String, val `class`: String, val modes: String)
}

View File

@ -0,0 +1,13 @@
/*
* Copyright 2003-2023 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.action
public object IntellijCommandProvider : CommandProvider {
override val exCommandListFileName: String = "intellij_commands.json"
}

View File

@ -35,6 +35,7 @@ public open class GlobalIjOptions(scope: OptionAccessScope) : OptionsPropertiesB
public var unifyjumps: Boolean by optionProperty(IjOptions.unifyjumps)
public var exCommandAnnotation: Boolean by optionProperty(IjOptions.exCommandAnnotation)
public var vimscriptFunctionAnnotation: Boolean by optionProperty(IjOptions.vimscriptFunctionAnnotation)
public var commandOrMotionAnnotation: Boolean by optionProperty(IjOptions.commandOrMotionAnnotation)
}
/**

View File

@ -84,6 +84,7 @@ public object IjOptions {
public val trackactionids: ToggleOption = addOption(ToggleOption("trackactionids", GLOBAL, "tai", false))
public val unifyjumps: ToggleOption = addOption(ToggleOption("unifyjumps", GLOBAL, "unifyjumps", true))
public val vimscriptFunctionAnnotation: ToggleOption = addOption(ToggleOption("vimscriptfunctionannotation", GLOBAL, "vimscriptfunctionannotation", true))
public val commandOrMotionAnnotation: ToggleOption = addOption(ToggleOption("commandormotionannotation", GLOBAL, "commandormotionannotation", true))
public val visualdelay: UnsignedNumberOption = addOption(UnsignedNumberOption("visualdelay", GLOBAL, "visualdelay", 100))
// This needs to be Option<out VimDataType> so that it can work with derived option types, such as NumberOption, which

View File

@ -38,7 +38,7 @@ import javax.swing.KeyStroke
* So, all actions are loaded on demand, including classes in classloader.
*/
@Deprecated(message = "Please use CommandOrMotion annotation")
@ScheduledForRemoval(inVersion = "2.7.0")
@ScheduledForRemoval(inVersion = "2.9.0")
internal class ActionBeanClass : BaseKeyedLazyInstance<EditorActionHandlerBase>() {
@Attribute("implementation")
var implementation: String? = null

View File

@ -11,7 +11,10 @@ package com.maddyhome.idea.vim.newapi
import com.maddyhome.idea.vim.api.VimActionsInitiator
import com.maddyhome.idea.vim.handler.ActionBeanClass
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
import org.jetbrains.annotations.ApiStatus
@Deprecated(message = "Please use CommandOrMotion annotation")
@ApiStatus.ScheduledForRemoval(inVersion = "2.9.0")
internal class IjVimActionsInitiator(val bean: ActionBeanClass) : VimActionsInitiator {
override fun getInstance(): EditorActionHandlerBase = bean.instance
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2003-2023 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.action
import com.intellij.vim.processors.CommandOrMotionProcessor
import com.maddyhome.idea.vim.action.change.LazyVimCommand
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.MappingMode
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import java.io.InputStream
public interface CommandProvider {
public val exCommandListFileName: String
@OptIn(ExperimentalSerializationApi::class)
public fun getCommands(): Collection<LazyVimCommand> {
val classLoader = this.javaClass.classLoader
val commands: List<CommandOrMotionProcessor.CommandBean> = Json.decodeFromStream(getFile())
return commands
.groupBy { it.`class` }
.map {
val keys = it.value.map { bean -> injector.parser.parseKeys(bean.keys) }.toSet()
val modes = it.value.first().modes.map { mode -> MappingMode.parseModeChar(mode) }.toSet()
LazyVimCommand(
keys,
modes,
it.key,
classLoader
)
}
}
private fun getFile(): InputStream {
return object {}.javaClass.classLoader.getResourceAsStream(exCommandListFileName)
?: throw RuntimeException("Failed to fetch ex commands from ${javaClass.name}")
}
}

View File

@ -0,0 +1,13 @@
/*
* Copyright 2003-2023 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.action
public object EngineCommandProvider : CommandProvider {
override val exCommandListFileName: String = "engine_commands.json"
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2003-2023 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.action.change
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
import com.maddyhome.idea.vim.vimscript.model.LazyInstance
import javax.swing.KeyStroke
public class LazyVimCommand(
public val keys: Set<List<KeyStroke>>,
public val modes: Set<MappingMode>,
className: String,
classLoader: ClassLoader,
) : LazyInstance<EditorActionHandlerBase>(className, classLoader) {
public val actionId: String = EditorActionHandlerBase.getActionId(className)
}

View File

@ -7,6 +7,7 @@
*/
package com.maddyhome.idea.vim.command
import com.maddyhome.idea.vim.ex.ExException
import java.util.*
/**
@ -71,5 +72,18 @@ public enum class MappingMode {
public val NVO: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL, OP_PENDING, SELECT)
public val INV: EnumSet<MappingMode> = EnumSet.of(INSERT, NORMAL, VISUAL, SELECT)
public val ALL: EnumSet<MappingMode> = EnumSet.allOf(MappingMode::class.java)
// This method is used only for single modes, not groups of them (V is not supported)
internal fun parseModeChar(char: Char): MappingMode {
return when (char.uppercaseChar()) {
'N' -> NORMAL
'X' -> VISUAL
'S' -> SELECT
'O' -> OP_PENDING
'I' -> INSERT
'C' -> CMD_LINE
else -> throw ExException("Unexpected mode for char $char")
}
}
}
}