mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-09-15 17:32:14 +02:00
Compare commits
10 Commits
1791692d92
...
customized
Author | SHA1 | Date | |
---|---|---|---|
edb9b194bb
|
|||
![]() |
eae7ed95e2
|
||
a1e2ae0eb9
|
|||
eae2e3b6b8
|
|||
c2d997a520
|
|||
e2a8a3c21a
|
|||
9b7fee6163
|
|||
d0f9d3dc70
|
|||
8d3a69b338
|
|||
3c530474a1
|
24
.teamcity/patches/buildTypes/Build.kts
vendored
24
.teamcity/patches/buildTypes/Build.kts
vendored
@@ -4,7 +4,7 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.golang
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.golang
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
|
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -17,33 +17,17 @@ create(DslContext.projectId, BuildType({
|
|||||||
name = "IdeaVim compatibility with external plugins"
|
name = "IdeaVim compatibility with external plugins"
|
||||||
|
|
||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(RelativeId("HttpsGithubComAlexPl292IdeaVimCompatibilityRefsHeadsMaster"))
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
name = "Check"
|
scriptContent = "go run test.go"
|
||||||
scriptContent = """
|
|
||||||
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}org.jetbrains.IdeaVim-EasyMotion' [latest-IU] -team-city
|
|
||||||
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}io.github.mishkun.ideavimsneak' [latest-IU] -team-city
|
|
||||||
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}eu.theblob42.idea.whichkey' [latest-IU] -team-city
|
|
||||||
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}IdeaVimExtension' [latest-IU] -team-city
|
|
||||||
# Outdated java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}github.zgqq.intellij-enhance' [latest-IU] -team-city
|
|
||||||
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.github.copilot' [latest-IU] -team-city
|
|
||||||
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.github.dankinsoid.multicursor' [latest-IU] -team-city
|
|
||||||
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.joshestein.ideavim-quickscope' [latest-IU] -team-city
|
|
||||||
""".trimIndent()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
triggers {
|
triggers {
|
||||||
schedule {
|
vcs {
|
||||||
schedulingPolicy = daily {
|
|
||||||
hour = 4
|
|
||||||
}
|
|
||||||
branchFilter = ""
|
|
||||||
triggerBuild = always()
|
|
||||||
withPendingChangesOnly = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
# suppress inspection "UnusedProperty" for whole file
|
# suppress inspection "UnusedProperty" for whole file
|
||||||
|
|
||||||
ideaVersion=LATEST-EAP-SNAPSHOT
|
ideaVersion=2022.1.2
|
||||||
downloadIdeaSources=true
|
downloadIdeaSources=true
|
||||||
instrumentPluginCode=true
|
instrumentPluginCode=true
|
||||||
version=SNAPSHOT
|
version=chylex-12
|
||||||
javaVersion=11
|
javaVersion=11
|
||||||
remoteRobotVersion=0.11.10
|
remoteRobotVersion=0.11.10
|
||||||
antlrVersion=4.10.1
|
antlrVersion=4.10.1
|
||||||
|
@@ -48,13 +48,13 @@ import com.maddyhome.idea.vim.group.visual.VisualMotionGroup;
|
|||||||
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
|
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerManager;
|
import com.maddyhome.idea.vim.listener.VimListenerManager;
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimInjector;
|
import com.maddyhome.idea.vim.newapi.IjVimInjector;
|
||||||
|
import com.maddyhome.idea.vim.options.OptionService;
|
||||||
import com.maddyhome.idea.vim.ui.StatusBarIconFactory;
|
import com.maddyhome.idea.vim.ui.StatusBarIconFactory;
|
||||||
import com.maddyhome.idea.vim.ui.VimEmulationConfigurable;
|
import com.maddyhome.idea.vim.ui.VimEmulationConfigurable;
|
||||||
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import com.maddyhome.idea.vim.vimscript.services.FunctionStorage;
|
import com.maddyhome.idea.vim.vimscript.services.FunctionStorage;
|
||||||
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService;
|
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService;
|
||||||
import com.maddyhome.idea.vim.vimscript.services.OptionService;
|
import com.maddyhome.idea.vim.vimscript.services.VimVariableService;
|
||||||
import com.maddyhome.idea.vim.vimscript.services.VariableService;
|
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Nls;
|
import org.jetbrains.annotations.Nls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -226,8 +226,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
return (PutGroup)VimInjectorKt.getInjector().getPut();
|
return (PutGroup)VimInjectorKt.getInjector().getPut();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull VariableService getVariableService() {
|
public static @NotNull VimVariableService getVariableService() {
|
||||||
return ApplicationManager.getApplication().getService(VariableService.class);
|
return ApplicationManager.getApplication().getService(VimVariableService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull OptionService getOptionService() {
|
public static @NotNull OptionService getOptionService() {
|
||||||
|
@@ -148,6 +148,10 @@ class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatible*/ {
|
|||||||
if (keyCode == KeyEvent.VK_TAB && editor.isTemplateActive()) return false
|
if (keyCode == KeyEvent.VK_TAB && editor.isTemplateActive()) return false
|
||||||
|
|
||||||
if ((keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_ENTER) && editor.appCodeTemplateCaptured()) return false
|
if ((keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_ENTER) && editor.appCodeTemplateCaptured()) return false
|
||||||
|
|
||||||
|
if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT) return false
|
||||||
|
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN) return false
|
||||||
|
if (keyCode == KeyEvent.VK_HOME || keyCode == KeyEvent.VK_END) return false
|
||||||
|
|
||||||
if (editor.inInsertMode) {
|
if (editor.inInsertMode) {
|
||||||
if (keyCode == KeyEvent.VK_TAB) {
|
if (keyCode == KeyEvent.VK_TAB) {
|
||||||
|
@@ -34,8 +34,8 @@ import com.maddyhome.idea.vim.group.visual.VimSelection
|
|||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import com.maddyhome.idea.vim.helper.vimStateMachine
|
import com.maddyhome.idea.vim.helper.vimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@@ -30,15 +30,6 @@ class CommandState(private val machine: VimStateMachine) {
|
|||||||
val isOperatorPending: Boolean
|
val isOperatorPending: Boolean
|
||||||
get() = machine.isOperatorPending
|
get() = machine.isOperatorPending
|
||||||
|
|
||||||
val mode: CommandState.Mode
|
|
||||||
get() = machine.mode.ij
|
|
||||||
|
|
||||||
val commandBuilder: CommandBuilder
|
|
||||||
get() = machine.commandBuilder
|
|
||||||
|
|
||||||
val mappingState: MappingState
|
|
||||||
get() = machine.mappingState
|
|
||||||
|
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
// Basic modes
|
// Basic modes
|
||||||
COMMAND, VISUAL, SELECT, INSERT, CMD_LINE, /*EX*/
|
COMMAND, VISUAL, SELECT, INSERT, CMD_LINE, /*EX*/
|
||||||
@@ -59,6 +50,7 @@ class CommandState(private val machine: VimStateMachine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val CommandState.SubMode.engine: VimStateMachine.SubMode
|
val CommandState.SubMode.engine: VimStateMachine.SubMode
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
CommandState.SubMode.NONE -> VimStateMachine.SubMode.NONE
|
CommandState.SubMode.NONE -> VimStateMachine.SubMode.NONE
|
||||||
@@ -81,6 +73,7 @@ val CommandState.Mode.engine: VimStateMachine.Mode
|
|||||||
CommandState.Mode.INSERT_SELECT -> VimStateMachine.Mode.INSERT_SELECT
|
CommandState.Mode.INSERT_SELECT -> VimStateMachine.Mode.INSERT_SELECT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val VimStateMachine.Mode.ij: CommandState.Mode
|
val VimStateMachine.Mode.ij: CommandState.Mode
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
VimStateMachine.Mode.COMMAND -> CommandState.Mode.COMMAND
|
VimStateMachine.Mode.COMMAND -> CommandState.Mode.COMMAND
|
||||||
|
@@ -23,7 +23,6 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.action.change.Extension
|
import com.maddyhome.idea.vim.action.change.Extension
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.common.CommandAlias
|
import com.maddyhome.idea.vim.common.CommandAlias
|
||||||
@@ -60,8 +59,8 @@ object VimExtensionFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* COMPATIBILITY-LAYER: Additional method
|
* COMPATIBILITY-LAYER: Additional method
|
||||||
*/
|
*/
|
||||||
/** The 'map' command for mapping keys to handlers defined in extensions. */
|
/** The 'map' command for mapping keys to handlers defined in extensions. */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun putExtensionHandlerMapping(
|
fun putExtensionHandlerMapping(
|
||||||
@@ -183,24 +182,12 @@ object VimExtensionFacade {
|
|||||||
return reg.keys
|
return reg.keys
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun getRegisterForCaret(register: Char, caret: VimCaret): List<KeyStroke>? {
|
|
||||||
val reg = caret.registerStorage.getRegister(register) ?: return null
|
|
||||||
return reg.keys
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the current contents of the given register */
|
/** Set the current contents of the given register */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setRegister(register: Char, keys: List<KeyStroke?>?) {
|
fun setRegister(register: Char, keys: List<KeyStroke?>?) {
|
||||||
VimPlugin.getRegister().setKeys(register, keys?.filterNotNull() ?: emptyList())
|
VimPlugin.getRegister().setKeys(register, keys?.filterNotNull() ?: emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the current contents of the given register */
|
|
||||||
@JvmStatic
|
|
||||||
fun setRegisterForCaret(register: Char, caret: VimCaret, keys: List<KeyStroke?>?) {
|
|
||||||
caret.registerStorage.setKeys(register, keys?.filterNotNull() ?: emptyList())
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the current contents of the given register */
|
/** Set the current contents of the given register */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setRegister(register: Char, keys: List<KeyStroke?>?, type: SelectionType) {
|
fun setRegister(register: Char, keys: List<KeyStroke?>?, type: SelectionType) {
|
||||||
|
@@ -25,9 +25,9 @@ import com.maddyhome.idea.vim.api.VimExtensionRegistrator
|
|||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner.Plugin.Companion.remove
|
import com.maddyhome.idea.vim.key.MappingOwner.Plugin.Companion.remove
|
||||||
import com.maddyhome.idea.vim.option.ToggleOption
|
|
||||||
import com.maddyhome.idea.vim.options.OptionChangeListener
|
import com.maddyhome.idea.vim.options.OptionChangeListener
|
||||||
import com.maddyhome.idea.vim.options.OptionScope
|
import com.maddyhome.idea.vim.options.OptionScope
|
||||||
|
import com.maddyhome.idea.vim.option.ToggleOption
|
||||||
import com.maddyhome.idea.vim.statistic.PluginState
|
import com.maddyhome.idea.vim.statistic.PluginState
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
||||||
|
|
||||||
|
@@ -34,14 +34,13 @@ import com.maddyhome.idea.vim.api.injector
|
|||||||
import com.maddyhome.idea.vim.command.Argument
|
import com.maddyhome.idea.vim.command.Argument
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
import com.maddyhome.idea.vim.command.CommandFlags
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.command.TextObjectVisualType
|
import com.maddyhome.idea.vim.command.TextObjectVisualType
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
|
||||||
import com.maddyhome.idea.vim.common.CommandAliasHandler
|
import com.maddyhome.idea.vim.common.CommandAliasHandler
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.ex.ranges.Ranges
|
import com.maddyhome.idea.vim.ex.ranges.Ranges
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.addCommand
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.addCommand
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
|
||||||
@@ -49,6 +48,7 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMa
|
|||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
||||||
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler
|
import com.maddyhome.idea.vim.handler.TextObjectActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.PsiHelper
|
import com.maddyhome.idea.vim.helper.PsiHelper
|
||||||
|
@@ -31,11 +31,10 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.getRegister
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.getRegister
|
||||||
@@ -43,6 +42,7 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMa
|
|||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegister
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegister
|
||||||
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition
|
||||||
|
@@ -33,21 +33,21 @@ import com.maddyhome.idea.vim.api.injector
|
|||||||
import com.maddyhome.idea.vim.command.Argument
|
import com.maddyhome.idea.vim.command.Argument
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
import com.maddyhome.idea.vim.command.CommandFlags
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
import com.maddyhome.idea.vim.command.MotionType
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.common.Direction
|
import com.maddyhome.idea.vim.common.Direction
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
||||||
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.handler.Motion
|
import com.maddyhome.idea.vim.handler.Motion
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||||
import com.maddyhome.idea.vim.handler.toMotionOrError
|
import com.maddyhome.idea.vim.handler.toMotionOrError
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.PsiHelper
|
import com.maddyhome.idea.vim.helper.PsiHelper
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import com.maddyhome.idea.vim.helper.vimStateMachine
|
import com.maddyhome.idea.vim.helper.vimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -233,7 +233,7 @@ private object FileTypePatterns {
|
|||||||
} else if (fileTypeName == "CMakeLists.txt" || fileName == "CMakeLists") {
|
} else if (fileTypeName == "CMakeLists.txt" || fileName == "CMakeLists") {
|
||||||
this.cMakePatterns
|
this.cMakePatterns
|
||||||
} else {
|
} else {
|
||||||
return null
|
this.htmlPatterns
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,8 +29,8 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
|
@@ -44,11 +44,11 @@ import com.maddyhome.idea.vim.api.VimEditor
|
|||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.common.CommandAlias
|
import com.maddyhome.idea.vim.common.CommandAlias
|
||||||
import com.maddyhome.idea.vim.common.CommandAliasHandler
|
import com.maddyhome.idea.vim.common.CommandAliasHandler
|
||||||
import com.maddyhome.idea.vim.key.CommandNode
|
import com.maddyhome.idea.vim.common.CommandNode
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.common.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.key.Node
|
import com.maddyhome.idea.vim.common.Node
|
||||||
import com.maddyhome.idea.vim.key.RootNode
|
import com.maddyhome.idea.vim.common.RootNode
|
||||||
import com.maddyhome.idea.vim.key.addLeafs
|
import com.maddyhome.idea.vim.common.addLeafs
|
||||||
import com.maddyhome.idea.vim.ex.ranges.Ranges
|
import com.maddyhome.idea.vim.ex.ranges.Ranges
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
import com.maddyhome.idea.vim.group.KeyGroup
|
import com.maddyhome.idea.vim.group.KeyGroup
|
||||||
|
@@ -24,10 +24,10 @@ import com.maddyhome.idea.vim.api.ExecutionContext
|
|||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
||||||
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper
|
import com.maddyhome.idea.vim.helper.SearchHelper
|
||||||
|
@@ -65,14 +65,15 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
|
|
||||||
private class RwrVisual : ExtensionHandler {
|
private class RwrVisual : ExtensionHandler {
|
||||||
override fun execute(editor: VimEditor, context: ExecutionContext) {
|
override fun execute(editor: VimEditor, context: ExecutionContext) {
|
||||||
|
val caretsAndSelections = mutableMapOf<VimCaret, VimSelection>()
|
||||||
val typeInEditor = SelectionType.fromSubMode(editor.subMode)
|
val typeInEditor = SelectionType.fromSubMode(editor.subMode)
|
||||||
editor.forEachCaret { caret ->
|
editor.forEachCaret { caret ->
|
||||||
val selectionStart = caret.selectionStart
|
val selectionStart = caret.selectionStart
|
||||||
val selectionEnd = caret.selectionEnd
|
val selectionEnd = caret.selectionEnd
|
||||||
|
|
||||||
val visualSelection = caret to VimSelection.create(selectionStart, selectionEnd - 1, typeInEditor, editor)
|
caretsAndSelections += caret to VimSelection.create(selectionStart, selectionEnd - 1, typeInEditor, editor)
|
||||||
doReplace(editor.ij, caret, PutData.VisualSelection(mapOf(visualSelection), typeInEditor))
|
|
||||||
}
|
}
|
||||||
|
doReplace(editor.ij, PutData.VisualSelection(caretsAndSelections, typeInEditor))
|
||||||
editor.exitVisualModeNative()
|
editor.exitVisualModeNative()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,12 +97,12 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
val lineStart = editor.getLineStartOffset(logicalLine)
|
val lineStart = editor.getLineStartOffset(logicalLine)
|
||||||
val lineEnd = editor.getLineEndOffset(logicalLine, true)
|
val lineEnd = editor.getLineEndOffset(logicalLine, true)
|
||||||
|
|
||||||
val visualSelection = caret to VimSelection.create(lineStart, lineEnd, SelectionType.LINE_WISE, editor)
|
caretsAndSelections += caret to VimSelection.create(lineStart, lineEnd, SelectionType.LINE_WISE, editor)
|
||||||
caretsAndSelections += visualSelection
|
|
||||||
|
|
||||||
doReplace(editor.ij, caret, PutData.VisualSelection(mapOf(visualSelection), SelectionType.LINE_WISE))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val visualSelection = PutData.VisualSelection(caretsAndSelections, SelectionType.LINE_WISE)
|
||||||
|
doReplace(editor.ij, visualSelection)
|
||||||
|
|
||||||
editor.forEachCaret { caret ->
|
editor.forEachCaret { caret ->
|
||||||
val vimStart = caretsAndSelections[caret]?.vimStart
|
val vimStart = caretsAndSelections[caret]?.vimStart
|
||||||
if (vimStart != null) {
|
if (vimStart != null) {
|
||||||
@@ -125,8 +126,7 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
),
|
),
|
||||||
selectionType
|
selectionType
|
||||||
)
|
)
|
||||||
// todo multicaret
|
doReplace(editor, visualSelection)
|
||||||
doReplace(editor, editor.vim.primaryCaret(), visualSelection)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,9 +147,8 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
@NonNls
|
@NonNls
|
||||||
private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
|
private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
|
||||||
|
|
||||||
private fun doReplace(editor: Editor, caret: VimCaret, visualSelection: PutData.VisualSelection) {
|
private fun doReplace(editor: Editor, visualSelection: PutData.VisualSelection) {
|
||||||
val lastRegisterChar = injector.registerGroup.lastRegisterChar
|
val savedRegister = VimPlugin.getRegister().lastRegister ?: return
|
||||||
val savedRegister = caret.registerStorage.getRegister(lastRegisterChar) ?: return
|
|
||||||
|
|
||||||
var usedType = savedRegister.type
|
var usedType = savedRegister.type
|
||||||
var usedText = savedRegister.text
|
var usedText = savedRegister.text
|
||||||
@@ -174,8 +173,8 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
VimPlugin.getPut().putText(IjVimEditor(editor), IjExecutionContext(EditorDataContext.init(editor)), putData)
|
VimPlugin.getPut().putText(IjVimEditor(editor), IjExecutionContext(EditorDataContext.init(editor)), putData)
|
||||||
}
|
}
|
||||||
|
|
||||||
caret.registerStorage.saveRegister(savedRegister.name, savedRegister)
|
VimPlugin.getRegister().saveRegister(savedRegister.name, savedRegister)
|
||||||
caret.registerStorage.saveRegister(VimPlugin.getRegister().defaultRegister, savedRegister)
|
VimPlugin.getRegister().saveRegister(VimPlugin.getRegister().defaultRegister, savedRegister)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ import com.intellij.openapi.application.runWriteAction
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimChangeGroup
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
@@ -32,21 +32,22 @@ import com.maddyhome.idea.vim.common.TextRange
|
|||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.getRegisterForCaret
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.getRegister
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.inputKeyStroke
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.inputKeyStroke
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.inputString
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.inputString
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegisterForCaret
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegister
|
||||||
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.editorMode
|
import com.maddyhome.idea.vim.helper.editorMode
|
||||||
|
import com.maddyhome.idea.vim.helper.runWithEveryCaretAndRestore
|
||||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimCaret
|
import com.maddyhome.idea.vim.newapi.IjVimCaret
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimEditor
|
import com.maddyhome.idea.vim.newapi.IjVimEditor
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import com.maddyhome.idea.vim.options.helpers.ClipboardOptionHelper
|
import com.maddyhome.idea.vim.options.helpers.ClipboardOptionHelper
|
||||||
import com.maddyhome.idea.vim.put.PutData
|
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
@@ -85,22 +86,20 @@ class VimSurroundExtension : VimExtension {
|
|||||||
override val isRepeatable = true
|
override val isRepeatable = true
|
||||||
|
|
||||||
override fun execute(editor: VimEditor, context: ExecutionContext) {
|
override fun execute(editor: VimEditor, context: ExecutionContext) {
|
||||||
setOperatorFunction(Operator())
|
setOperatorFunction(Operator(supportsMultipleCursors = false)) // TODO
|
||||||
executeNormalWithoutMapping(injector.parser.parseKeys("g@"), editor.ij)
|
executeNormalWithoutMapping(injector.parser.parseKeys("g@"), editor.ij)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class VSurroundHandler : ExtensionHandler {
|
private class VSurroundHandler : ExtensionHandler {
|
||||||
override fun execute(editor: VimEditor, context: ExecutionContext) {
|
override fun execute(editor: VimEditor, context: ExecutionContext) {
|
||||||
val selectionStart = editor.ij.caretModel.primaryCaret.selectionStart
|
|
||||||
// NB: Operator ignores SelectionType anyway
|
// NB: Operator ignores SelectionType anyway
|
||||||
if (!Operator().apply(editor.ij, context.ij, SelectionType.CHARACTER_WISE)) {
|
if (!Operator(supportsMultipleCursors = true).apply(editor.ij, context.ij, SelectionType.CHARACTER_WISE)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
runWriteAction {
|
runWriteAction {
|
||||||
// Leave visual mode
|
// Leave visual mode
|
||||||
executeNormalWithoutMapping(injector.parser.parseKeys("<Esc>"), editor.ij)
|
executeNormalWithoutMapping(injector.parser.parseKeys("<Esc>"), editor.ij)
|
||||||
editor.ij.caretModel.moveToOffset(selectionStart)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,70 +115,37 @@ class VimSurroundExtension : VimExtension {
|
|||||||
if (charTo.code == 0) return
|
if (charTo.code == 0) return
|
||||||
|
|
||||||
val newSurround = getOrInputPair(charTo, editor.ij) ?: return
|
val newSurround = getOrInputPair(charTo, editor.ij) ?: return
|
||||||
runWriteAction { change(editor, context, charFrom, newSurround) }
|
runWriteAction { change(editor.ij, charFrom, newSurround) }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun change(editor: VimEditor, context: ExecutionContext, charFrom: Char, newSurround: Pair<String, String>?) {
|
fun change(editor: Editor, charFrom: Char, newSurround: Pair<String, String>?) {
|
||||||
// Save old register values for carets
|
editor.runWithEveryCaretAndRestore { changeAtCaret(editor, charFrom, newSurround) }
|
||||||
val surroundings = editor.sortedCarets()
|
}
|
||||||
.map {
|
|
||||||
val oldValue: List<KeyStroke>? = getRegisterForCaret(REGISTER, it)
|
fun changeAtCaret(editor: Editor, charFrom: Char, newSurround: Pair<String, String>?) {
|
||||||
setRegisterForCaret(REGISTER, it, null)
|
// We take over the " register, so preserve it
|
||||||
SurroundingInfo(it, null, oldValue, null)
|
val oldValue: List<KeyStroke>? = getRegister(REGISTER)
|
||||||
}
|
// Empty the " register
|
||||||
|
setRegister(REGISTER, null)
|
||||||
// Delete surrounding's content
|
// Extract the inner value
|
||||||
perform("di" + pick(charFrom), editor.ij)
|
perform("di" + pick(charFrom), editor)
|
||||||
|
val innerValue: MutableList<KeyStroke> = getRegister(REGISTER)?.toMutableList() ?: mutableListOf()
|
||||||
// Add info about surrounding's inner text and location
|
// If the surrounding characters were not found, the register will be empty
|
||||||
surroundings.forEach {
|
if (innerValue.isNotEmpty()) {
|
||||||
val registerValue = getRegisterForCaret(REGISTER, it.caret)
|
// Delete the surrounding
|
||||||
val innerValue = if (registerValue.isNullOrEmpty()) null else registerValue
|
perform("da" + pick(charFrom), editor)
|
||||||
it.innerText = innerValue
|
// Insert the surrounding characters and paste
|
||||||
|
if (newSurround != null) {
|
||||||
val lineEndOffset = injector.engineEditorHelper.getLineEndOffset(editor, it.caret.getLine().line, false)
|
innerValue.addAll(0, injector.parser.parseKeys(newSurround.first))
|
||||||
if (lineEndOffset == it.caret.offset.point) {
|
innerValue.addAll(injector.parser.parseKeys(newSurround.second))
|
||||||
it.isLineEnd = true
|
|
||||||
}
|
}
|
||||||
|
pasteSurround(innerValue, editor)
|
||||||
|
// Jump back to start
|
||||||
|
executeNormalWithoutMapping(injector.parser.parseKeys("`["), editor)
|
||||||
}
|
}
|
||||||
|
// Restore the old value
|
||||||
// Remove surrounding
|
setRegister(REGISTER, oldValue)
|
||||||
perform("da" + pick(charFrom), editor.ij)
|
|
||||||
|
|
||||||
surroundings.forEach {
|
|
||||||
if (it.innerText == null && getRegisterForCaret(REGISTER, it.caret)?.isNotEmpty() == true) {
|
|
||||||
it.innerText = emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
// caret should be placed at the first char of inserted text
|
|
||||||
// the best solution would be using [ mark after the paste, but marks are not supported by multicaret
|
|
||||||
// todo
|
|
||||||
if (it.innerText != null) {
|
|
||||||
it.offset = it.caret.offset.point
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
surroundings
|
|
||||||
.filter { it.innerText != null } // we do nothing with carets that are not inside the surrounding
|
|
||||||
.map { surrounding ->
|
|
||||||
val innerValue = injector.parser.toPrintableString(surrounding.innerText!!)
|
|
||||||
val text = newSurround?.let { it.first + innerValue + it.second } ?: innerValue
|
|
||||||
val textData = PutData.TextData(text, SelectionType.CHARACTER_WISE, emptyList())
|
|
||||||
val putData = PutData(textData, null, 1, insertTextBeforeCaret = !surrounding.isLineEnd, rawIndent = true, caretAfterInsertedText = false)
|
|
||||||
|
|
||||||
surrounding.caret to putData
|
|
||||||
}.forEach {
|
|
||||||
injector.put.putTextForCaret(editor, it.first, context, it.second)
|
|
||||||
}
|
|
||||||
|
|
||||||
surroundings.forEach {
|
|
||||||
it.restoreRegister()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surroundings.size == 1) {
|
|
||||||
surroundings.first().moveCaret()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun perform(sequence: String, editor: Editor) {
|
private fun perform(sequence: String, editor: Editor) {
|
||||||
@@ -187,6 +153,21 @@ class VimSurroundExtension : VimExtension {
|
|||||||
.use { executeNormalWithoutMapping(injector.parser.parseKeys("\"" + REGISTER + sequence), editor) }
|
.use { executeNormalWithoutMapping(injector.parser.parseKeys("\"" + REGISTER + sequence), editor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun pasteSurround(
|
||||||
|
innerValue: List<KeyStroke?>,
|
||||||
|
editor: Editor,
|
||||||
|
) { // This logic is direct from vim-surround
|
||||||
|
val offset = editor.caretModel.offset
|
||||||
|
val lineEndOffset = EditorHelper.getLineEndForOffset(editor, offset)
|
||||||
|
val motionEndMark = VimPlugin.getMark().getMark(editor.vim, ']')
|
||||||
|
val motionEndOffset = if (motionEndMark != null) {
|
||||||
|
EditorHelper.getOffset(editor, motionEndMark.logicalLine, motionEndMark.col)
|
||||||
|
} else -1
|
||||||
|
val pasteCommand = if (motionEndOffset == lineEndOffset && offset + 1 == lineEndOffset) "p" else "P"
|
||||||
|
setRegister(REGISTER, innerValue)
|
||||||
|
perform(pasteCommand, editor)
|
||||||
|
}
|
||||||
|
|
||||||
private fun pick(charFrom: Char) = when (charFrom) {
|
private fun pick(charFrom: Char) = when (charFrom) {
|
||||||
'a' -> '>'
|
'a' -> '>'
|
||||||
'r' -> ']'
|
'r' -> ']'
|
||||||
@@ -195,18 +176,6 @@ class VimSurroundExtension : VimExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class SurroundingInfo(val caret: VimCaret, var innerText: List<KeyStroke>?, val oldRegisterContent: List<KeyStroke>?, var offset: Int?, var isLineEnd: Boolean = false) {
|
|
||||||
fun restoreRegister() {
|
|
||||||
setRegisterForCaret(REGISTER, caret, oldRegisterContent)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun moveCaret() {
|
|
||||||
if (innerText != null && offset != null) {
|
|
||||||
caret.moveToOffset(offset!! + if (isLineEnd) 1 else 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DSurroundHandler : ExtensionHandler {
|
private class DSurroundHandler : ExtensionHandler {
|
||||||
override val isRepeatable = true
|
override val isRepeatable = true
|
||||||
|
|
||||||
@@ -215,29 +184,47 @@ class VimSurroundExtension : VimExtension {
|
|||||||
val charFrom = getChar(editor.ij)
|
val charFrom = getChar(editor.ij)
|
||||||
if (charFrom.code == 0) return
|
if (charFrom.code == 0) return
|
||||||
|
|
||||||
runWriteAction { CSurroundHandler.change(editor, context, charFrom, null) }
|
runWriteAction { CSurroundHandler.change(editor.ij, charFrom, null) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Operator : OperatorFunction {
|
private class Operator(private val supportsMultipleCursors: Boolean) : OperatorFunction {
|
||||||
override fun apply(editor: Editor, context: DataContext, selectionType: SelectionType): Boolean {
|
override fun apply(editor: Editor, context: DataContext, selectionType: SelectionType): Boolean {
|
||||||
val c = getChar(editor)
|
val c = getChar(editor)
|
||||||
if (c.code == 0) return true
|
if (c.code == 0) return true
|
||||||
|
|
||||||
val pair = getOrInputPair(c, editor) ?: return false
|
val pair = getOrInputPair(c, editor) ?: return false
|
||||||
// XXX: Will it work with line-wise or block-wise selections?
|
|
||||||
val range = getSurroundRange(editor) ?: return false
|
|
||||||
runWriteAction {
|
runWriteAction {
|
||||||
val change = VimPlugin.getChange()
|
val change = VimPlugin.getChange()
|
||||||
val leftSurround = pair.first
|
if (supportsMultipleCursors) {
|
||||||
val primaryCaret = editor.caretModel.primaryCaret
|
editor.runWithEveryCaretAndRestore {
|
||||||
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.startOffset, leftSurround)
|
applyOnce(editor, change, pair)
|
||||||
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.endOffset + leftSurround.length, pair.second)
|
}
|
||||||
// Jump back to start
|
}
|
||||||
executeNormalWithoutMapping(injector.parser.parseKeys("`["), editor)
|
else {
|
||||||
|
applyOnce(editor, change, pair)
|
||||||
|
// Jump back to start
|
||||||
|
executeNormalWithoutMapping(injector.parser.parseKeys("`["), editor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun applyOnce(editor: Editor, change: VimChangeGroup, pair: Pair<String, String>) {
|
||||||
|
// XXX: Will it work with line-wise or block-wise selections?
|
||||||
|
val range = getSurroundRange(editor)
|
||||||
|
if (range != null) {
|
||||||
|
val primaryCaret = editor.caretModel.primaryCaret
|
||||||
|
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.startOffset, pair.first)
|
||||||
|
change.insertText(
|
||||||
|
IjVimEditor(editor),
|
||||||
|
IjVimCaret(primaryCaret),
|
||||||
|
range.endOffset + pair.first.length,
|
||||||
|
pair.second
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getSurroundRange(editor: Editor): TextRange? = when (editor.editorMode) {
|
private fun getSurroundRange(editor: Editor): TextRange? = when (editor.editorMode) {
|
||||||
VimStateMachine.Mode.COMMAND -> VimPlugin.getMark().getChangeMarks(editor.vim)
|
VimStateMachine.Mode.COMMAND -> VimPlugin.getMark().getChangeMarks(editor.vim)
|
||||||
|
@@ -50,7 +50,10 @@ import com.maddyhome.idea.vim.group.visual.VisualModeHelperKt;
|
|||||||
import com.maddyhome.idea.vim.helper.*;
|
import com.maddyhome.idea.vim.helper.*;
|
||||||
import com.maddyhome.idea.vim.key.KeyHandlerKeeper;
|
import com.maddyhome.idea.vim.key.KeyHandlerKeeper;
|
||||||
import com.maddyhome.idea.vim.listener.VimInsertListener;
|
import com.maddyhome.idea.vim.listener.VimInsertListener;
|
||||||
import com.maddyhome.idea.vim.newapi.*;
|
import com.maddyhome.idea.vim.newapi.IjExecutionContext;
|
||||||
|
import com.maddyhome.idea.vim.newapi.IjExecutionContextKt;
|
||||||
|
import com.maddyhome.idea.vim.newapi.IjVimCaret;
|
||||||
|
import com.maddyhome.idea.vim.newapi.IjVimEditor;
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants;
|
import com.maddyhome.idea.vim.options.OptionConstants;
|
||||||
import com.maddyhome.idea.vim.options.OptionScope;
|
import com.maddyhome.idea.vim.options.OptionScope;
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString;
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString;
|
||||||
@@ -200,6 +203,61 @@ public class ChangeGroup extends VimChangeGroupBase {
|
|||||||
return new Pair<>(range, type);
|
return new Pair<>(range, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the range of text.
|
||||||
|
*
|
||||||
|
* @param editor The editor to delete the text from
|
||||||
|
* @param caret The caret to be moved after deletion
|
||||||
|
* @param range The range to delete
|
||||||
|
* @param type The type of deletion
|
||||||
|
* @param isChange Is from a change action
|
||||||
|
* @return true if able to delete the text, false if not
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean deleteRange(@NotNull VimEditor editor,
|
||||||
|
@NotNull VimCaret caret,
|
||||||
|
@NotNull TextRange range,
|
||||||
|
@Nullable SelectionType type,
|
||||||
|
boolean isChange,
|
||||||
|
boolean noYank) {
|
||||||
|
|
||||||
|
// Update the last column before we delete, or we might be retrieving the data for a line that no longer exists
|
||||||
|
UserDataManager.setVimLastColumn(((IjVimCaret) caret).getCaret(), InlayHelperKt.getInlayAwareVisualColumn(((IjVimCaret) caret).getCaret()));
|
||||||
|
|
||||||
|
boolean removeLastNewLine = removeLastNewLine(editor, range, type);
|
||||||
|
final boolean res = deleteText(editor, range, type, noYank);
|
||||||
|
if (removeLastNewLine) {
|
||||||
|
int textLength = ((IjVimEditor) editor).getEditor().getDocument().getTextLength();
|
||||||
|
((IjVimEditor) editor).getEditor().getDocument().deleteString(textLength - 1, textLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
int pos = EditorHelper.normalizeOffset(((IjVimEditor) editor).getEditor(), range.getStartOffset(), isChange);
|
||||||
|
if (type == SelectionType.LINE_WISE) {
|
||||||
|
pos = VimPlugin.getMotion()
|
||||||
|
.moveCaretToLineWithStartOfLineOption(editor, editor.offsetToLogicalPosition(pos).getLine(),
|
||||||
|
caret);
|
||||||
|
}
|
||||||
|
injector.getMotion().moveCaret(editor, caret, pos);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean removeLastNewLine(@NotNull VimEditor editor, @NotNull TextRange range, @Nullable SelectionType type) {
|
||||||
|
int endOffset = range.getEndOffset();
|
||||||
|
int fileSize = EditorHelperRt.getFileSize(((IjVimEditor) editor).getEditor());
|
||||||
|
if (endOffset > fileSize) {
|
||||||
|
if (injector.getOptionService().isSet(OptionScope.GLOBAL.INSTANCE, OptionConstants.ideastrictmodeName, OptionConstants.ideastrictmodeName)) {
|
||||||
|
throw new IllegalStateException("Incorrect offset. File size: " + fileSize + ", offset: " + endOffset);
|
||||||
|
}
|
||||||
|
endOffset = fileSize;
|
||||||
|
}
|
||||||
|
return type == SelectionType.LINE_WISE &&
|
||||||
|
range.getStartOffset() != 0 &&
|
||||||
|
((IjVimEditor) editor).getEditor().getDocument().getCharsSequence().charAt(endOffset - 1) != '\n' &&
|
||||||
|
endOffset == fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void insertLineAround(@NotNull VimEditor editor, @NotNull ExecutionContext context, int shift) {
|
public void insertLineAround(@NotNull VimEditor editor, @NotNull ExecutionContext context, int shift) {
|
||||||
com.maddyhome.idea.vim.newapi.ChangeGroupKt.insertLineAround(editor, context, shift);
|
com.maddyhome.idea.vim.newapi.ChangeGroupKt.insertLineAround(editor, context, shift);
|
||||||
@@ -228,7 +286,8 @@ public class ChangeGroup extends VimChangeGroupBase {
|
|||||||
@NotNull VimCaret caret,
|
@NotNull VimCaret caret,
|
||||||
@NotNull ExecutionContext context,
|
@NotNull ExecutionContext context,
|
||||||
@NotNull Argument argument,
|
@NotNull Argument argument,
|
||||||
@NotNull OperatorArguments operatorArguments) {
|
@NotNull OperatorArguments operatorArguments,
|
||||||
|
boolean noYank) {
|
||||||
int count0 = operatorArguments.getCount0();
|
int count0 = operatorArguments.getCount0();
|
||||||
// Vim treats cw as ce and cW as cE if cursor is on a non-blank character
|
// Vim treats cw as ce and cW as cE if cursor is on a non-blank character
|
||||||
final Command motion = argument.getMotion();
|
final Command motion = argument.getMotion();
|
||||||
@@ -306,7 +365,7 @@ public class ChangeGroup extends VimChangeGroupBase {
|
|||||||
Pair<TextRange, SelectionType> deleteRangeAndType =
|
Pair<TextRange, SelectionType> deleteRangeAndType =
|
||||||
getDeleteRangeAndType(editor, caret, context, argument, true, operatorArguments.withCount0(count0));
|
getDeleteRangeAndType(editor, caret, context, argument, true, operatorArguments.withCount0(count0));
|
||||||
if (deleteRangeAndType == null) return false;
|
if (deleteRangeAndType == null) return false;
|
||||||
return changeRange(editor, caret, deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), context);
|
return changeRange(editor, caret, deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), context, noYank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +495,8 @@ public class ChangeGroup extends VimChangeGroupBase {
|
|||||||
@NotNull VimCaret caret,
|
@NotNull VimCaret caret,
|
||||||
@NotNull TextRange range,
|
@NotNull TextRange range,
|
||||||
@NotNull SelectionType type,
|
@NotNull SelectionType type,
|
||||||
ExecutionContext context) {
|
@Nullable ExecutionContext context,
|
||||||
|
boolean noYank) {
|
||||||
int col = 0;
|
int col = 0;
|
||||||
int lines = 0;
|
int lines = 0;
|
||||||
if (type == SelectionType.BLOCK_WISE) {
|
if (type == SelectionType.BLOCK_WISE) {
|
||||||
@@ -450,7 +510,7 @@ public class ChangeGroup extends VimChangeGroupBase {
|
|||||||
|
|
||||||
final VimLogicalPosition lp = editor.offsetToLogicalPosition(injector.getMotion().moveCaretToLineStartSkipLeading(editor, caret));
|
final VimLogicalPosition lp = editor.offsetToLogicalPosition(injector.getMotion().moveCaretToLineStartSkipLeading(editor, caret));
|
||||||
|
|
||||||
boolean res = deleteRange(editor, caret, range, type, true);
|
boolean res = deleteRange(editor, caret, range, type, true, noYank);
|
||||||
if (res) {
|
if (res) {
|
||||||
if (type == SelectionType.LINE_WISE) {
|
if (type == SelectionType.LINE_WISE) {
|
||||||
// Please don't use `getDocument().getText().isEmpty()` because it converts CharSequence into String
|
// Please don't use `getDocument().getText().isEmpty()` because it converts CharSequence into String
|
||||||
@@ -675,7 +735,7 @@ public class ChangeGroup extends VimChangeGroupBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos > wsoff) {
|
if (pos > wsoff) {
|
||||||
deleteText(editor, new TextRange(wsoff, pos), null, caret);
|
deleteText(editor, new TextRange(wsoff, pos), null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,8 @@ import com.maddyhome.idea.vim.action.ComplicatedKeysAction;
|
|||||||
import com.maddyhome.idea.vim.action.VimShortcutKeyAction;
|
import com.maddyhome.idea.vim.action.VimShortcutKeyAction;
|
||||||
import com.maddyhome.idea.vim.api.*;
|
import com.maddyhome.idea.vim.api.*;
|
||||||
import com.maddyhome.idea.vim.command.MappingMode;
|
import com.maddyhome.idea.vim.command.MappingMode;
|
||||||
import com.maddyhome.idea.vim.key.Node;
|
import com.maddyhome.idea.vim.common.Node;
|
||||||
|
import com.maddyhome.idea.vim.common.NodesKt;
|
||||||
import com.maddyhome.idea.vim.ex.ExOutputModel;
|
import com.maddyhome.idea.vim.ex.ExOutputModel;
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
||||||
import com.maddyhome.idea.vim.helper.HelperKt;
|
import com.maddyhome.idea.vim.helper.HelperKt;
|
||||||
|
@@ -92,7 +92,7 @@ public class ProcessGroup extends VimProcessGroupBase {
|
|||||||
String initText = getRange(((IjVimEditor) editor).getEditor(), cmd);
|
String initText = getRange(((IjVimEditor) editor).getEditor(), cmd);
|
||||||
VimStateMachine.getInstance(editor).pushModes(VimStateMachine.Mode.CMD_LINE, VimStateMachine.SubMode.NONE);
|
VimStateMachine.getInstance(editor).pushModes(VimStateMachine.Mode.CMD_LINE, VimStateMachine.SubMode.NONE);
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
ExEntryPanel panel = ExEntryPanel.getInstance();
|
||||||
panel.activate(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext(), ":", initText, 1);
|
panel.activate(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext(), ":", initText, cmd.getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -123,7 +123,7 @@ public class ProcessGroup extends VimProcessGroupBase {
|
|||||||
|
|
||||||
logger.debug("processing command");
|
logger.debug("processing command");
|
||||||
|
|
||||||
final String text = panel.getText();
|
String text = panel.getText();
|
||||||
|
|
||||||
if (!panel.getLabel().equals(":")) {
|
if (!panel.getLabel().equals(":")) {
|
||||||
// Search is handled via Argument.Type.EX_STRING. Although ProcessExEntryAction is registered as the handler for
|
// Search is handled via Argument.Type.EX_STRING. Although ProcessExEntryAction is registered as the handler for
|
||||||
@@ -134,7 +134,15 @@ public class ProcessGroup extends VimProcessGroupBase {
|
|||||||
|
|
||||||
if (logger.isDebugEnabled()) logger.debug("swing=" + SwingUtilities.isEventDispatchThread());
|
if (logger.isDebugEnabled()) logger.debug("swing=" + SwingUtilities.isEventDispatchThread());
|
||||||
|
|
||||||
VimInjectorKt.getInjector().getVimscriptExecutor().execute(text, editor, context, skipHistory(editor), true, CommandLineVimLContext.INSTANCE);
|
int repeat = 1;
|
||||||
|
if (text.contains("raction ")) {
|
||||||
|
text = text.replace("raction ", "action ");
|
||||||
|
repeat = panel.getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < repeat; i++) {
|
||||||
|
VimInjectorKt.getInjector().getVimscriptExecutor().execute(text, editor, context, skipHistory(editor), true, CommandLineVimLContext.INSTANCE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ExException e) {
|
catch (ExException e) {
|
||||||
VimPlugin.showMessage(e.getMessage());
|
VimPlugin.showMessage(e.getMessage());
|
||||||
|
@@ -34,8 +34,8 @@ import com.maddyhome.idea.vim.api.ExecutionContext
|
|||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.command.isBlock
|
import com.maddyhome.idea.vim.command.isBlock
|
||||||
import com.maddyhome.idea.vim.command.isChar
|
import com.maddyhome.idea.vim.command.isChar
|
||||||
import com.maddyhome.idea.vim.command.isLine
|
import com.maddyhome.idea.vim.command.isLine
|
||||||
@@ -60,14 +60,10 @@ import java.awt.datatransfer.DataFlavor
|
|||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class PutGroup : VimPutBase() {
|
class PutGroup : VimPutBase() {
|
||||||
override fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData, updateVisualMarks: Boolean): Boolean {
|
override fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData): Boolean {
|
||||||
val additionalData = collectPreModificationData(editor, data)
|
val additionalData = collectPreModificationData(editor, data)
|
||||||
data.visualSelection?.let { deleteSelectedText(editor, data) }
|
|
||||||
val processedText = processText(editor, data) ?: return false
|
val processedText = processText(editor, data) ?: return false
|
||||||
putForCaret(editor, caret, data, additionalData, context, processedText)
|
putForCaret(editor, caret, data, additionalData, context, processedText)
|
||||||
if (editor.primaryCaret() == caret && updateVisualMarks) {
|
|
||||||
wrapInsertedTextWithVisualMarks(editor, data, processedText)
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +97,22 @@ class PutGroup : VimPutBase() {
|
|||||||
EditorHelper.getOrderedCaretsList(editor.ij).map { IjVimCaret(it) }
|
EditorHelper.getOrderedCaretsList(editor.ij).map { IjVimCaret(it) }
|
||||||
}
|
}
|
||||||
injector.application.runWriteAction {
|
injector.application.runWriteAction {
|
||||||
myCarets.forEach { caret -> putForCaret(editor, caret, data, additionalData, context, text) }
|
val singleCaret = myCarets.singleOrNull()
|
||||||
|
if (singleCaret != null) {
|
||||||
|
putForCaret(editor, singleCaret, data, additionalData, context, text)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val lines = text.text.split('\n')
|
||||||
|
if (lines.size != myCarets.size) {
|
||||||
|
myCarets.forEach { caret -> putForCaret(editor, caret, data, additionalData, context, text) }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myCarets.asReversed().forEachIndexed { index, caret ->
|
||||||
|
val line = ProcessedTextData(lines[index], text.typeInRegister, text.transferableData)
|
||||||
|
putForCaret(editor, caret, data, additionalData, context, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,9 +133,7 @@ class PutGroup : VimPutBase() {
|
|||||||
editor, caret, context, text.text, text.typeInRegister, subMode,
|
editor, caret, context, text.text, text.typeInRegister, subMode,
|
||||||
startOffset, data.count, data.indent, data.caretAfterInsertedText
|
startOffset, data.count, data.indent, data.caretAfterInsertedText
|
||||||
)
|
)
|
||||||
if (caret == editor.primaryCaret()) {
|
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, endOffset))
|
||||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, endOffset))
|
|
||||||
}
|
|
||||||
moveCaretToEndPosition(
|
moveCaretToEndPosition(
|
||||||
editor,
|
editor,
|
||||||
caret,
|
caret,
|
||||||
@@ -235,13 +244,13 @@ class PutGroup : VimPutBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun putTextViaIde(
|
private fun putTextViaIde(
|
||||||
pasteProvider: PasteProvider,
|
pasteProvider: PasteProvider,
|
||||||
vimEditor: VimEditor,
|
vimEditor: VimEditor,
|
||||||
vimContext: ExecutionContext,
|
vimContext: ExecutionContext,
|
||||||
text: ProcessedTextData,
|
text: ProcessedTextData,
|
||||||
subMode: VimStateMachine.SubMode,
|
subMode: VimStateMachine.SubMode,
|
||||||
data: PutData,
|
data: PutData,
|
||||||
additionalData: Map<String, Any>,
|
additionalData: Map<String, Any>,
|
||||||
) {
|
) {
|
||||||
val editor = (vimEditor as IjVimEditor).editor
|
val editor = (vimEditor as IjVimEditor).editor
|
||||||
val context = vimContext.context as DataContext
|
val context = vimContext.context as DataContext
|
||||||
|
@@ -18,16 +18,18 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.group.copy
|
package com.maddyhome.idea.vim.group.copy
|
||||||
|
|
||||||
|
import com.intellij.openapi.editor.Caret
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.action.motion.updown.MotionDownLess1FirstNonSpaceAction
|
import com.maddyhome.idea.vim.action.motion.updown.MotionDownLess1FirstNonSpaceAction
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
import com.maddyhome.idea.vim.command.Argument
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
import com.maddyhome.idea.vim.listener.VimYankListener
|
import com.maddyhome.idea.vim.listener.VimYankListener
|
||||||
@@ -44,8 +46,8 @@ class YankGroup : YankGroupBase() {
|
|||||||
|
|
||||||
fun removeListener(listener: VimYankListener) = yankListeners.remove(listener)
|
fun removeListener(listener: VimYankListener) = yankListeners.remove(listener)
|
||||||
|
|
||||||
private fun notifyListeners(editor: VimEditor, textRange: TextRange) = yankListeners.forEach {
|
private fun notifyListeners(editor: Editor, textRange: TextRange) = yankListeners.forEach {
|
||||||
it.yankPerformed(editor.ij, textRange)
|
it.yankPerformed(editor, textRange)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,38 +67,32 @@ class YankGroup : YankGroupBase() {
|
|||||||
operatorArguments: OperatorArguments
|
operatorArguments: OperatorArguments
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val motion = argument.motion
|
val motion = argument.motion
|
||||||
val type = if (motion.isLinewiseMotion()) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
|
|
||||||
|
|
||||||
val nativeCaretCount = editor.nativeCarets().size
|
val caretModel = editor.ij.caretModel
|
||||||
if (nativeCaretCount <= 0) return false
|
if (caretModel.caretCount <= 0) return false
|
||||||
|
|
||||||
val carretToRange = HashMap<VimCaret, TextRange>(nativeCaretCount)
|
val ranges = ArrayList<Pair<Int, Int>>(caretModel.caretCount)
|
||||||
val ranges = ArrayList<Pair<Int, Int>>(nativeCaretCount)
|
|
||||||
|
|
||||||
// This logic is from original vim
|
// This logic is from original vim
|
||||||
val startOffsets = if (argument.motion.action is MotionDownLess1FirstNonSpaceAction) null else HashMap<VimCaret, Int>(nativeCaretCount)
|
val startOffsets =
|
||||||
|
if (argument.motion.action is MotionDownLess1FirstNonSpaceAction) null else HashMap<Caret, Int>(caretModel.caretCount)
|
||||||
|
|
||||||
for (caret in editor.nativeCarets()) {
|
for (caret in caretModel.allCarets) {
|
||||||
val motionRange = injector.motion.getMotionRange(editor, caret, context, argument, operatorArguments)
|
val motionRange = MotionGroup.getMotionRange(editor.ij, caret, context.ij, argument, operatorArguments)
|
||||||
?: continue
|
?: continue
|
||||||
|
|
||||||
assert(motionRange.size() == 1)
|
assert(motionRange.size() == 1)
|
||||||
ranges.add(motionRange.startOffset to motionRange.endOffset)
|
ranges.add(motionRange.startOffset to motionRange.endOffset)
|
||||||
startOffsets?.put(caret, motionRange.normalize().startOffset)
|
startOffsets?.put(caret, motionRange.normalize().startOffset)
|
||||||
carretToRange[caret] = TextRange(motionRange.startOffset, motionRange.endOffset)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val type = if (motion.isLinewiseMotion()) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
|
||||||
val range = getTextRange(ranges, type) ?: return false
|
val range = getTextRange(ranges, type) ?: return false
|
||||||
|
|
||||||
if (range.size() == 0) return false
|
if (range.size() == 0) return false
|
||||||
|
|
||||||
return yankRange(
|
val selectionType = if (type == SelectionType.CHARACTER_WISE && range.isMultiple) SelectionType.BLOCK_WISE else type
|
||||||
editor,
|
return yankRange(editor.ij, range, selectionType, startOffsets)
|
||||||
carretToRange,
|
|
||||||
range,
|
|
||||||
type,
|
|
||||||
startOffsets
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,21 +103,19 @@ class YankGroup : YankGroupBase() {
|
|||||||
* @return true if able to yank the lines, false if not
|
* @return true if able to yank the lines, false if not
|
||||||
*/
|
*/
|
||||||
override fun yankLine(editor: VimEditor, count: Int): Boolean {
|
override fun yankLine(editor: VimEditor, count: Int): Boolean {
|
||||||
val caretCount = editor.nativeCarets().size
|
val caretModel = editor.ij.caretModel
|
||||||
val ranges = ArrayList<Pair<Int, Int>>(caretCount)
|
val ranges = ArrayList<Pair<Int, Int>>(caretModel.caretCount)
|
||||||
val caretToRange = HashMap<VimCaret, TextRange>(caretCount)
|
for (caret in caretModel.allCarets) {
|
||||||
for (caret in editor.nativeCarets()) {
|
val start = VimPlugin.getMotion().moveCaretToLineStart(editor, caret.vim)
|
||||||
val start = injector.motion.moveCaretToLineStart(editor, caret)
|
val end = min(VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret.vim, count - 1, true) + 1, editor.fileSize().toInt())
|
||||||
val end = min(injector.motion.moveCaretToLineEndOffset(editor, caret, count - 1, true) + 1, editor.fileSize().toInt())
|
|
||||||
|
|
||||||
if (end == -1) continue
|
if (end == -1) continue
|
||||||
|
|
||||||
ranges.add(start to end)
|
ranges.add(start to end)
|
||||||
caretToRange[caret] = TextRange(start, end)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val range = getTextRange(ranges, SelectionType.LINE_WISE) ?: return false
|
val range = getTextRange(ranges, SelectionType.LINE_WISE) ?: return false
|
||||||
return yankRange(editor, caretToRange, range, SelectionType.LINE_WISE, null)
|
return yankRange(editor.ij, range, SelectionType.LINE_WISE, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +129,6 @@ class YankGroup : YankGroupBase() {
|
|||||||
override fun yankRange(editor: VimEditor, range: TextRange?, type: SelectionType, moveCursor: Boolean): Boolean {
|
override fun yankRange(editor: VimEditor, range: TextRange?, type: SelectionType, moveCursor: Boolean): Boolean {
|
||||||
range ?: return false
|
range ?: return false
|
||||||
|
|
||||||
val caretToRange = HashMap<VimCaret, TextRange>()
|
|
||||||
val selectionType = if (type == SelectionType.CHARACTER_WISE && range.isMultiple) SelectionType.BLOCK_WISE else type
|
val selectionType = if (type == SelectionType.CHARACTER_WISE && range.isMultiple) SelectionType.BLOCK_WISE else type
|
||||||
|
|
||||||
if (type == SelectionType.LINE_WISE) {
|
if (type == SelectionType.LINE_WISE) {
|
||||||
@@ -150,25 +143,24 @@ class YankGroup : YankGroupBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val caretModel = editor.ij.caretModel
|
||||||
val rangeStartOffsets = range.startOffsets
|
val rangeStartOffsets = range.startOffsets
|
||||||
val rangeEndOffsets = range.endOffsets
|
val rangeEndOffsets = range.endOffsets
|
||||||
|
|
||||||
val startOffsets = HashMap<VimCaret, Int>(editor.nativeCarets().size)
|
|
||||||
if (type == SelectionType.BLOCK_WISE) {
|
|
||||||
startOffsets[editor.primaryCaret()] = range.normalize().startOffset
|
|
||||||
caretToRange[editor.primaryCaret()] = range
|
|
||||||
} else {
|
|
||||||
for ((i, caret) in editor.nativeCarets().withIndex()) {
|
|
||||||
val textRange = TextRange(rangeStartOffsets[i], rangeEndOffsets[i])
|
|
||||||
startOffsets[caret] = textRange.normalize().startOffset
|
|
||||||
caretToRange[caret] = textRange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (moveCursor) {
|
return if (moveCursor) {
|
||||||
yankRange(editor, caretToRange, range, selectionType, startOffsets)
|
val startOffsets = HashMap<Caret, Int>(caretModel.caretCount)
|
||||||
|
if (type == SelectionType.BLOCK_WISE) {
|
||||||
|
startOffsets[caretModel.primaryCaret] = range.normalize().startOffset
|
||||||
|
} else {
|
||||||
|
val carets = caretModel.allCarets
|
||||||
|
for (i in carets.indices) {
|
||||||
|
startOffsets[carets[i]] = TextRange(rangeStartOffsets[i], rangeEndOffsets[i]).normalize().startOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yankRange(editor.ij, range, selectionType, startOffsets)
|
||||||
} else {
|
} else {
|
||||||
yankRange(editor, caretToRange, range, selectionType, null)
|
yankRange(editor.ij, range, selectionType, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,20 +192,15 @@ class YankGroup : YankGroupBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun yankRange(
|
private fun yankRange(
|
||||||
editor: VimEditor,
|
editor: Editor,
|
||||||
caretToRange: Map<VimCaret, TextRange>,
|
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
type: SelectionType,
|
type: SelectionType,
|
||||||
startOffsets: Map<VimCaret, Int>?,
|
startOffsets: Map<Caret, Int>?,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
startOffsets?.forEach { (caret, offset) -> injector.motion.moveCaret(editor, caret, offset) }
|
startOffsets?.forEach { (caret, offset) -> MotionGroup.moveCaret(editor, caret, offset) }
|
||||||
|
|
||||||
notifyListeners(editor, range)
|
notifyListeners(editor, range)
|
||||||
|
|
||||||
var result = true
|
return VimPlugin.getRegister().storeText(editor.vim, range, type, false)
|
||||||
for ((caret, range) in caretToRange) {
|
|
||||||
result = caret.registerStorage.storeText(editor, range, type, false) && result
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ import com.maddyhome.idea.vim.KeyHandler
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.helper.EditorDataContext
|
import com.maddyhome.idea.vim.helper.EditorDataContext
|
||||||
import com.maddyhome.idea.vim.helper.editorMode
|
import com.maddyhome.idea.vim.helper.vimStateMachine
|
||||||
import com.maddyhome.idea.vim.helper.exitSelectMode
|
import com.maddyhome.idea.vim.helper.exitSelectMode
|
||||||
import com.maddyhome.idea.vim.helper.exitVisualMode
|
import com.maddyhome.idea.vim.helper.exitVisualMode
|
||||||
import com.maddyhome.idea.vim.helper.hasVisualSelection
|
import com.maddyhome.idea.vim.helper.hasVisualSelection
|
||||||
@@ -35,8 +35,8 @@ import com.maddyhome.idea.vim.helper.inSelectMode
|
|||||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
import com.maddyhome.idea.vim.helper.inVisualMode
|
||||||
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
|
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
|
||||||
import com.maddyhome.idea.vim.helper.isTemplateActive
|
import com.maddyhome.idea.vim.helper.isTemplateActive
|
||||||
|
import com.maddyhome.idea.vim.helper.editorMode
|
||||||
import com.maddyhome.idea.vim.helper.popAllModes
|
import com.maddyhome.idea.vim.helper.popAllModes
|
||||||
import com.maddyhome.idea.vim.helper.vimStateMachine
|
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerManager
|
import com.maddyhome.idea.vim.listener.VimListenerManager
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimEditor
|
import com.maddyhome.idea.vim.newapi.IjVimEditor
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
|
@@ -25,11 +25,11 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.api.VimMotionGroupBase
|
import com.maddyhome.idea.vim.api.VimMotionGroupBase
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.editorMode
|
|
||||||
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
||||||
import com.maddyhome.idea.vim.helper.inSelectMode
|
import com.maddyhome.idea.vim.helper.inSelectMode
|
||||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
import com.maddyhome.idea.vim.helper.inVisualMode
|
||||||
import com.maddyhome.idea.vim.helper.isEndAllowed
|
import com.maddyhome.idea.vim.helper.isEndAllowed
|
||||||
|
import com.maddyhome.idea.vim.helper.editorMode
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.helper.updateCaretsVisualAttributes
|
import com.maddyhome.idea.vim.helper.updateCaretsVisualAttributes
|
||||||
|
@@ -22,6 +22,7 @@ package com.maddyhome.idea.vim.helper
|
|||||||
|
|
||||||
import com.intellij.codeWithMe.ClientId
|
import com.intellij.codeWithMe.ClientId
|
||||||
import com.intellij.openapi.editor.Caret
|
import com.intellij.openapi.editor.Caret
|
||||||
|
import com.intellij.openapi.editor.CaretState
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.ex.util.EditorUtil
|
import com.intellij.openapi.editor.ex.util.EditorUtil
|
||||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
||||||
@@ -106,3 +107,41 @@ val Caret.vimLine: Int
|
|||||||
*/
|
*/
|
||||||
val Editor.vimLine: Int
|
val Editor.vimLine: Int
|
||||||
get() = this.caretModel.currentCaret.vimLine
|
get() = this.caretModel.currentCaret.vimLine
|
||||||
|
|
||||||
|
inline fun Editor.runWithEveryCaretAndRestore(action: () -> Unit) {
|
||||||
|
val caretModel = this.caretModel
|
||||||
|
val carets = if (this.inBlockSubMode) null else caretModel.allCarets
|
||||||
|
if (carets == null || carets.size == 1) {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var initialDocumentSize = this.document.textLength
|
||||||
|
var documentSizeDifference = 0
|
||||||
|
|
||||||
|
val caretOffsets = carets.map { it.selectionStart to it.selectionEnd }
|
||||||
|
val restoredCarets = mutableListOf<CaretState>()
|
||||||
|
|
||||||
|
caretModel.removeSecondaryCarets()
|
||||||
|
|
||||||
|
for ((selectionStart, selectionEnd) in caretOffsets) {
|
||||||
|
if (selectionStart == selectionEnd) {
|
||||||
|
caretModel.primaryCaret.moveToOffset(selectionStart + documentSizeDifference)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
caretModel.primaryCaret.setSelection(
|
||||||
|
selectionStart + documentSizeDifference,
|
||||||
|
selectionEnd + documentSizeDifference
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
action()
|
||||||
|
restoredCarets.add(caretModel.caretsAndSelections.single())
|
||||||
|
|
||||||
|
val documentLength = this.document.textLength
|
||||||
|
documentSizeDifference += documentLength - initialDocumentSize
|
||||||
|
initialDocumentSize = documentLength
|
||||||
|
}
|
||||||
|
|
||||||
|
caretModel.caretsAndSelections = restoredCarets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -25,9 +25,9 @@ import com.intellij.openapi.editor.Caret
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
||||||
import com.maddyhome.idea.vim.newapi.IjExecutionContext
|
import com.maddyhome.idea.vim.newapi.IjExecutionContext
|
||||||
|
@@ -15,30 +15,25 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim.helper
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
package com.maddyhome.idea.vim.helper;
|
||||||
import java.util.*
|
|
||||||
import java.util.stream.Collectors
|
import javax.swing.*;
|
||||||
import javax.swing.KeyStroke
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.maddyhome.idea.vim.api.VimInjectorKt.injector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* COMPATIBILITY-LAYER: Created a helper class
|
* COMPATIBILITY-LAYER: Created a helper class
|
||||||
*/
|
*/
|
||||||
object StringHelper {
|
public class StringHelper {
|
||||||
@JvmStatic
|
public static List<KeyStroke> parseKeys(String string) {
|
||||||
fun parseKeys(string: String): List<KeyStroke> {
|
return injector.getParser().parseKeys(string);
|
||||||
return injector.parser.parseKeys(string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
public static List<KeyStroke> parseKeys(String... string) {
|
||||||
fun parseKeys(vararg string: String): List<KeyStroke> {
|
return Arrays.stream(string).flatMap(o -> injector.getParser().parseKeys(o).stream()).collect(Collectors.toList());
|
||||||
return Arrays.stream(string).flatMap { o: String -> injector.parser.parseKeys(o).stream() }
|
|
||||||
.collect(Collectors.toList())
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@JvmStatic
|
|
||||||
fun isCloseKeyStroke(stroke: KeyStroke): Boolean {
|
|
||||||
return stroke.isCloseKeyStroke()
|
|
||||||
}
|
|
||||||
}
|
|
@@ -25,9 +25,7 @@ import com.intellij.openapi.command.undo.UndoManager
|
|||||||
import com.intellij.openapi.components.Service
|
import com.intellij.openapi.components.Service
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.common.ChangesListener
|
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimEditor
|
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import com.maddyhome.idea.vim.options.OptionScope
|
import com.maddyhome.idea.vim.options.OptionScope
|
||||||
@@ -49,7 +47,7 @@ class UndoRedoHelper : UndoRedoBase() {
|
|||||||
SelectionVimListenerSuppressor.lock().use { undoManager.undo(fileEditor) }
|
SelectionVimListenerSuppressor.lock().use { undoManager.undo(fileEditor) }
|
||||||
} else {
|
} else {
|
||||||
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
|
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
|
||||||
performUntilFileChanges(editor, { undoManager.isUndoAvailable(fileEditor) }, { undoManager.undo(fileEditor) })
|
undoManager.undo(fileEditor)
|
||||||
editor?.carets()?.forEach {
|
editor?.carets()?.forEach {
|
||||||
val ijCaret = it.ij
|
val ijCaret = it.ij
|
||||||
val hasSelection = ijCaret.hasSelection()
|
val hasSelection = ijCaret.hasSelection()
|
||||||
@@ -75,30 +73,14 @@ class UndoRedoHelper : UndoRedoBase() {
|
|||||||
SelectionVimListenerSuppressor.lock().use { undoManager.redo(fileEditor) }
|
SelectionVimListenerSuppressor.lock().use { undoManager.redo(fileEditor) }
|
||||||
} else {
|
} else {
|
||||||
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
|
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
|
||||||
performUntilFileChanges(editor, { undoManager.isRedoAvailable(fileEditor) }, { undoManager.redo(fileEditor) })
|
undoManager.redo(fileEditor)
|
||||||
|
if (editor?.primaryCaret()?.ij?.hasSelection() == true) {
|
||||||
|
undoManager.redo(fileEditor)
|
||||||
|
}
|
||||||
editor?.carets()?.forEach { it.ij.removeSelection() }
|
editor?.carets()?.forEach { it.ij.removeSelection() }
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun performUntilFileChanges(editor: IjVimEditor?, check: () -> Boolean, action: Runnable) {
|
|
||||||
if (editor == null) return
|
|
||||||
val vimDocument = editor.document
|
|
||||||
|
|
||||||
val changeListener = object : ChangesListener {
|
|
||||||
var hasChanged = false
|
|
||||||
|
|
||||||
override fun documentChanged(change: ChangesListener.Change) {
|
|
||||||
hasChanged = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vimDocument.addChangeListener(changeListener)
|
|
||||||
while (check() && !changeListener.hasChanged) {
|
|
||||||
action.run()
|
|
||||||
}
|
|
||||||
vimDocument.removeChangeListener(changeListener)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -27,9 +27,8 @@ import com.intellij.openapi.editor.RangeMarker
|
|||||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.util.UserDataHolder
|
import com.intellij.openapi.util.UserDataHolder
|
||||||
import com.maddyhome.idea.vim.api.CaretRegisterStorageBase
|
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.ex.ExOutputModel
|
import com.maddyhome.idea.vim.ex.ExOutputModel
|
||||||
import com.maddyhome.idea.vim.group.visual.VisualChange
|
import com.maddyhome.idea.vim.group.visual.VisualChange
|
||||||
import com.maddyhome.idea.vim.group.visual.vimLeadSelectionOffset
|
import com.maddyhome.idea.vim.group.visual.vimLeadSelectionOffset
|
||||||
@@ -74,7 +73,6 @@ var Caret.vimInsertStart: RangeMarker by userDataOr {
|
|||||||
this.offset
|
this.offset
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
var Caret.registerStorage: CaretRegisterStorageBase? by userDataCaretToEditor()
|
|
||||||
|
|
||||||
// ------------------ Editor
|
// ------------------ Editor
|
||||||
fun unInitializeEditor(editor: Editor) {
|
fun unInitializeEditor(editor: Editor) {
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
package com.maddyhome.idea.vim.key
|
package com.maddyhome.idea.vim.key
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
|
import com.maddyhome.idea.vim.common.Node
|
||||||
|
import com.maddyhome.idea.vim.common.addLeafs
|
||||||
|
|
||||||
fun <T> Node<T>.addLeafs(keys: String, actionHolder: T) {
|
fun <T> Node<T>.addLeafs(keys: String, actionHolder: T) {
|
||||||
addLeafs(injector.parser.parseKeys(keys), actionHolder)
|
addLeafs(injector.parser.parseKeys(keys), actionHolder)
|
||||||
|
@@ -19,8 +19,10 @@
|
|||||||
package com.maddyhome.idea.vim.listener
|
package com.maddyhome.idea.vim.listener
|
||||||
|
|
||||||
import com.intellij.codeInsight.lookup.Lookup
|
import com.intellij.codeInsight.lookup.Lookup
|
||||||
|
import com.intellij.codeInsight.lookup.LookupManager
|
||||||
import com.intellij.codeInsight.lookup.LookupManagerListener
|
import com.intellij.codeInsight.lookup.LookupManagerListener
|
||||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
||||||
|
import com.intellij.codeInsight.lookup.impl.actions.ChooseItemAction
|
||||||
import com.intellij.codeInsight.template.Template
|
import com.intellij.codeInsight.template.Template
|
||||||
import com.intellij.codeInsight.template.TemplateEditingAdapter
|
import com.intellij.codeInsight.template.TemplateEditingAdapter
|
||||||
import com.intellij.codeInsight.template.TemplateManagerListener
|
import com.intellij.codeInsight.template.TemplateManagerListener
|
||||||
@@ -35,20 +37,22 @@ import com.intellij.openapi.actionSystem.ex.AnActionListener
|
|||||||
import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet
|
import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.project.DumbAwareToggleAction
|
import com.intellij.openapi.project.DumbAwareToggleAction
|
||||||
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.group.NotificationService
|
|
||||||
import com.maddyhome.idea.vim.helper.EditorDataContext
|
import com.maddyhome.idea.vim.helper.EditorDataContext
|
||||||
|
import com.maddyhome.idea.vim.helper.vimStateMachine
|
||||||
import com.maddyhome.idea.vim.helper.inNormalMode
|
import com.maddyhome.idea.vim.helper.inNormalMode
|
||||||
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
|
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
|
||||||
import com.maddyhome.idea.vim.helper.vimStateMachine
|
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants
|
import com.maddyhome.idea.vim.options.OptionConstants
|
||||||
import com.maddyhome.idea.vim.options.OptionScope
|
import com.maddyhome.idea.vim.options.OptionScope
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||||
import com.maddyhome.idea.vim.vimscript.model.options.helpers.IdeaRefactorModeHelper
|
import com.maddyhome.idea.vim.vimscript.model.options.helpers.IdeaRefactorModeHelper
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import java.awt.event.KeyEvent
|
||||||
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Alex Plate
|
* @author Alex Plate
|
||||||
@@ -60,6 +64,8 @@ object IdeaSpecifics {
|
|||||||
private val surrounderAction =
|
private val surrounderAction =
|
||||||
"com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction"
|
"com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction"
|
||||||
private var editor: Editor? = null
|
private var editor: Editor? = null
|
||||||
|
private var completionPrevDocumentLength: Int? = null
|
||||||
|
private var completionPrevDocumentOffset: Int? = null
|
||||||
override fun beforeActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
|
override fun beforeActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
|
||||||
if (!VimPlugin.isEnabled()) return
|
if (!VimPlugin.isEnabled()) return
|
||||||
|
|
||||||
@@ -68,19 +74,52 @@ object IdeaSpecifics {
|
|||||||
editor = hostEditor
|
editor = hostEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
//region Track action id
|
|
||||||
if (VimPlugin.getOptionService().isSet(OptionScope.GLOBAL, OptionConstants.trackactionidsName)) {
|
if (VimPlugin.getOptionService().isSet(OptionScope.GLOBAL, OptionConstants.trackactionidsName)) {
|
||||||
if (action !is NotificationService.ActionIdNotifier.CopyActionId && action !is NotificationService.ActionIdNotifier.StopTracking) {
|
val id: String? = ActionManager.getInstance().getId(action) ?: (action.shortcutSet as? ProxyShortcutSet)?.actionId
|
||||||
val id: String? = ActionManager.getInstance().getId(action) ?: (action.shortcutSet as? ProxyShortcutSet)?.actionId
|
VimPlugin.getNotifications(dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id)
|
||||||
VimPlugin.getNotifications(dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id)
|
}
|
||||||
|
|
||||||
|
if (hostEditor != null && action is ChooseItemAction && hostEditor.vimStateMachine?.isRecording == true) {
|
||||||
|
val lookup = LookupManager.getActiveLookup(hostEditor)
|
||||||
|
if (lookup != null) {
|
||||||
|
val charsToRemove = hostEditor.caretModel.primaryCaret.offset - lookup.lookupStart
|
||||||
|
|
||||||
|
val register = VimPlugin.getRegister()
|
||||||
|
val backSpace = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0)
|
||||||
|
repeat(charsToRemove) {
|
||||||
|
register.recordKeyStroke(backSpace)
|
||||||
|
}
|
||||||
|
|
||||||
|
completionPrevDocumentLength = hostEditor.document.textLength - charsToRemove
|
||||||
|
completionPrevDocumentOffset = lookup.lookupStart
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
|
override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
|
||||||
if (!VimPlugin.isEnabled()) return
|
if (!VimPlugin.isEnabled()) return
|
||||||
|
|
||||||
|
val editor = editor
|
||||||
|
if (editor != null && action is ChooseItemAction && editor.vimStateMachine?.isRecording == true) {
|
||||||
|
val prevDocumentLength = completionPrevDocumentLength
|
||||||
|
val prevDocumentOffset = completionPrevDocumentOffset
|
||||||
|
|
||||||
|
if (prevDocumentLength != null && prevDocumentOffset != null) {
|
||||||
|
val register = VimPlugin.getRegister()
|
||||||
|
val addedTextLength = editor.document.textLength - prevDocumentLength
|
||||||
|
val caretShift = addedTextLength - (editor.caretModel.primaryCaret.offset - prevDocumentOffset)
|
||||||
|
val leftArrow = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)
|
||||||
|
|
||||||
|
register.recordText(editor.document.getText(TextRange(prevDocumentOffset, prevDocumentOffset + addedTextLength)))
|
||||||
|
repeat(caretShift.coerceAtLeast(0)) {
|
||||||
|
register.recordKeyStroke(leftArrow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.completionPrevDocumentLength = null
|
||||||
|
this.completionPrevDocumentOffset = null
|
||||||
|
}
|
||||||
|
|
||||||
//region Enter insert mode after surround with if
|
//region Enter insert mode after surround with if
|
||||||
if (surrounderAction == action.javaClass.name && surrounderItems.any {
|
if (surrounderAction == action.javaClass.name && surrounderItems.any {
|
||||||
action.templatePresentation.text.endsWith(
|
action.templatePresentation.text.endsWith(
|
||||||
@@ -99,7 +138,7 @@ object IdeaSpecifics {
|
|||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
editor = null
|
this.editor = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,8 +32,8 @@ import com.maddyhome.idea.vim.api.VimChangeGroupBase
|
|||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.VimMotionGroupBase
|
import com.maddyhome.idea.vim.api.VimMotionGroupBase
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.common.EditorLine
|
import com.maddyhome.idea.vim.common.EditorLine
|
||||||
import com.maddyhome.idea.vim.common.IndentConfig
|
import com.maddyhome.idea.vim.common.IndentConfig
|
||||||
import com.maddyhome.idea.vim.common.OperatedRange
|
import com.maddyhome.idea.vim.common.OperatedRange
|
||||||
|
@@ -22,10 +22,7 @@ import com.intellij.openapi.editor.Caret
|
|||||||
import com.intellij.openapi.editor.LogicalPosition
|
import com.intellij.openapi.editor.LogicalPosition
|
||||||
import com.intellij.openapi.editor.VisualPosition
|
import com.intellij.openapi.editor.VisualPosition
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.CaretRegisterStorage
|
|
||||||
import com.maddyhome.idea.vim.api.CaretRegisterStorageBase
|
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
import com.maddyhome.idea.vim.api.VimCaretBase
|
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.VimLogicalPosition
|
import com.maddyhome.idea.vim.api.VimLogicalPosition
|
||||||
import com.maddyhome.idea.vim.api.VimVisualPosition
|
import com.maddyhome.idea.vim.api.VimVisualPosition
|
||||||
@@ -41,23 +38,13 @@ import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
|||||||
import com.maddyhome.idea.vim.group.visual.vimUpdateEditorSelection
|
import com.maddyhome.idea.vim.group.visual.vimUpdateEditorSelection
|
||||||
import com.maddyhome.idea.vim.helper.inlayAwareVisualColumn
|
import com.maddyhome.idea.vim.helper.inlayAwareVisualColumn
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.registerStorage
|
|
||||||
import com.maddyhome.idea.vim.helper.vimInsertStart
|
import com.maddyhome.idea.vim.helper.vimInsertStart
|
||||||
import com.maddyhome.idea.vim.helper.vimLastColumn
|
import com.maddyhome.idea.vim.helper.vimLastColumn
|
||||||
import com.maddyhome.idea.vim.helper.vimLastVisualOperatorRange
|
import com.maddyhome.idea.vim.helper.vimLastVisualOperatorRange
|
||||||
import com.maddyhome.idea.vim.helper.vimLine
|
import com.maddyhome.idea.vim.helper.vimLine
|
||||||
import com.maddyhome.idea.vim.helper.vimSelectionStart
|
import com.maddyhome.idea.vim.helper.vimSelectionStart
|
||||||
|
|
||||||
class IjVimCaret(val caret: Caret) : VimCaretBase() {
|
class IjVimCaret(val caret: Caret) : VimCaret {
|
||||||
override val registerStorage: CaretRegisterStorage
|
|
||||||
get() {
|
|
||||||
var storage = this.caret.registerStorage
|
|
||||||
if (storage == null) {
|
|
||||||
storage = CaretRegisterStorageBase(editor.primaryCaret().ij == caret)
|
|
||||||
this.caret.registerStorage = storage
|
|
||||||
}
|
|
||||||
return storage
|
|
||||||
}
|
|
||||||
override val editor: VimEditor
|
override val editor: VimEditor
|
||||||
get() = IjVimEditor(caret.editor)
|
get() = IjVimEditor(caret.editor)
|
||||||
override val offset: Offset
|
override val offset: Offset
|
||||||
|
@@ -38,9 +38,9 @@ import com.maddyhome.idea.vim.api.VimLogicalPosition
|
|||||||
import com.maddyhome.idea.vim.api.VimSelectionModel
|
import com.maddyhome.idea.vim.api.VimSelectionModel
|
||||||
import com.maddyhome.idea.vim.api.VimVisualPosition
|
import com.maddyhome.idea.vim.api.VimVisualPosition
|
||||||
import com.maddyhome.idea.vim.api.VirtualFile
|
import com.maddyhome.idea.vim.api.VirtualFile
|
||||||
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
|
||||||
import com.maddyhome.idea.vim.common.EditorLine
|
import com.maddyhome.idea.vim.common.EditorLine
|
||||||
import com.maddyhome.idea.vim.common.LiveRange
|
import com.maddyhome.idea.vim.common.LiveRange
|
||||||
import com.maddyhome.idea.vim.common.Offset
|
import com.maddyhome.idea.vim.common.Offset
|
||||||
|
@@ -68,7 +68,7 @@ import com.maddyhome.idea.vim.helper.vimStateMachine
|
|||||||
import com.maddyhome.idea.vim.history.VimHistory
|
import com.maddyhome.idea.vim.history.VimHistory
|
||||||
import com.maddyhome.idea.vim.macro.VimMacro
|
import com.maddyhome.idea.vim.macro.VimMacro
|
||||||
import com.maddyhome.idea.vim.mark.VimMarkGroup
|
import com.maddyhome.idea.vim.mark.VimMarkGroup
|
||||||
import com.maddyhome.idea.vim.vimscript.services.OptionService
|
import com.maddyhome.idea.vim.options.OptionService
|
||||||
import com.maddyhome.idea.vim.put.VimPut
|
import com.maddyhome.idea.vim.put.VimPut
|
||||||
import com.maddyhome.idea.vim.register.VimRegisterGroup
|
import com.maddyhome.idea.vim.register.VimRegisterGroup
|
||||||
import com.maddyhome.idea.vim.ui.VimRcFileState
|
import com.maddyhome.idea.vim.ui.VimRcFileState
|
||||||
@@ -76,7 +76,7 @@ import com.maddyhome.idea.vim.undo.VimUndoRedo
|
|||||||
import com.maddyhome.idea.vim.vimscript.Executor
|
import com.maddyhome.idea.vim.vimscript.Executor
|
||||||
import com.maddyhome.idea.vim.vimscript.services.FunctionStorage
|
import com.maddyhome.idea.vim.vimscript.services.FunctionStorage
|
||||||
import com.maddyhome.idea.vim.vimscript.services.PatternService
|
import com.maddyhome.idea.vim.vimscript.services.PatternService
|
||||||
import com.maddyhome.idea.vim.vimscript.services.VariableService
|
import com.maddyhome.idea.vim.vimscript.services.VimVariableService
|
||||||
import com.maddyhome.idea.vim.yank.VimYankGroup
|
import com.maddyhome.idea.vim.yank.VimYankGroup
|
||||||
|
|
||||||
class IjVimInjector : VimInjectorBase() {
|
class IjVimInjector : VimInjectorBase() {
|
||||||
@@ -161,7 +161,7 @@ class IjVimInjector : VimInjectorBase() {
|
|||||||
|
|
||||||
override val functionService: VimscriptFunctionService
|
override val functionService: VimscriptFunctionService
|
||||||
get() = FunctionStorage
|
get() = FunctionStorage
|
||||||
override val variableService: VariableService
|
override val variableService: VimVariableService
|
||||||
get() = service()
|
get() = service()
|
||||||
override val vimrcFileState: VimrcFileState
|
override val vimrcFileState: VimrcFileState
|
||||||
get() = VimRcFileState
|
get() = VimRcFileState
|
||||||
|
@@ -22,8 +22,6 @@ import com.maddyhome.idea.vim.api.injector
|
|||||||
import com.maddyhome.idea.vim.options.OptionConstants
|
import com.maddyhome.idea.vim.options.OptionConstants
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants.Companion.ignorecaseName
|
import com.maddyhome.idea.vim.options.OptionConstants.Companion.ignorecaseName
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants.Companion.smartcaseName
|
import com.maddyhome.idea.vim.options.OptionConstants.Companion.smartcaseName
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants.Companion.timeoutName
|
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants.Companion.timeoutlenName
|
|
||||||
import com.maddyhome.idea.vim.options.OptionScope
|
import com.maddyhome.idea.vim.options.OptionScope
|
||||||
import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper
|
import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper
|
||||||
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService
|
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService
|
||||||
@@ -36,10 +34,6 @@ object OptionsManager {
|
|||||||
get() = (injector.optionService as IjVimOptionService).getRawOption(ignorecaseName) as ToggleOption
|
get() = (injector.optionService as IjVimOptionService).getRawOption(ignorecaseName) as ToggleOption
|
||||||
val smartcase: ToggleOption
|
val smartcase: ToggleOption
|
||||||
get() = (injector.optionService as IjVimOptionService).getRawOption(smartcaseName) as ToggleOption
|
get() = (injector.optionService as IjVimOptionService).getRawOption(smartcaseName) as ToggleOption
|
||||||
val timeout: ToggleOption
|
|
||||||
get() = (injector.optionService as IjVimOptionService).getRawOption(timeoutName) as ToggleOption
|
|
||||||
val timeoutlen: NumberOption
|
|
||||||
get() = (injector.optionService as IjVimOptionService).getRawOption(timeoutlenName) as NumberOption
|
|
||||||
val iskeyword: KeywordOption
|
val iskeyword: KeywordOption
|
||||||
get() = KeywordOption(KeywordOptionHelper)
|
get() = KeywordOption(KeywordOptionHelper)
|
||||||
}
|
}
|
||||||
|
@@ -20,8 +20,8 @@ package com.maddyhome.idea.vim.ui
|
|||||||
|
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.helper.isCloseKeyStroke
|
|
||||||
import com.maddyhome.idea.vim.helper.vimStateMachine
|
import com.maddyhome.idea.vim.helper.vimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.helper.isCloseKeyStroke
|
||||||
import java.awt.KeyEventDispatcher
|
import java.awt.KeyEventDispatcher
|
||||||
import java.awt.KeyboardFocusManager
|
import java.awt.KeyboardFocusManager
|
||||||
import java.awt.Toolkit
|
import java.awt.Toolkit
|
||||||
|
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2021 The IdeaVim authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.vimscript.model.functions.handlers
|
||||||
|
|
||||||
|
import com.intellij.refactoring.rename.inplace.InplaceRefactoring
|
||||||
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
|
import com.maddyhome.idea.vim.vimscript.model.VimLContext
|
||||||
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
||||||
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||||
|
import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
|
||||||
|
import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler
|
||||||
|
|
||||||
|
object RenamingFunctionHandler : FunctionHandler() {
|
||||||
|
|
||||||
|
override val name = "renaming"
|
||||||
|
override val minimumNumberOfArguments = 0
|
||||||
|
override val maximumNumberOfArguments = 0
|
||||||
|
|
||||||
|
override fun doFunction(
|
||||||
|
argumentValues: List<Expression>,
|
||||||
|
editor: VimEditor,
|
||||||
|
context: ExecutionContext,
|
||||||
|
vimContext: VimLContext,
|
||||||
|
): VimDataType {
|
||||||
|
return if (InplaceRefactoring.getActiveInplaceRenamer(editor.ij) == null)
|
||||||
|
VimInt.ZERO
|
||||||
|
else
|
||||||
|
VimInt.ONE
|
||||||
|
}
|
||||||
|
}
|
@@ -25,9 +25,9 @@ import com.intellij.codeInsight.lookup.impl.LookupImpl
|
|||||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
|
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.helper.editorMode
|
|
||||||
import com.maddyhome.idea.vim.helper.hasBlockOrUnderscoreCaret
|
import com.maddyhome.idea.vim.helper.hasBlockOrUnderscoreCaret
|
||||||
import com.maddyhome.idea.vim.helper.hasVisualSelection
|
import com.maddyhome.idea.vim.helper.hasVisualSelection
|
||||||
|
import com.maddyhome.idea.vim.helper.editorMode
|
||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
|
@@ -20,9 +20,9 @@ package com.maddyhome.idea.vim.vimscript.services
|
|||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationNamesInfo
|
import com.intellij.openapi.application.ApplicationNamesInfo
|
||||||
import com.maddyhome.idea.vim.api.VimOptionServiceBase
|
import com.maddyhome.idea.vim.api.VimOptionServiceBase
|
||||||
import com.maddyhome.idea.vim.option.ToggleOption
|
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants
|
import com.maddyhome.idea.vim.options.OptionConstants
|
||||||
import com.maddyhome.idea.vim.options.StringOption
|
import com.maddyhome.idea.vim.options.StringOption
|
||||||
|
import com.maddyhome.idea.vim.option.ToggleOption
|
||||||
|
|
||||||
internal class IjVimOptionService : VimOptionServiceBase() {
|
internal class IjVimOptionService : VimOptionServiceBase() {
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
|||||||
import com.maddyhome.idea.vim.vimscript.model.expressions.Scope
|
import com.maddyhome.idea.vim.vimscript.model.expressions.Scope
|
||||||
import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
|
import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
|
||||||
|
|
||||||
class IjVariableService : VimVariableServiceBase() {
|
internal class VimVariableServiceImpl : VimVariableServiceBase() {
|
||||||
override fun storeVariable(variable: Variable, value: VimDataType, editor: VimEditor, context: ExecutionContext, vimContext: VimLContext) {
|
override fun storeVariable(variable: Variable, value: VimDataType, editor: VimEditor, context: ExecutionContext, vimContext: VimLContext) {
|
||||||
super.storeVariable(variable, value, editor, context, vimContext)
|
super.storeVariable(variable, value, editor, context, vimContext)
|
||||||
|
|
@@ -26,13 +26,13 @@
|
|||||||
serviceInterface="com.maddyhome.idea.vim.api.VimVisualMotionGroup"/>
|
serviceInterface="com.maddyhome.idea.vim.api.VimVisualMotionGroup"/>
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.copy.YankGroup"/>
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.copy.YankGroup"/>
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.copy.PutGroup"/>
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.copy.PutGroup"/>
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.vimscript.services.IjVariableService"
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.vimscript.services.VimVariableServiceImpl"
|
||||||
serviceInterface="com.maddyhome.idea.vim.vimscript.services.VariableService"/>
|
serviceInterface="com.maddyhome.idea.vim.vimscript.services.VimVariableService"/>
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjStatisticsService"
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjStatisticsService"
|
||||||
serviceInterface="com.maddyhome.idea.vim.api.VimStatistics"/>
|
serviceInterface="com.maddyhome.idea.vim.api.VimStatistics"/>
|
||||||
|
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.vimscript.services.IjVimOptionService"
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.vimscript.services.IjVimOptionService"
|
||||||
serviceInterface="com.maddyhome.idea.vim.vimscript.services.OptionService"/>
|
serviceInterface="com.maddyhome.idea.vim.options.OptionService"/>
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjVimStorageService"
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjVimStorageService"
|
||||||
serviceInterface="com.maddyhome.idea.vim.api.VimStorageService"/>
|
serviceInterface="com.maddyhome.idea.vim.api.VimStorageService"/>
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjVimSystemInfoService"
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjVimSystemInfoService"
|
||||||
|
@@ -14,5 +14,6 @@
|
|||||||
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.TolowerFunctionHandler" name="tolower"/>
|
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.TolowerFunctionHandler" name="tolower"/>
|
||||||
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.ToupperFunctionHandler" name="toupper"/>
|
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.ToupperFunctionHandler" name="toupper"/>
|
||||||
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.JoinFunctionHandler" name="join"/>
|
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.JoinFunctionHandler" name="join"/>
|
||||||
|
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.RenamingFunctionHandler" name="renaming"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<idea-plugin url="https://plugins.jetbrains.com/plugin/164" xmlns:xi="http://www.w3.org/2001/XInclude">
|
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
<name>IdeaVim</name>
|
<name>IdeaVim</name>
|
||||||
<id>IdeaVIM</id>
|
<id>IdeaVIM</id>
|
||||||
<change-notes><![CDATA[
|
<change-notes><![CDATA[
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<li><a href="https://youtrack.jetbrains.com/issues/VIM">Issue tracker</a>: feature requests and bug reports</li>
|
<li><a href="https://youtrack.jetbrains.com/issues/VIM">Issue tracker</a>: feature requests and bug reports</li>
|
||||||
</ul>
|
</ul>
|
||||||
]]></description>
|
]]></description>
|
||||||
<version>SNAPSHOT</version>
|
<version>chylex</version>
|
||||||
<vendor>JetBrains</vendor>
|
<vendor>JetBrains</vendor>
|
||||||
|
|
||||||
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->
|
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->
|
||||||
|
@@ -31,8 +31,9 @@ import com.maddyhome.idea.vim.helper.RunnableHelper;
|
|||||||
import com.maddyhome.idea.vim.helper.TestInputModel;
|
import com.maddyhome.idea.vim.helper.TestInputModel;
|
||||||
import com.maddyhome.idea.vim.newapi.IjExecutionContext;
|
import com.maddyhome.idea.vim.newapi.IjExecutionContext;
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimEditor;
|
import com.maddyhome.idea.vim.newapi.IjVimEditor;
|
||||||
import com.maddyhome.idea.vim.options.OptionScope;
|
|
||||||
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
|
import com.maddyhome.idea.vim.options.OptionScope;
|
||||||
|
import com.maddyhome.idea.vim.vimscript.services.VimVariableServiceImpl;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ public abstract class JavaVimTestCase extends JavaCodeInsightFixtureTestCase {
|
|||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
ExEntryPanel.getInstance().deactivate(false);
|
ExEntryPanel.getInstance().deactivate(false);
|
||||||
VimPlugin.getVariableService().clear();
|
((VimVariableServiceImpl) VimPlugin.getVariableService()).clear();
|
||||||
Timer swingTimer = VimVisualTimer.INSTANCE.getSwingTimer();
|
Timer swingTimer = VimVisualTimer.INSTANCE.getSwingTimer();
|
||||||
if (swingTimer != null) {
|
if (swingTimer != null) {
|
||||||
swingTimer.stop();
|
swingTimer.stop();
|
||||||
|
@@ -21,10 +21,10 @@ package org.jetbrains.plugins.ideavim
|
|||||||
import com.maddyhome.idea.vim.RegisterActions.VIM_ACTIONS_EP
|
import com.maddyhome.idea.vim.RegisterActions.VIM_ACTIONS_EP
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.key.CommandNode
|
import com.maddyhome.idea.vim.common.CommandNode
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.common.CommandPartNode
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.handler.ActionBeanClass
|
import com.maddyhome.idea.vim.handler.ActionBeanClass
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
@@ -76,9 +76,9 @@ inline fun waitAndAssert(timeInMillis: Int = 1000, condition: () -> Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun waitAndAssertMode(
|
fun waitAndAssertMode(
|
||||||
fixture: CodeInsightTestFixture,
|
fixture: CodeInsightTestFixture,
|
||||||
mode: VimStateMachine.Mode,
|
mode: VimStateMachine.Mode,
|
||||||
timeInMillis: Int = (VimPlugin.getOptionService().getOptionValue(OptionScope.GLOBAL, OptionConstants.visualdelayName) as VimInt).value + 1000,
|
timeInMillis: Int = (VimPlugin.getOptionService().getOptionValue(OptionScope.GLOBAL, OptionConstants.visualdelayName) as VimInt).value + 1000,
|
||||||
) {
|
) {
|
||||||
waitAndAssert(timeInMillis) { fixture.editor.editorMode == mode }
|
waitAndAssert(timeInMillis) { fixture.editor.editorMode == mode }
|
||||||
}
|
}
|
||||||
|
@@ -50,9 +50,9 @@ import com.maddyhome.idea.vim.KeyHandler
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.action.VimShortcutKeyAction
|
import com.maddyhome.idea.vim.action.VimShortcutKeyAction
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine.SubMode
|
import com.maddyhome.idea.vim.command.VimStateMachine.SubMode
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.ex.ExOutputModel.Companion.getInstance
|
import com.maddyhome.idea.vim.ex.ExOutputModel.Companion.getInstance
|
||||||
import com.maddyhome.idea.vim.group.visual.VimVisualTimer.swingTimer
|
import com.maddyhome.idea.vim.group.visual.VimVisualTimer.swingTimer
|
||||||
@@ -61,9 +61,9 @@ import com.maddyhome.idea.vim.helper.EditorHelper
|
|||||||
import com.maddyhome.idea.vim.helper.GuicursorChangeListener
|
import com.maddyhome.idea.vim.helper.GuicursorChangeListener
|
||||||
import com.maddyhome.idea.vim.helper.RunnableHelper.runWriteCommand
|
import com.maddyhome.idea.vim.helper.RunnableHelper.runWriteCommand
|
||||||
import com.maddyhome.idea.vim.helper.TestInputModel
|
import com.maddyhome.idea.vim.helper.TestInputModel
|
||||||
import com.maddyhome.idea.vim.helper.editorMode
|
|
||||||
import com.maddyhome.idea.vim.helper.getGuiCursorMode
|
import com.maddyhome.idea.vim.helper.getGuiCursorMode
|
||||||
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
||||||
|
import com.maddyhome.idea.vim.helper.editorMode
|
||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner
|
import com.maddyhome.idea.vim.key.MappingOwner
|
||||||
import com.maddyhome.idea.vim.key.ToKeysMappingInfo
|
import com.maddyhome.idea.vim.key.ToKeysMappingInfo
|
||||||
@@ -77,6 +77,7 @@ import com.maddyhome.idea.vim.ui.ex.ExEntryPanel
|
|||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFuncref
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFuncref
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||||
import com.maddyhome.idea.vim.vimscript.parser.errors.IdeavimErrorListener
|
import com.maddyhome.idea.vim.vimscript.parser.errors.IdeavimErrorListener
|
||||||
|
import com.maddyhome.idea.vim.vimscript.services.VimVariableServiceImpl
|
||||||
import org.assertj.core.api.Assertions
|
import org.assertj.core.api.Assertions
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
@@ -136,7 +137,7 @@ abstract class VimTestCase : UsefulTestCase() {
|
|||||||
}
|
}
|
||||||
SelectionVimListenerSuppressor.lock().use { myFixture.tearDown() }
|
SelectionVimListenerSuppressor.lock().use { myFixture.tearDown() }
|
||||||
ExEntryPanel.getInstance().deactivate(false)
|
ExEntryPanel.getInstance().deactivate(false)
|
||||||
VimPlugin.getVariableService().clear()
|
(VimPlugin.getVariableService() as VimVariableServiceImpl).clear()
|
||||||
VimFuncref.lambdaCounter = 0
|
VimFuncref.lambdaCounter = 0
|
||||||
VimFuncref.anonymousCounter = 0
|
VimFuncref.anonymousCounter = 0
|
||||||
IdeavimErrorListener.testLogger.clear()
|
IdeavimErrorListener.testLogger.clear()
|
||||||
@@ -508,21 +509,21 @@ abstract class VimTestCase : UsefulTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun doTest(
|
fun doTest(
|
||||||
keys: List<String>,
|
keys: List<String>,
|
||||||
before: String,
|
before: String,
|
||||||
after: String,
|
after: String,
|
||||||
modeAfter: VimStateMachine.Mode,
|
modeAfter: VimStateMachine.Mode,
|
||||||
subModeAfter: SubMode,
|
subModeAfter: SubMode,
|
||||||
) {
|
) {
|
||||||
doTest(keys.joinToString(separator = ""), before, after, modeAfter, subModeAfter)
|
doTest(keys.joinToString(separator = ""), before, after, modeAfter, subModeAfter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doTest(
|
fun doTest(
|
||||||
keys: String,
|
keys: String,
|
||||||
before: String,
|
before: String,
|
||||||
after: String,
|
after: String,
|
||||||
modeAfter: VimStateMachine.Mode,
|
modeAfter: VimStateMachine.Mode,
|
||||||
subModeAfter: SubMode,
|
subModeAfter: SubMode,
|
||||||
) {
|
) {
|
||||||
configureByText(before)
|
configureByText(before)
|
||||||
|
|
||||||
@@ -532,12 +533,12 @@ abstract class VimTestCase : UsefulTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun doTest(
|
fun doTest(
|
||||||
keys: String,
|
keys: String,
|
||||||
before: String,
|
before: String,
|
||||||
after: String,
|
after: String,
|
||||||
modeAfter: VimStateMachine.Mode,
|
modeAfter: VimStateMachine.Mode,
|
||||||
subModeAfter: SubMode,
|
subModeAfter: SubMode,
|
||||||
fileType: FileType,
|
fileType: FileType,
|
||||||
) {
|
) {
|
||||||
configureByText(fileType, before)
|
configureByText(fileType, before)
|
||||||
|
|
||||||
@@ -550,12 +551,12 @@ abstract class VimTestCase : UsefulTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun doTest(
|
fun doTest(
|
||||||
keys: String,
|
keys: String,
|
||||||
before: String,
|
before: String,
|
||||||
after: String,
|
after: String,
|
||||||
modeAfter: VimStateMachine.Mode,
|
modeAfter: VimStateMachine.Mode,
|
||||||
subModeAfter: SubMode,
|
subModeAfter: SubMode,
|
||||||
fileName: String,
|
fileName: String,
|
||||||
) {
|
) {
|
||||||
configureByText(fileName, before)
|
configureByText(fileName, before)
|
||||||
|
|
||||||
@@ -576,12 +577,12 @@ abstract class VimTestCase : UsefulTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun doTest(
|
fun doTest(
|
||||||
keys: List<KeyStroke>,
|
keys: List<KeyStroke>,
|
||||||
before: String,
|
before: String,
|
||||||
after: String?,
|
after: String?,
|
||||||
modeAfter: VimStateMachine.Mode,
|
modeAfter: VimStateMachine.Mode,
|
||||||
subModeAfter: SubMode,
|
subModeAfter: SubMode,
|
||||||
afterEditorInitialized: (Editor) -> Unit,
|
afterEditorInitialized: (Editor) -> Unit,
|
||||||
) {
|
) {
|
||||||
configureByText(before)
|
configureByText(before)
|
||||||
afterEditorInitialized(myFixture.editor)
|
afterEditorInitialized(myFixture.editor)
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,8 @@ package org.jetbrains.plugins.ideavim.action
|
|||||||
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner
|
import com.maddyhome.idea.vim.key.MappingOwner
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
||||||
|
@@ -75,28 +75,6 @@ class UndoActionTest : VimTestCase() {
|
|||||||
assertFalse(hasSelection())
|
assertFalse(hasSelection())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun `test cursor movements do not require additional undo`() {
|
|
||||||
val keys = listOf("a1<Esc>ea2<Esc>ea3<Esc>", "uu")
|
|
||||||
val before = """
|
|
||||||
A Discovery
|
|
||||||
|
|
||||||
${c}I found it in a legendary land
|
|
||||||
all rocks and lavender and tufted grass,
|
|
||||||
where it was settled on some sodden sand
|
|
||||||
hard by the torrent of a mountain pass.
|
|
||||||
""".trimIndent()
|
|
||||||
val after = """
|
|
||||||
A Discovery
|
|
||||||
|
|
||||||
I1 found$c it in a legendary land
|
|
||||||
all rocks and lavender and tufted grass,
|
|
||||||
where it was settled on some sodden sand
|
|
||||||
hard by the torrent of a mountain pass.
|
|
||||||
""".trimIndent()
|
|
||||||
doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE)
|
|
||||||
assertFalse(hasSelection())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hasSelection(): Boolean {
|
private fun hasSelection(): Boolean {
|
||||||
val editor = myFixture.editor
|
val editor = myFixture.editor
|
||||||
return editor.caretModel.primaryCaret.hasSelection()
|
return editor.caretModel.primaryCaret.hasSelection()
|
||||||
|
@@ -20,8 +20,8 @@ package org.jetbrains.plugins.ideavim.action.copy
|
|||||||
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.helper.VimBehaviorDiffers
|
import com.maddyhome.idea.vim.helper.VimBehaviorDiffers
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
|
@@ -56,7 +56,8 @@ class PutViaIdeaTest : VimTestCase() {
|
|||||||
val before = "${c}I found it in a legendary land"
|
val before = "${c}I found it in a legendary land"
|
||||||
configureByText(before)
|
configureByText(before)
|
||||||
|
|
||||||
injector.registerGroup.storeText('"', "legendary", SelectionType.CHARACTER_WISE)
|
VimPlugin.getRegister()
|
||||||
|
.storeText(myFixture.editor.vim, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
|
||||||
|
|
||||||
typeText(injector.parser.parseKeys("ve" + "p"))
|
typeText(injector.parser.parseKeys("ve" + "p"))
|
||||||
val after = "legendar${c}y it in a legendary land"
|
val after = "legendar${c}y it in a legendary land"
|
||||||
|
@@ -115,9 +115,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
@TestWithoutNeovim(SkipNeovimReason.DIFFERENT)
|
@TestWithoutNeovim(SkipNeovimReason.DIFFERENT)
|
||||||
fun `test put visual text multicaret`() {
|
fun `test put visual text multicaret`() {
|
||||||
val before = "${c}I found ${c}it in a ${c}legendary land"
|
val before = "${c}I found ${c}it in a ${c}legendary land"
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "legendary", SelectionType.CHARACTER_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("ve" + "\"*p"))
|
typeText(injector.parser.parseKeys("ve" + "p"))
|
||||||
val after = "legendar${c}y legendar${c}y in a legendar${c}y land"
|
val after = "legendar${c}y legendar${c}y in a legendar${c}y land"
|
||||||
assertState(after)
|
assertState(after)
|
||||||
}
|
}
|
||||||
@@ -254,9 +254,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
${c}hard by the torrent of a mountain pass.
|
${c}hard by the torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "A Discovery\n", SelectionType.LINE_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("ve" + "\"*p"))
|
typeText(injector.parser.parseKeys("ve" + "p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -285,9 +285,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
${c}hard by the$c torrent of a mountain pass.
|
${c}hard by the$c torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "A Discovery\n", SelectionType.LINE_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("ve" + "\"*p"))
|
typeText(injector.parser.parseKeys("ve" + "p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -314,9 +314,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
${c}hard by the$c torrent of a mountain pass.
|
${c}hard by the$c torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "A Discovery\n", SelectionType.LINE_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("ve" + "2\"*p"))
|
typeText(injector.parser.parseKeys("ve" + "2p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -461,10 +461,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
akin to moonlight, tempering its blue,
|
akin to moonlight, tempering its blue,
|
||||||
the dingy ${c}underside, the checquered fringe.
|
the dingy ${c}underside, the checquered fringe.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "|found|\n|l roc|\n|ere i|", SelectionType.BLOCK_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
|
||||||
// VimPlugin.getRegister().storeText(editor.vim, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
|
typeText(injector.parser.parseKeys("ve" + "p"))
|
||||||
typeText(injector.parser.parseKeys("ve" + "\"*p"))
|
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -593,9 +592,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
hard by the ${c}torrent of a mountain pass.
|
hard by the ${c}torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "Discovery", SelectionType.CHARACTER_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("V" + "\"*p"))
|
typeText(injector.parser.parseKeys("V" + "p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -629,9 +628,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
hard by the ${c}torrent of a mountain pass.
|
hard by the ${c}torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "Discovery", SelectionType.CHARACTER_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("V" + "\"*p"))
|
typeText(injector.parser.parseKeys("V" + "p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -754,9 +753,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
hard by the ${c}torrent of a mountain pass.
|
hard by the ${c}torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "A Discovery\n", SelectionType.LINE_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("V" + "\"*p"))
|
typeText(injector.parser.parseKeys("V" + "p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -790,9 +789,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
hard by the ${c}torrent of a mountain pass.
|
hard by the ${c}torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "A Discovery\n", SelectionType.LINE_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("V" + "\"*p"))
|
typeText(injector.parser.parseKeys("V" + "p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
@@ -996,9 +995,9 @@ class PutVisualTextActionTest : VimTestCase() {
|
|||||||
akin to moonlight, tempering its blue,
|
akin to moonlight, tempering its blue,
|
||||||
the dingy ${c}underside, the checquered fringe.
|
the dingy ${c}underside, the checquered fringe.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "|found|\n|l roc|\n|ere i|", SelectionType.BLOCK_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, editor.rangeOf("|found|", 2), SelectionType.BLOCK_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("V" + "\"*p"))
|
typeText(injector.parser.parseKeys("V" + "p"))
|
||||||
val after = """
|
val after = """
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
|
@@ -202,9 +202,9 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() {
|
|||||||
${c}zxcvbn
|
${c}zxcvbn
|
||||||
|
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
configureByText(before)
|
val editor = configureByText(before)
|
||||||
injector.registerGroup.storeText('*', "zxcvbn\n", SelectionType.LINE_WISE)
|
VimPlugin.getRegister().storeText(editor.vim, TextRange(14, 21), SelectionType.LINE_WISE, false)
|
||||||
typeText(injector.parser.parseKeys("vl" + "\"*gp"))
|
typeText(injector.parser.parseKeys("vl" + "gp"))
|
||||||
val after = """
|
val after = """
|
||||||
q
|
q
|
||||||
zxcvbn
|
zxcvbn
|
||||||
|
@@ -24,7 +24,7 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.helper.VimBehaviorDiffers
|
import com.maddyhome.idea.vim.helper.VimBehaviorDiffers
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
||||||
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
@@ -79,48 +79,47 @@ class YankVisualActionTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun `test yank multicaret`() {
|
fun `test yank multicaret`() {
|
||||||
val text = """
|
doTest(
|
||||||
|
injector.parser.parseKeys("viw" + "y"),
|
||||||
|
"""
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
I ${c}found it in a legendary land
|
I ${c}found it in a legendary land
|
||||||
all rocks and lavender and tufted grass,
|
all rocks and lavender and tufted grass,
|
||||||
where it ${c}was settled on some sodden sand
|
where it ${c}was settled on some sodden sand
|
||||||
hard by the torrent of a mountain pass.
|
hard by the torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent(),
|
||||||
configureByText(text)
|
"found\nwas", SelectionType.BLOCK_WISE
|
||||||
typeText(injector.parser.parseKeys("viw" + "y"))
|
)
|
||||||
val editor = myFixture.editor.vim
|
|
||||||
val lastRegister = injector.registerGroup.lastRegisterChar
|
|
||||||
val registers = editor.carets().map { it.registerStorage.getRegister(lastRegister)?.rawText }
|
|
||||||
assertEquals(listOf("found", "was"), registers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo multicaret
|
@TestWithoutNeovim(SkipNeovimReason.DIFFERENT)
|
||||||
// @TestWithoutNeovim(SkipNeovimReason.DIFFERENT)
|
fun testYankVisualRange() {
|
||||||
// fun testYankVisualRange() {
|
val before = """
|
||||||
// val before = """
|
q${c}werty
|
||||||
// q${c}werty
|
asdf${c}gh
|
||||||
// asdf${c}gh
|
${c}zxcvbn
|
||||||
// ${c}zxcvbn
|
|
||||||
//
|
""".trimIndent()
|
||||||
// """.trimIndent()
|
configureByText(before)
|
||||||
// configureByText(before)
|
typeText(injector.parser.parseKeys("vey"))
|
||||||
// typeText(injector.parser.parseKeys("vey"))
|
|
||||||
//
|
val lastRegister = VimPlugin.getRegister().lastRegister
|
||||||
// val lastRegister = VimPlugin.getRegister().lastRegister
|
TestCase.assertNotNull(lastRegister)
|
||||||
// TestCase.assertNotNull(lastRegister)
|
val text = lastRegister!!.text
|
||||||
// val text = lastRegister!!.text
|
TestCase.assertNotNull(text)
|
||||||
// TestCase.assertNotNull(text)
|
|
||||||
//
|
typeText(injector.parser.parseKeys("G" + "$" + "p"))
|
||||||
// typeText(injector.parser.parseKeys("G" + "$" + "p"))
|
val after = """
|
||||||
// val after = """
|
qwerty
|
||||||
// qwerty
|
asdfgh
|
||||||
// asdfgh
|
zxcvbn
|
||||||
// zxcvbn
|
${c}werty
|
||||||
// wert${c}yg${c}hzxcvb${c}n
|
gh
|
||||||
// """.trimIndent()
|
zxcvbn
|
||||||
// assertState(after)
|
""".trimIndent()
|
||||||
// }
|
assertState(after)
|
||||||
|
}
|
||||||
|
|
||||||
fun `test yank line`() {
|
fun `test yank line`() {
|
||||||
doTest(
|
doTest(
|
||||||
@@ -153,22 +152,17 @@ class YankVisualActionTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun `test yank multicaret line`() {
|
fun `test yank multicaret line`() {
|
||||||
val text = """
|
doTest(
|
||||||
|
injector.parser.parseKeys("V" + "y"),
|
||||||
|
"""
|
||||||
A Discovery
|
A Discovery
|
||||||
|
|
||||||
I found it in a legendary land
|
I found it in a legendary land
|
||||||
all ${c}rocks and lavender and tufted grass,
|
all ${c}rocks and lavender and tufted grass,
|
||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
hard by ${c}the torrent of a mountain pass.
|
hard by ${c}the torrent of a mountain pass.
|
||||||
""".trimIndent()
|
""".trimIndent(),
|
||||||
configureByText(text)
|
"all rocks and lavender and tufted grass,\nhard by the torrent of a mountain pass.\n", SelectionType.LINE_WISE
|
||||||
typeText(injector.parser.parseKeys("V" + "y"))
|
|
||||||
val editor = myFixture.editor.vim
|
|
||||||
val lastRegister = injector.registerGroup.lastRegisterChar
|
|
||||||
val registers = editor.carets().map { it.registerStorage.getRegister(lastRegister)?.rawText }
|
|
||||||
assertEquals(
|
|
||||||
listOf("all rocks and lavender and tufted grass,\n", "hard by the torrent of a mountain pass.\n"),
|
|
||||||
registers
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,15 +180,35 @@ class YankVisualActionTest : VimTestCase() {
|
|||||||
configureByText(before)
|
configureByText(before)
|
||||||
typeText(injector.parser.parseKeys("Vy"))
|
typeText(injector.parser.parseKeys("Vy"))
|
||||||
|
|
||||||
|
val lastRegister = VimPlugin.getRegister().lastRegister
|
||||||
|
TestCase.assertNotNull(lastRegister)
|
||||||
|
val text = lastRegister!!.text
|
||||||
|
TestCase.assertNotNull(text)
|
||||||
|
TestCase.assertEquals(
|
||||||
|
"""
|
||||||
|
qwe
|
||||||
|
zxc
|
||||||
|
rty
|
||||||
|
|
||||||
|
""".trimIndent(),
|
||||||
|
text
|
||||||
|
)
|
||||||
|
|
||||||
typeText(injector.parser.parseKeys("p"))
|
typeText(injector.parser.parseKeys("p"))
|
||||||
val after = """
|
val after = """
|
||||||
qwe
|
qwe
|
||||||
${c}qwe
|
${c}qwe
|
||||||
|
zxc
|
||||||
|
rty
|
||||||
asd
|
asd
|
||||||
zxc
|
zxc
|
||||||
${c}zxc
|
${c}qwe
|
||||||
|
zxc
|
||||||
|
rty
|
||||||
|
rty
|
||||||
|
${c}qwe
|
||||||
|
zxc
|
||||||
rty
|
rty
|
||||||
${c}rty
|
|
||||||
fgh
|
fgh
|
||||||
vbn
|
vbn
|
||||||
|
|
||||||
|
@@ -221,9 +221,11 @@ class MultipleCaretsTest : VimTestCase() {
|
|||||||
val after = """qwe
|
val after = """qwe
|
||||||
|rty
|
|rty
|
||||||
|${c}rty
|
|${c}rty
|
||||||
|
|fgh
|
||||||
|asd
|
|asd
|
||||||
|fgh
|
|fgh
|
||||||
|${c}fgh
|
|${c}rty
|
||||||
|
|fgh
|
||||||
|zxc
|
|zxc
|
||||||
|vbn
|
|vbn
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
|
@@ -25,15 +25,15 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.extension.Alias
|
import com.maddyhome.idea.vim.extension.Alias
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionBeanClass
|
import com.maddyhome.idea.vim.extension.ExtensionBeanClass
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
||||||
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionRegistrar
|
import com.maddyhome.idea.vim.extension.VimExtensionRegistrar
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.helper.isEndAllowed
|
import com.maddyhome.idea.vim.helper.isEndAllowed
|
||||||
|
@@ -20,8 +20,8 @@ package org.jetbrains.plugins.ideavim.extension.replacewithregister
|
|||||||
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.helper.VimBehaviorDiffers
|
import com.maddyhome.idea.vim.helper.VimBehaviorDiffers
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import com.maddyhome.idea.vim.register.RegisterConstants.UNNAMED_REGISTER
|
import com.maddyhome.idea.vim.register.RegisterConstants.UNNAMED_REGISTER
|
||||||
@@ -367,7 +367,9 @@ class ReplaceWithRegisterTest : VimTestCase() {
|
|||||||
I found it in a legendary land
|
I found it in a legendary land
|
||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
where it was settled on some sodden sand
|
where it was settled on some sodden sand
|
||||||
|
I found it in a legendary land
|
||||||
|
where it was settled on some sodden sand
|
||||||
|
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -541,32 +541,4 @@ class VimSurroundExtensionTest : VimTestCase() {
|
|||||||
val keys = ":map gw ds)<CR>" + "qqgwqj@q"
|
val keys = ":map gw ds)<CR>" + "qqgwqj@q"
|
||||||
doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE)
|
doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.PLUGIN)
|
|
||||||
fun `test change surround with multicaret`() {
|
|
||||||
val before = """
|
|
||||||
(${c}abc)
|
|
||||||
(${c}xyz)
|
|
||||||
"""
|
|
||||||
val after = """
|
|
||||||
[abc]
|
|
||||||
[xyz]
|
|
||||||
"""
|
|
||||||
|
|
||||||
doTest(listOf("cs(]"), before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE)
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.PLUGIN)
|
|
||||||
fun `test delete surround with multicaret`() {
|
|
||||||
val before = """
|
|
||||||
(${c}abc)
|
|
||||||
(${c}xyz)
|
|
||||||
"""
|
|
||||||
val after = """
|
|
||||||
abc
|
|
||||||
xyz
|
|
||||||
"""
|
|
||||||
|
|
||||||
doTest(listOf("ds("), before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ import com.intellij.ide.IdeEventQueue
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.testFramework.PlatformTestUtil
|
import com.intellij.testFramework.PlatformTestUtil
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.key.CommandNode
|
import com.maddyhome.idea.vim.common.CommandNode
|
||||||
import com.maddyhome.idea.vim.helper.vimStateMachine
|
import com.maddyhome.idea.vim.helper.vimStateMachine
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
|
Binary file not shown.
@@ -29,12 +29,12 @@ import com.maddyhome.idea.vim.command.VimStateMachine
|
|||||||
import com.maddyhome.idea.vim.command.VimStateMachine.Companion.getInstance
|
import com.maddyhome.idea.vim.command.VimStateMachine.Companion.getInstance
|
||||||
import com.maddyhome.idea.vim.command.MappingState
|
import com.maddyhome.idea.vim.command.MappingState
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.key.CommandNode
|
import com.maddyhome.idea.vim.common.CommandNode
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.common.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.common.CurrentCommandState
|
import com.maddyhome.idea.vim.common.CurrentCommandState
|
||||||
import com.maddyhome.idea.vim.common.DigraphResult
|
import com.maddyhome.idea.vim.common.DigraphResult
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.key.Node
|
import com.maddyhome.idea.vim.common.Node
|
||||||
import com.maddyhome.idea.vim.common.argumentCaptured
|
import com.maddyhome.idea.vim.common.argumentCaptured
|
||||||
import com.maddyhome.idea.vim.diagnostic.VimLogger
|
import com.maddyhome.idea.vim.diagnostic.VimLogger
|
||||||
import com.maddyhome.idea.vim.diagnostic.debug
|
import com.maddyhome.idea.vim.diagnostic.debug
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim.action.change.change
|
package com.maddyhome.idea.vim.action.change.change
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.action.copy.YankMotionAction
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
@@ -34,6 +35,19 @@ class ChangeMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableO
|
|||||||
|
|
||||||
override val duplicateWith: Char = 'c'
|
override val duplicateWith: Char = 'c'
|
||||||
|
|
||||||
|
private var isMultiCaret = false
|
||||||
|
|
||||||
|
override fun baseExecute(
|
||||||
|
editor: VimEditor,
|
||||||
|
caret: VimCaret,
|
||||||
|
context: ExecutionContext,
|
||||||
|
cmd: Command,
|
||||||
|
operatorArguments: OperatorArguments
|
||||||
|
): Boolean {
|
||||||
|
isMultiCaret = YankMotionAction().yankIfMultiCaret(cmd, editor, context, operatorArguments)
|
||||||
|
return super.baseExecute(editor, caret, context, cmd, operatorArguments)
|
||||||
|
}
|
||||||
|
|
||||||
override fun execute(
|
override fun execute(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
caret: VimCaret,
|
caret: VimCaret,
|
||||||
@@ -46,7 +60,8 @@ class ChangeMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableO
|
|||||||
caret,
|
caret,
|
||||||
context,
|
context,
|
||||||
argument,
|
argument,
|
||||||
operatorArguments
|
operatorArguments,
|
||||||
|
noYank = isMultiCaret
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim.action.change.change
|
package com.maddyhome.idea.vim.action.change.change
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.action.copy.YankVisualAction
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
@@ -37,6 +38,18 @@ class ChangeVisualAction : VisualOperatorActionHandler.ForEachCaret() {
|
|||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_MULTIKEY_UNDO, CommandFlags.FLAG_EXIT_VISUAL)
|
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_MULTIKEY_UNDO, CommandFlags.FLAG_EXIT_VISUAL)
|
||||||
|
|
||||||
|
private var isMultiCaret = false
|
||||||
|
|
||||||
|
override fun beforeExecution(
|
||||||
|
editor: VimEditor,
|
||||||
|
context: ExecutionContext,
|
||||||
|
cmd: Command,
|
||||||
|
caretsAndSelections: Map<VimCaret, VimSelection>
|
||||||
|
): Boolean {
|
||||||
|
isMultiCaret = YankVisualAction().yankIfMultiCaret(editor, caretsAndSelections)
|
||||||
|
return super.beforeExecution(editor, context, cmd, caretsAndSelections)
|
||||||
|
}
|
||||||
|
|
||||||
override fun executeAction(
|
override fun executeAction(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
caret: VimCaret,
|
caret: VimCaret,
|
||||||
@@ -50,7 +63,8 @@ class ChangeVisualAction : VisualOperatorActionHandler.ForEachCaret() {
|
|||||||
caret,
|
caret,
|
||||||
range.toVimTextRange(false),
|
range.toVimTextRange(false),
|
||||||
range.type,
|
range.type,
|
||||||
context
|
context,
|
||||||
|
noYank = isMultiCaret
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim.action.change.delete
|
package com.maddyhome.idea.vim.action.change.delete
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.action.copy.YankMotionAction
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
@@ -36,6 +37,19 @@ class DeleteMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableO
|
|||||||
|
|
||||||
override val duplicateWith: Char = 'd'
|
override val duplicateWith: Char = 'd'
|
||||||
|
|
||||||
|
private var isMultiCaret = false
|
||||||
|
|
||||||
|
override fun baseExecute(
|
||||||
|
editor: VimEditor,
|
||||||
|
caret: VimCaret,
|
||||||
|
context: ExecutionContext,
|
||||||
|
cmd: Command,
|
||||||
|
operatorArguments: OperatorArguments
|
||||||
|
): Boolean {
|
||||||
|
isMultiCaret = YankMotionAction().yankIfMultiCaret(cmd, editor, context, operatorArguments)
|
||||||
|
return super.baseExecute(editor, caret, context, cmd, operatorArguments)
|
||||||
|
}
|
||||||
|
|
||||||
override fun execute(
|
override fun execute(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
caret: VimCaret,
|
caret: VimCaret,
|
||||||
@@ -53,7 +67,7 @@ class DeleteMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableO
|
|||||||
val (first, second) = injector.changeGroup
|
val (first, second) = injector.changeGroup
|
||||||
.getDeleteRangeAndType(editor, caret, context, argument, false, operatorArguments)
|
.getDeleteRangeAndType(editor, caret, context, argument, false, operatorArguments)
|
||||||
?: return false
|
?: return false
|
||||||
return injector.changeGroup.deleteRange(editor, caret, first, second, false)
|
return injector.changeGroup.deleteRange(editor, caret, first, second, false, noYank = isMultiCaret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim.action.change.delete
|
package com.maddyhome.idea.vim.action.change.delete
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.action.copy.YankVisualAction
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
@@ -37,6 +38,18 @@ class DeleteVisualAction : VisualOperatorActionHandler.ForEachCaret() {
|
|||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_EXIT_VISUAL)
|
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_EXIT_VISUAL)
|
||||||
|
|
||||||
|
private var isMultiCaret = false
|
||||||
|
|
||||||
|
override fun beforeExecution(
|
||||||
|
editor: VimEditor,
|
||||||
|
context: ExecutionContext,
|
||||||
|
cmd: Command,
|
||||||
|
caretsAndSelections: Map<VimCaret, VimSelection>,
|
||||||
|
): Boolean {
|
||||||
|
isMultiCaret = YankVisualAction().yankIfMultiCaret(editor, caretsAndSelections)
|
||||||
|
return super.beforeExecution(editor, context, cmd, caretsAndSelections)
|
||||||
|
}
|
||||||
|
|
||||||
override fun executeAction(
|
override fun executeAction(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
caret: VimCaret,
|
caret: VimCaret,
|
||||||
@@ -45,7 +58,13 @@ class DeleteVisualAction : VisualOperatorActionHandler.ForEachCaret() {
|
|||||||
range: VimSelection,
|
range: VimSelection,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val selectionType = range.type
|
return injector.changeGroup.deleteRange(
|
||||||
return injector.changeGroup.deleteRange(editor, caret, range.toVimTextRange(false), selectionType, false)
|
editor,
|
||||||
|
caret,
|
||||||
|
range.toVimTextRange(false),
|
||||||
|
range.type,
|
||||||
|
false,
|
||||||
|
noYank = isMultiCaret
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
package com.maddyhome.idea.vim.action.copy
|
package com.maddyhome.idea.vim.action.copy
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
import com.maddyhome.idea.vim.command.Argument
|
||||||
@@ -41,28 +40,14 @@ sealed class PutTextBaseAction(
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments
|
operatorArguments: OperatorArguments
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val count = operatorArguments.count1
|
val lastRegister = injector.registerGroup.lastRegister
|
||||||
val caretToPutData = editor.sortedCarets().associateWith { getPutDataForCaret(it, count) }
|
val textData = if (lastRegister != null) TextData(
|
||||||
var result = true
|
lastRegister.text ?: injector.parser.toPrintableString(lastRegister.keys),
|
||||||
injector.application.runWriteAction {
|
lastRegister.type,
|
||||||
caretToPutData.forEach {
|
lastRegister.transferableData
|
||||||
result = injector.put.putTextForCaret(editor, it.key, context, it.value) && result
|
) else null
|
||||||
}
|
val putData = PutData(textData, null, operatorArguments.count1, insertTextBeforeCaret, indent, caretAfterInsertedText, -1)
|
||||||
}
|
return injector.put.putText(editor, context, putData)
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPutDataForCaret(caret: VimCaret, count: Int): PutData {
|
|
||||||
val lastRegisterChar = injector.registerGroup.lastRegisterChar
|
|
||||||
val register = caret.registerStorage.getRegister(lastRegisterChar)
|
|
||||||
val textData = register?.let {
|
|
||||||
TextData(
|
|
||||||
register.text ?: injector.parser.toPrintableString(register.keys),
|
|
||||||
register.type,
|
|
||||||
register.transferableData
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return PutData(textData, null, count, insertTextBeforeCaret, indent, caretAfterInsertedText, -1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,30 +52,16 @@ sealed class PutVisualTextBaseAction(
|
|||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (caretsAndSelections.isEmpty()) return false
|
if (caretsAndSelections.isEmpty()) return false
|
||||||
val count = cmd.count
|
val textData = injector.registerGroup.lastRegister?.let { PutData.TextData(it.text, it.type, it.transferableData) }
|
||||||
val caretToPutData = editor.sortedCarets().associateWith { getPutDataForCaret(it, caretsAndSelections[it], count) }
|
|
||||||
injector.registerGroup.resetRegister()
|
injector.registerGroup.resetRegister()
|
||||||
var result = true
|
|
||||||
injector.application.runWriteAction {
|
|
||||||
caretToPutData.forEach {
|
|
||||||
result = injector.put.putTextForCaret(editor, it.key, context, it.value, true) && result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPutDataForCaret(caret: VimCaret, selection: VimSelection?, count: Int): PutData {
|
val selection = PutData.VisualSelection(
|
||||||
val lastRegisterChar = injector.registerGroup.lastRegisterChar
|
caretsAndSelections,
|
||||||
val register = caret.registerStorage.getRegister(lastRegisterChar)
|
caretsAndSelections.values.first().type
|
||||||
val textData = register?.let {
|
)
|
||||||
PutData.TextData(
|
val putData = PutData(textData, selection, cmd.count, insertTextBeforeCaret, indent, caretAfterInsertedText)
|
||||||
register.text ?: injector.parser.toPrintableString(register.keys),
|
|
||||||
register.type,
|
return injector.put.putText(editor, context, putData, true)
|
||||||
register.transferableData
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val visualSelection = selection?.let { PutData.VisualSelection(mapOf(caret to it), it.type) }
|
|
||||||
return PutData(textData, visualSelection, count, insertTextBeforeCaret, indent, caretAfterInsertedText)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,8 +38,27 @@ class YankMotionAction : VimActionHandler.SingleExecution(), DuplicableOperatorA
|
|||||||
context: ExecutionContext,
|
context: ExecutionContext,
|
||||||
cmd: Command,
|
cmd: Command,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
|
): Boolean {
|
||||||
|
return executeYank(cmd, editor, context, operatorArguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun executeYank(
|
||||||
|
cmd: Command,
|
||||||
|
editor: VimEditor,
|
||||||
|
context: ExecutionContext,
|
||||||
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val argument = cmd.argument ?: return false
|
val argument = cmd.argument ?: return false
|
||||||
return injector.yank.yankMotion(editor, context, argument, operatorArguments)
|
return injector.yank.yankMotion(editor, context, argument, operatorArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun yankIfMultiCaret(cmd: Command, editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): Boolean {
|
||||||
|
if (editor.nativeCarets().size > 1) {
|
||||||
|
executeYank(cmd, editor, context, operatorArguments)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,13 @@ class YankVisualAction : VisualOperatorActionHandler.SingleExecution() {
|
|||||||
cmd: Command,
|
cmd: Command,
|
||||||
caretsAndSelections: Map<VimCaret, VimSelection>,
|
caretsAndSelections: Map<VimCaret, VimSelection>,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
|
): Boolean {
|
||||||
|
return executeYank(editor, caretsAndSelections)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun executeYank(
|
||||||
|
editor: VimEditor,
|
||||||
|
caretsAndSelections: Map<VimCaret, VimSelection>,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val selections = caretsAndSelections.values
|
val selections = caretsAndSelections.values
|
||||||
val starts: MutableList<Int> = ArrayList()
|
val starts: MutableList<Int> = ArrayList()
|
||||||
@@ -58,4 +65,14 @@ class YankVisualAction : VisualOperatorActionHandler.SingleExecution() {
|
|||||||
val endsArray = ends.toIntArray()
|
val endsArray = ends.toIntArray()
|
||||||
return injector.yank.yankRange(editor, TextRange(startsArray, endsArray), vimSelection.type, true)
|
return injector.yank.yankRange(editor, TextRange(startsArray, endsArray), vimSelection.type, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun yankIfMultiCaret(editor: VimEditor, caretsAndSelections: Map<VimCaret, VimSelection>): Boolean {
|
||||||
|
if (caretsAndSelections.size > 1) {
|
||||||
|
executeYank(editor, caretsAndSelections)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,12 @@
|
|||||||
package com.maddyhome.idea.vim.api
|
package com.maddyhome.idea.vim.api
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.common.EditorLine
|
import com.maddyhome.idea.vim.common.EditorLine
|
||||||
import com.maddyhome.idea.vim.common.LiveRange
|
import com.maddyhome.idea.vim.common.LiveRange
|
||||||
import com.maddyhome.idea.vim.common.Offset
|
import com.maddyhome.idea.vim.common.Offset
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
|
||||||
import com.maddyhome.idea.vim.group.visual.VisualChange
|
import com.maddyhome.idea.vim.group.visual.VisualChange
|
||||||
import com.maddyhome.idea.vim.register.Register
|
|
||||||
import javax.swing.KeyStroke
|
|
||||||
|
|
||||||
// TODO: 29.12.2021 Split interface to mutable and immutable
|
// TODO: 29.12.2021 Split interface to mutable and immutable
|
||||||
interface VimCaret {
|
interface VimCaret {
|
||||||
val registerStorage: CaretRegisterStorage
|
|
||||||
val editor: VimEditor
|
val editor: VimEditor
|
||||||
val offset: Offset
|
val offset: Offset
|
||||||
var vimLastColumn: Int
|
var vimLastColumn: Int
|
||||||
@@ -40,20 +35,4 @@ interface VimCaret {
|
|||||||
fun moveToVisualPosition(position: VimVisualPosition)
|
fun moveToVisualPosition(position: VimVisualPosition)
|
||||||
fun setNativeSelection(start: Offset, end: Offset)
|
fun setNativeSelection(start: Offset, end: Offset)
|
||||||
fun removeNativeSelection()
|
fun removeNativeSelection()
|
||||||
}
|
|
||||||
|
|
||||||
interface CaretRegisterStorage {
|
|
||||||
/**
|
|
||||||
* Stores text to caret's recordable (named/numbered/unnamed) register
|
|
||||||
*/
|
|
||||||
fun storeText(editor: VimEditor, range: TextRange, type: SelectionType, isDelete: Boolean): Boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets text from caret's recordable register
|
|
||||||
* If the register is not recordable - global text state will be returned
|
|
||||||
*/
|
|
||||||
fun getRegister(r: Char): Register?
|
|
||||||
|
|
||||||
fun setKeys(register: Char, keys: List<KeyStroke>)
|
|
||||||
fun saveRegister(r: Char, register: Register)
|
|
||||||
}
|
}
|
@@ -1,56 +0,0 @@
|
|||||||
package com.maddyhome.idea.vim.api
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
|
||||||
import com.maddyhome.idea.vim.register.Register
|
|
||||||
import com.maddyhome.idea.vim.register.RegisterConstants
|
|
||||||
import com.maddyhome.idea.vim.register.VimRegisterGroupBase
|
|
||||||
import javax.swing.KeyStroke
|
|
||||||
|
|
||||||
abstract class VimCaretBase : VimCaret
|
|
||||||
|
|
||||||
open class CaretRegisterStorageBase(private val isCaretPrimary: Boolean) : CaretRegisterStorage, VimRegisterGroupBase() {
|
|
||||||
override var lastRegisterChar: Char
|
|
||||||
get() {
|
|
||||||
return injector.registerGroup.lastRegisterChar
|
|
||||||
}
|
|
||||||
set(value) {}
|
|
||||||
|
|
||||||
override fun storeText(editor: VimEditor, range: TextRange, type: SelectionType, isDelete: Boolean): Boolean {
|
|
||||||
if (isCaretPrimary) {
|
|
||||||
return injector.registerGroup.storeText(editor, range, type, isDelete)
|
|
||||||
}
|
|
||||||
val register = lastRegisterChar
|
|
||||||
if (!RegisterConstants.RECORDABLE_REGISTERS.contains(register)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return super.storeText(editor, range, type, isDelete)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRegister(r: Char): Register? {
|
|
||||||
if (isCaretPrimary || !RegisterConstants.RECORDABLE_REGISTERS.contains(r)) {
|
|
||||||
return injector.registerGroup.getRegister(r)
|
|
||||||
}
|
|
||||||
return super.getRegister(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setKeys(register: Char, keys: List<KeyStroke>) {
|
|
||||||
if (isCaretPrimary) {
|
|
||||||
injector.registerGroup.setKeys(register, keys)
|
|
||||||
}
|
|
||||||
if (!RegisterConstants.RECORDABLE_REGISTERS.contains(register)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return super.setKeys(register, keys)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun saveRegister(r: Char, register: Register) {
|
|
||||||
if (isCaretPrimary) {
|
|
||||||
injector.registerGroup.saveRegister(r, register)
|
|
||||||
}
|
|
||||||
if (!RegisterConstants.RECORDABLE_REGISTERS.contains(r)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return super.saveRegister(r, register)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -83,14 +83,14 @@ interface VimChangeGroup {
|
|||||||
|
|
||||||
fun getDeleteRangeAndType2(editor: VimEditor, caret: VimCaret, context: ExecutionContext, argument: Argument, isChange: Boolean, operatorArguments: OperatorArguments): Pair<TextRange, SelectionType>?
|
fun getDeleteRangeAndType2(editor: VimEditor, caret: VimCaret, context: ExecutionContext, argument: Argument, isChange: Boolean, operatorArguments: OperatorArguments): Pair<TextRange, SelectionType>?
|
||||||
|
|
||||||
fun deleteRange(editor: VimEditor, caret: VimCaret, range: TextRange, type: SelectionType?, isChange: Boolean): Boolean
|
fun deleteRange(editor: VimEditor, caret: VimCaret, range: TextRange, type: SelectionType?, isChange: Boolean, noYank: Boolean = false): Boolean
|
||||||
fun deleteRange2(editor: VimEditor, caret: VimCaret, range: TextRange, type: SelectionType): Boolean
|
fun deleteRange2(editor: VimEditor, caret: VimCaret, range: TextRange, type: SelectionType): Boolean
|
||||||
|
|
||||||
fun changeCharacters(editor: VimEditor, caret: VimCaret, count: Int): Boolean
|
fun changeCharacters(editor: VimEditor, caret: VimCaret, count: Int): Boolean
|
||||||
|
|
||||||
fun changeEndOfLine(editor: VimEditor, caret: VimCaret, count: Int): Boolean
|
fun changeEndOfLine(editor: VimEditor, caret: VimCaret, count: Int): Boolean
|
||||||
|
|
||||||
fun changeMotion(editor: VimEditor, caret: VimCaret, context: ExecutionContext, argument: Argument, operatorArguments: OperatorArguments): Boolean
|
fun changeMotion(editor: VimEditor, caret: VimCaret, context: ExecutionContext, argument: Argument, operatorArguments: OperatorArguments, noYank: Boolean = false): Boolean
|
||||||
|
|
||||||
fun changeCaseToggleCharacter(editor: VimEditor, caret: VimCaret, count: Int): Boolean
|
fun changeCaseToggleCharacter(editor: VimEditor, caret: VimCaret, count: Int): Boolean
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ interface VimChangeGroup {
|
|||||||
|
|
||||||
fun changeCaseRange(editor: VimEditor, caret: VimCaret, range: TextRange, type: Char): Boolean
|
fun changeCaseRange(editor: VimEditor, caret: VimCaret, range: TextRange, type: Char): Boolean
|
||||||
|
|
||||||
fun changeRange(editor: VimEditor, caret: VimCaret, range: TextRange, type: SelectionType, context: ExecutionContext?): Boolean
|
fun changeRange(editor: VimEditor, caret: VimCaret, range: TextRange, type: SelectionType, context: ExecutionContext?, noYank: Boolean = false): Boolean
|
||||||
|
|
||||||
fun changeCaseMotion(editor: VimEditor, caret: VimCaret, context: ExecutionContext?, type: Char, argument: Argument, operatorArguments: OperatorArguments): Boolean
|
fun changeCaseMotion(editor: VimEditor, caret: VimCaret, context: ExecutionContext?, type: Char, argument: Argument, operatorArguments: OperatorArguments): Boolean
|
||||||
|
|
||||||
|
@@ -4,10 +4,10 @@ import com.maddyhome.idea.vim.KeyHandler
|
|||||||
import com.maddyhome.idea.vim.command.Argument
|
import com.maddyhome.idea.vim.command.Argument
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
import com.maddyhome.idea.vim.command.CommandFlags
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine
|
|
||||||
import com.maddyhome.idea.vim.command.VimStateMachine.Companion.getInstance
|
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
|
import com.maddyhome.idea.vim.command.VimStateMachine
|
||||||
|
import com.maddyhome.idea.vim.command.VimStateMachine.Companion.getInstance
|
||||||
import com.maddyhome.idea.vim.common.ChangesListener
|
import com.maddyhome.idea.vim.common.ChangesListener
|
||||||
import com.maddyhome.idea.vim.common.Offset
|
import com.maddyhome.idea.vim.common.Offset
|
||||||
import com.maddyhome.idea.vim.common.OperatedRange
|
import com.maddyhome.idea.vim.common.OperatedRange
|
||||||
@@ -17,10 +17,10 @@ import com.maddyhome.idea.vim.diagnostic.debug
|
|||||||
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
||||||
import com.maddyhome.idea.vim.helper.vimStateMachine
|
|
||||||
import com.maddyhome.idea.vim.helper.inInsertMode
|
import com.maddyhome.idea.vim.helper.inInsertMode
|
||||||
import com.maddyhome.idea.vim.helper.inSingleCommandMode
|
import com.maddyhome.idea.vim.helper.inSingleCommandMode
|
||||||
import com.maddyhome.idea.vim.helper.usesVirtualSpace
|
import com.maddyhome.idea.vim.helper.usesVirtualSpace
|
||||||
|
import com.maddyhome.idea.vim.helper.vimStateMachine
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
||||||
import com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_END
|
import com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_END
|
||||||
import com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_POS
|
import com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_POS
|
||||||
@@ -83,7 +83,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
override fun deleteCharacter(editor: VimEditor, caret: VimCaret, count: Int, isChange: Boolean): Boolean {
|
override fun deleteCharacter(editor: VimEditor, caret: VimCaret, count: Int, isChange: Boolean): Boolean {
|
||||||
val endOffset = injector.motion.getOffsetOfHorizontalMotion(editor, caret, count, true)
|
val endOffset = injector.motion.getOffsetOfHorizontalMotion(editor, caret, count, true)
|
||||||
if (endOffset != -1) {
|
if (endOffset != -1) {
|
||||||
val res = deleteText(editor, TextRange(caret.offset.point, endOffset), SelectionType.CHARACTER_WISE, caret)
|
val res = deleteText(editor, TextRange(caret.offset.point, endOffset), SelectionType.CHARACTER_WISE)
|
||||||
val pos = caret.offset.point
|
val pos = caret.offset.point
|
||||||
val norm = injector.engineEditorHelper.normalizeOffset(editor, caret.getLogicalPosition().line, pos, isChange)
|
val norm = injector.engineEditorHelper.normalizeOffset(editor, caret.getLogicalPosition().line, pos, isChange)
|
||||||
if (norm != pos ||
|
if (norm != pos ||
|
||||||
@@ -132,7 +132,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
range: TextRange,
|
range: TextRange,
|
||||||
type: SelectionType?,
|
type: SelectionType?,
|
||||||
caret: VimCaret,
|
noYank: Boolean = false
|
||||||
): Boolean {
|
): Boolean {
|
||||||
var updatedRange = range
|
var updatedRange = range
|
||||||
// Fix for https://youtrack.jetbrains.net/issue/VIM-35
|
// Fix for https://youtrack.jetbrains.net/issue/VIM-35
|
||||||
@@ -146,7 +146,8 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type == null ||
|
if (type == null ||
|
||||||
editor.inInsertMode || caret.registerStorage.storeText(editor, updatedRange, type, true)
|
noYank ||
|
||||||
|
editor.inInsertMode || injector.registerGroup.storeText(editor, updatedRange, type, true)
|
||||||
) {
|
) {
|
||||||
val startOffsets = updatedRange.startOffsets
|
val startOffsets = updatedRange.startOffsets
|
||||||
val endOffsets = updatedRange.endOffsets
|
val endOffsets = updatedRange.endOffsets
|
||||||
@@ -155,10 +156,8 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
}
|
}
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
val start = updatedRange.startOffset
|
val start = updatedRange.startOffset
|
||||||
if (editor.primaryCaret() == caret) {
|
injector.markGroup.setMark(editor, MARK_CHANGE_POS, start)
|
||||||
injector.markGroup.setMark(editor, MARK_CHANGE_POS, start)
|
injector.markGroup.setChangeMarks(editor, TextRange(start, start + 1))
|
||||||
injector.markGroup.setChangeMarks(editor, TextRange(start, start + 1))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -634,7 +633,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
val rangeToDelete = TextRange(startOffset, offset)
|
val rangeToDelete = TextRange(startOffset, offset)
|
||||||
editor.nativeCarets().filter { it != caret && rangeToDelete.contains(it.offset.point) }
|
editor.nativeCarets().filter { it != caret && rangeToDelete.contains(it.offset.point) }
|
||||||
.forEach { editor.removeCaret(it) }
|
.forEach { editor.removeCaret(it) }
|
||||||
val res = deleteText(editor, rangeToDelete, SelectionType.CHARACTER_WISE, caret)
|
val res = deleteText(editor, rangeToDelete, SelectionType.CHARACTER_WISE)
|
||||||
if (usesVirtualSpace) {
|
if (usesVirtualSpace) {
|
||||||
injector.motion.moveCaret(editor, caret, startOffset)
|
injector.motion.moveCaret(editor, caret, startOffset)
|
||||||
} else {
|
} else {
|
||||||
@@ -729,7 +728,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
logger.debug("offset=$offset")
|
logger.debug("offset=$offset")
|
||||||
}
|
}
|
||||||
if (offset != -1) {
|
if (offset != -1) {
|
||||||
val res = deleteText(editor, TextRange(start, offset), SelectionType.LINE_WISE, caret)
|
val res = deleteText(editor, TextRange(start, offset), SelectionType.LINE_WISE)
|
||||||
if (res && caret.offset.point >= editor.fileSize() && caret.offset.point != 0) {
|
if (res && caret.offset.point >= editor.fileSize() && caret.offset.point != 0) {
|
||||||
injector.motion.moveCaret(
|
injector.motion.moveCaret(
|
||||||
editor, caret, injector.motion.moveCaretToLineStartSkipLeadingOffset(
|
editor, caret, injector.motion.moveCaretToLineStartSkipLeadingOffset(
|
||||||
@@ -854,12 +853,13 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
range: TextRange,
|
range: TextRange,
|
||||||
type: SelectionType?,
|
type: SelectionType?,
|
||||||
isChange: Boolean,
|
isChange: Boolean,
|
||||||
|
noYank: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
|
||||||
// Update the last column before we delete, or we might be retrieving the data for a line that no longer exists
|
// Update the last column before we delete, or we might be retrieving the data for a line that no longer exists
|
||||||
caret.vimLastColumn = caret.inlayAwareVisualColumn
|
caret.vimLastColumn = caret.inlayAwareVisualColumn
|
||||||
val removeLastNewLine = removeLastNewLine(editor, range, type)
|
val removeLastNewLine = removeLastNewLine(editor, range, type)
|
||||||
val res = deleteText(editor, range, type, caret)
|
val res = deleteText(editor, range, type)
|
||||||
if (removeLastNewLine) {
|
if (removeLastNewLine) {
|
||||||
val textLength = editor.fileSize().toInt()
|
val textLength = editor.fileSize().toInt()
|
||||||
editor.deleteString(TextRange(textLength - 1, textLength))
|
editor.deleteString(TextRange(textLength - 1, textLength))
|
||||||
@@ -978,7 +978,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
} else {
|
} else {
|
||||||
injector.motion.moveCaretToLineStart(editor, caret.getLogicalPosition().line + 1)
|
injector.motion.moveCaretToLineStart(editor, caret.getLogicalPosition().line + 1)
|
||||||
}
|
}
|
||||||
deleteText(editor, TextRange(caret.offset.point, offset), null, caret)
|
deleteText(editor, TextRange(caret.offset.point, offset), null)
|
||||||
if (spaces && !hasTrailingWhitespace) {
|
if (spaces && !hasTrailingWhitespace) {
|
||||||
insertText(editor, caret, " ")
|
insertText(editor, caret, " ")
|
||||||
injector.motion.moveCaret(
|
injector.motion.moveCaret(
|
||||||
|
@@ -9,11 +9,11 @@ import com.maddyhome.idea.vim.helper.VimCommandLineHelper
|
|||||||
import com.maddyhome.idea.vim.history.VimHistory
|
import com.maddyhome.idea.vim.history.VimHistory
|
||||||
import com.maddyhome.idea.vim.macro.VimMacro
|
import com.maddyhome.idea.vim.macro.VimMacro
|
||||||
import com.maddyhome.idea.vim.mark.VimMarkGroup
|
import com.maddyhome.idea.vim.mark.VimMarkGroup
|
||||||
import com.maddyhome.idea.vim.vimscript.services.OptionService
|
import com.maddyhome.idea.vim.options.OptionService
|
||||||
import com.maddyhome.idea.vim.put.VimPut
|
import com.maddyhome.idea.vim.put.VimPut
|
||||||
import com.maddyhome.idea.vim.register.VimRegisterGroup
|
import com.maddyhome.idea.vim.register.VimRegisterGroup
|
||||||
import com.maddyhome.idea.vim.undo.VimUndoRedo
|
import com.maddyhome.idea.vim.undo.VimUndoRedo
|
||||||
import com.maddyhome.idea.vim.vimscript.services.VariableService
|
import com.maddyhome.idea.vim.vimscript.services.VimVariableService
|
||||||
import com.maddyhome.idea.vim.yank.VimYankGroup
|
import com.maddyhome.idea.vim.yank.VimYankGroup
|
||||||
|
|
||||||
interface VimInjector {
|
interface VimInjector {
|
||||||
@@ -117,7 +117,7 @@ interface VimInjector {
|
|||||||
// Can't be fully moved to vim-engine.
|
// Can't be fully moved to vim-engine.
|
||||||
val vimscriptParser: VimscriptParser
|
val vimscriptParser: VimscriptParser
|
||||||
// !! in progress
|
// !! in progress
|
||||||
val variableService: VariableService
|
val variableService: VimVariableService
|
||||||
// !! in progress
|
// !! in progress
|
||||||
val functionService: VimscriptFunctionService
|
val functionService: VimscriptFunctionService
|
||||||
// Can't be fully moved to vim-engine.
|
// Can't be fully moved to vim-engine.
|
||||||
|
@@ -8,10 +8,10 @@ import com.maddyhome.idea.vim.api.stubs.VimProcessGroupStub
|
|||||||
import com.maddyhome.idea.vim.common.VimMachine
|
import com.maddyhome.idea.vim.common.VimMachine
|
||||||
import com.maddyhome.idea.vim.common.VimMachineBase
|
import com.maddyhome.idea.vim.common.VimMachineBase
|
||||||
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
||||||
import com.maddyhome.idea.vim.vimscript.services.OptionService
|
import com.maddyhome.idea.vim.options.OptionService
|
||||||
import com.maddyhome.idea.vim.register.VimRegisterGroup
|
import com.maddyhome.idea.vim.register.VimRegisterGroup
|
||||||
import com.maddyhome.idea.vim.register.VimRegisterGroupBase
|
import com.maddyhome.idea.vim.register.VimRegisterGroupBase
|
||||||
import com.maddyhome.idea.vim.vimscript.services.VariableService
|
import com.maddyhome.idea.vim.vimscript.services.VimVariableService
|
||||||
import com.maddyhome.idea.vim.vimscript.services.VimVariableServiceBase
|
import com.maddyhome.idea.vim.vimscript.services.VimVariableServiceBase
|
||||||
|
|
||||||
abstract class VimInjectorBase : VimInjector {
|
abstract class VimInjectorBase : VimInjector {
|
||||||
@@ -23,7 +23,7 @@ abstract class VimInjectorBase : VimInjector {
|
|||||||
override val parser: VimStringParser = object : VimStringParserBase() {}
|
override val parser: VimStringParser = object : VimStringParserBase() {}
|
||||||
override val vimMachine: VimMachine = object : VimMachineBase() {}
|
override val vimMachine: VimMachine = object : VimMachineBase() {}
|
||||||
override val optionService: OptionService by lazy { object : VimOptionServiceBase(){} }
|
override val optionService: OptionService by lazy { object : VimOptionServiceBase(){} }
|
||||||
override val variableService: VariableService by lazy { object : VimVariableServiceBase(){} }
|
override val variableService: VimVariableService by lazy { object : VimVariableServiceBase(){} }
|
||||||
|
|
||||||
override val registerGroup: VimRegisterGroup by lazy { registerGroupStub }
|
override val registerGroup: VimRegisterGroup by lazy { registerGroupStub }
|
||||||
override val registerGroupIfCreated: VimRegisterGroup? by lazy { registerGroupStub }
|
override val registerGroupIfCreated: VimRegisterGroup? by lazy { registerGroupStub }
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim.api
|
package com.maddyhome.idea.vim.api
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.common.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.key.KeyMapping
|
import com.maddyhome.idea.vim.key.KeyMapping
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package com.maddyhome.idea.vim.api
|
package com.maddyhome.idea.vim.api
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.common.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
import com.maddyhome.idea.vim.key.RootNode
|
import com.maddyhome.idea.vim.common.RootNode
|
||||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
||||||
import com.maddyhome.idea.vim.key.KeyMapping
|
import com.maddyhome.idea.vim.key.KeyMapping
|
||||||
|
@@ -3,11 +3,12 @@ package com.maddyhome.idea.vim.api
|
|||||||
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.option.ToggleOption
|
import com.maddyhome.idea.vim.option.ToggleOption
|
||||||
import com.maddyhome.idea.vim.option.NumberOption
|
import com.maddyhome.idea.vim.options.NumberOption
|
||||||
import com.maddyhome.idea.vim.options.Option
|
import com.maddyhome.idea.vim.options.Option
|
||||||
import com.maddyhome.idea.vim.options.OptionChangeListener
|
import com.maddyhome.idea.vim.options.OptionChangeListener
|
||||||
import com.maddyhome.idea.vim.options.OptionConstants
|
import com.maddyhome.idea.vim.options.OptionConstants
|
||||||
import com.maddyhome.idea.vim.options.OptionScope
|
import com.maddyhome.idea.vim.options.OptionScope
|
||||||
|
import com.maddyhome.idea.vim.options.OptionService
|
||||||
import com.maddyhome.idea.vim.options.StringOption
|
import com.maddyhome.idea.vim.options.StringOption
|
||||||
import com.maddyhome.idea.vim.options.helpers.GuiCursorOptionHelper
|
import com.maddyhome.idea.vim.options.helpers.GuiCursorOptionHelper
|
||||||
import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper
|
import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper
|
||||||
@@ -15,7 +16,6 @@ import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
|||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.parseNumber
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.parseNumber
|
||||||
import com.maddyhome.idea.vim.vimscript.services.OptionService
|
|
||||||
|
|
||||||
abstract class VimOptionServiceBase : OptionService {
|
abstract class VimOptionServiceBase : OptionService {
|
||||||
private val localOptionsKey = Key<MutableMap<String, VimDataType>>("localOptions")
|
private val localOptionsKey = Key<MutableMap<String, VimDataType>>("localOptions")
|
||||||
@@ -253,14 +253,6 @@ abstract class VimOptionServiceBase : OptionService {
|
|||||||
setOptionValue(scope, optionName, VimInt.ONE, token)
|
setOptionValue(scope, optionName, VimInt.ONE, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setOption(scope: OptionService.Scope, optionName: String, token: String) {
|
|
||||||
val newScope = when (scope) {
|
|
||||||
is OptionService.Scope.GLOBAL -> OptionScope.GLOBAL
|
|
||||||
is OptionService.Scope.LOCAL -> OptionScope.LOCAL(scope.editor)
|
|
||||||
}
|
|
||||||
this.setOption(newScope, optionName, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets the option (false)
|
* Unsets the option (false)
|
||||||
*/
|
*/
|
||||||
|
@@ -19,10 +19,10 @@
|
|||||||
package com.maddyhome.idea.vim.command
|
package com.maddyhome.idea.vim.command
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.VimActionsInitiator
|
import com.maddyhome.idea.vim.api.VimActionsInitiator
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.common.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.common.CurrentCommandState
|
import com.maddyhome.idea.vim.common.CurrentCommandState
|
||||||
import com.maddyhome.idea.vim.key.Node
|
import com.maddyhome.idea.vim.common.Node
|
||||||
import com.maddyhome.idea.vim.key.RootNode
|
import com.maddyhome.idea.vim.common.RootNode
|
||||||
import com.maddyhome.idea.vim.diagnostic.debug
|
import com.maddyhome.idea.vim.diagnostic.debug
|
||||||
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
||||||
|
@@ -25,58 +25,54 @@ import java.util.*
|
|||||||
* COMPATIBILITY-LAYER: Do not move this class to a different package
|
* COMPATIBILITY-LAYER: Do not move this class to a different package
|
||||||
*/
|
*/
|
||||||
enum class MappingMode {
|
enum class MappingMode {
|
||||||
/**
|
/**
|
||||||
* Indicates this key mapping applies to Normal mode
|
* Indicates this key mapping applies to Normal mode
|
||||||
*/
|
*/
|
||||||
NORMAL,
|
NORMAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates this key mapping applies to Visual mode
|
* Indicates this key mapping applies to Visual mode
|
||||||
*/
|
*/
|
||||||
VISUAL,
|
VISUAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates this key mapping applies to Select mode
|
* Indicates this key mapping applies to Select mode
|
||||||
*/
|
*/
|
||||||
SELECT,
|
SELECT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates this key mapping applies to Operator Pending mode
|
* Indicates this key mapping applies to Operator Pending mode
|
||||||
*/
|
*/
|
||||||
OP_PENDING,
|
OP_PENDING,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates this key mapping applies to Insert mode
|
* Indicates this key mapping applies to Insert mode
|
||||||
*/
|
*/
|
||||||
INSERT,
|
INSERT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates this key mapping applies to Command Line mode
|
* Indicates this key mapping applies to Command Line mode
|
||||||
*/
|
*/
|
||||||
CMD_LINE;
|
CMD_LINE;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val N: EnumSet<MappingMode> = EnumSet.of(NORMAL)
|
val N: EnumSet<MappingMode> = EnumSet.of(NORMAL)
|
||||||
val X: EnumSet<MappingMode> = EnumSet.of(VISUAL)
|
val X: EnumSet<MappingMode> = EnumSet.of(VISUAL)
|
||||||
val O: EnumSet<MappingMode> = EnumSet.of(OP_PENDING)
|
val O: EnumSet<MappingMode> = EnumSet.of(OP_PENDING)
|
||||||
val I: EnumSet<MappingMode> = EnumSet.of(INSERT)
|
val I: EnumSet<MappingMode> = EnumSet.of(INSERT)
|
||||||
val C: EnumSet<MappingMode> = EnumSet.of(CMD_LINE)
|
val C: EnumSet<MappingMode> = EnumSet.of(CMD_LINE)
|
||||||
val S: EnumSet<MappingMode> = EnumSet.of(SELECT)
|
val S: EnumSet<MappingMode> = EnumSet.of(SELECT)
|
||||||
val V: EnumSet<MappingMode> = EnumSet.of(VISUAL, SELECT)
|
val V: EnumSet<MappingMode> = EnumSet.of(VISUAL, SELECT)
|
||||||
val NO: EnumSet<MappingMode> = EnumSet.of(NORMAL, OP_PENDING)
|
val NO: EnumSet<MappingMode> = EnumSet.of(NORMAL, OP_PENDING)
|
||||||
|
@JvmField
|
||||||
@JvmField
|
val XO: EnumSet<MappingMode> = EnumSet.of(VISUAL, OP_PENDING)
|
||||||
val XO: EnumSet<MappingMode> = EnumSet.of(VISUAL, OP_PENDING)
|
val NX: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL)
|
||||||
val NX: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL)
|
val IC: EnumSet<MappingMode> = EnumSet.of(INSERT, CMD_LINE)
|
||||||
val IC: EnumSet<MappingMode> = EnumSet.of(INSERT, CMD_LINE)
|
val NV: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL, SELECT)
|
||||||
val NV: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL, SELECT)
|
val NXO: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL, OP_PENDING)
|
||||||
|
@JvmField
|
||||||
@JvmField
|
val NVO: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL, OP_PENDING, SELECT)
|
||||||
val NXO: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL, OP_PENDING)
|
val ALL: EnumSet<MappingMode> = EnumSet.allOf(MappingMode::class.java)
|
||||||
|
}
|
||||||
@JvmField
|
}
|
||||||
val NVO: EnumSet<MappingMode> = EnumSet.of(NORMAL, VISUAL, OP_PENDING, SELECT)
|
|
||||||
val ALL: EnumSet<MappingMode> = EnumSet.allOf(MappingMode::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -20,7 +20,7 @@ package com.maddyhome.idea.vim.command
|
|||||||
import com.maddyhome.idea.vim.api.VimActionsInitiator
|
import com.maddyhome.idea.vim.api.VimActionsInitiator
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.common.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.common.DigraphResult
|
import com.maddyhome.idea.vim.common.DigraphResult
|
||||||
import com.maddyhome.idea.vim.common.DigraphSequence
|
import com.maddyhome.idea.vim.common.DigraphSequence
|
||||||
import com.maddyhome.idea.vim.diagnostic.debug
|
import com.maddyhome.idea.vim.diagnostic.debug
|
||||||
|
@@ -16,14 +16,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.key
|
package com.maddyhome.idea.vim.common
|
||||||
|
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: Moved from common package to this one
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All the commands are stored into the tree where the key is either a complete command (for `x`, `j`, `l`, etc.),
|
* All the commands are stored into the tree where the key is either a complete command (for `x`, `j`, `l`, etc.),
|
||||||
* or a part of a command (e.g. `g` for `gg`).
|
* or a part of a command (e.g. `g` for `gg`).
|
@@ -95,7 +95,7 @@ abstract class VimMachineBase : VimMachine {
|
|||||||
val operatedText = editor.deleteDryRun(range) ?: return null
|
val operatedText = editor.deleteDryRun(range) ?: return null
|
||||||
|
|
||||||
val normalizedRange = operatedText.toNormalizedTextRange(editor)
|
val normalizedRange = operatedText.toNormalizedTextRange(editor)
|
||||||
caret.registerStorage.storeText(editor, normalizedRange, operatedText.toType(), true)
|
injector.registerGroup.storeText(editor, normalizedRange, operatedText.toType(), true)
|
||||||
(editor as MutableVimEditor).delete(range)
|
(editor as MutableVimEditor).delete(range)
|
||||||
|
|
||||||
val start = normalizedRange.startOffset
|
val start = normalizedRange.startOffset
|
||||||
|
@@ -66,7 +66,7 @@ sealed class ChangeEditorActionHandler : EditorActionHandlerBase(false) {
|
|||||||
): Boolean
|
): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun baseExecute(
|
override fun baseExecute(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
caret: VimCaret,
|
caret: VimCaret,
|
||||||
context: ExecutionContext,
|
context: ExecutionContext,
|
||||||
|
@@ -1,42 +0,0 @@
|
|||||||
package com.maddyhome.idea.vim.option
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
|
||||||
import com.maddyhome.idea.vim.options.Option
|
|
||||||
import com.maddyhome.idea.vim.options.OptionScope
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.parseNumber
|
|
||||||
|
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: Moved out of class and to a different package
|
|
||||||
*/
|
|
||||||
open class NumberOption(name: String, abbrev: String, defaultValue: VimInt) :
|
|
||||||
Option<VimInt>(name, abbrev, defaultValue) {
|
|
||||||
constructor(name: String, abbrev: String, defaultValue: Int) : this(name, abbrev, VimInt(defaultValue))
|
|
||||||
|
|
||||||
override fun checkIfValueValid(value: VimDataType, token: String) {
|
|
||||||
if (value !is VimInt) {
|
|
||||||
throw ExException("E521: Number required after =: $token")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getValueIfAppend(currentValue: VimDataType, value: String, token: String): VimInt {
|
|
||||||
val valueToAdd = parseNumber(token) ?: throw ExException("E521: Number required after =: $token")
|
|
||||||
return VimInt((currentValue as VimInt).value + valueToAdd)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getValueIfPrepend(currentValue: VimDataType, value: String, token: String): VimInt {
|
|
||||||
val valueToAdd = parseNumber(token) ?: throw ExException("E521: Number required after =: $token")
|
|
||||||
return VimInt((currentValue as VimInt).value * valueToAdd)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getValueIfRemove(currentValue: VimDataType, value: String, token: String): VimInt {
|
|
||||||
val valueToAdd = parseNumber(token) ?: throw ExException("E521: Number required after =: $token")
|
|
||||||
return VimInt((currentValue as VimInt).value - valueToAdd)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun value(): Int {
|
|
||||||
return injector.optionService.getOptionValue(OptionScope.GLOBAL, name).asDouble().toInt()
|
|
||||||
}
|
|
||||||
}
|
|
@@ -37,15 +37,4 @@ class ToggleOption(name: String, abbrev: String, defaultValue: VimInt) : Option<
|
|||||||
fun isSet(): Boolean {
|
fun isSet(): Boolean {
|
||||||
return injector.optionService.getOptionValue(OptionScope.GLOBAL, name).asBoolean()
|
return injector.optionService.getOptionValue(OptionScope.GLOBAL, name).asBoolean()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: Method added
|
|
||||||
*/
|
|
||||||
@Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
|
||||||
override val value: java.lang.Boolean
|
|
||||||
get() = if (injector.optionService.getOptionValue(OptionScope.GLOBAL, name).asBoolean()) {
|
|
||||||
java.lang.Boolean(true)
|
|
||||||
} else {
|
|
||||||
java.lang.Boolean(false)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -20,7 +20,9 @@ package com.maddyhome.idea.vim.options
|
|||||||
|
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
||||||
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
||||||
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.parseNumber
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,13 +59,6 @@ import java.util.*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: Method added
|
|
||||||
*/
|
|
||||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
|
||||||
open val value: java.lang.Boolean
|
|
||||||
get() = TODO()
|
|
||||||
|
|
||||||
// todo 1.9 should return Result with exceptions
|
// todo 1.9 should return Result with exceptions
|
||||||
abstract fun checkIfValueValid(value: VimDataType, token: String)
|
abstract fun checkIfValueValid(value: VimDataType, token: String)
|
||||||
|
|
||||||
@@ -72,6 +67,31 @@ import java.util.*
|
|||||||
abstract fun getValueIfRemove(currentValue: VimDataType, value: String, token: String): T
|
abstract fun getValueIfRemove(currentValue: VimDataType, value: String, token: String): T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class NumberOption(name: String, abbrev: String, defaultValue: VimInt) : Option<VimInt>(name, abbrev, defaultValue) {
|
||||||
|
constructor(name: String, abbrev: String, defaultValue: Int) : this(name, abbrev, VimInt(defaultValue))
|
||||||
|
|
||||||
|
override fun checkIfValueValid(value: VimDataType, token: String) {
|
||||||
|
if (value !is VimInt) {
|
||||||
|
throw ExException("E521: Number required after =: $token")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getValueIfAppend(currentValue: VimDataType, value: String, token: String): VimInt {
|
||||||
|
val valueToAdd = parseNumber(token) ?: throw ExException("E521: Number required after =: $token")
|
||||||
|
return VimInt((currentValue as VimInt).value + valueToAdd)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getValueIfPrepend(currentValue: VimDataType, value: String, token: String): VimInt {
|
||||||
|
val valueToAdd = parseNumber(token) ?: throw ExException("E521: Number required after =: $token")
|
||||||
|
return VimInt((currentValue as VimInt).value * valueToAdd)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getValueIfRemove(currentValue: VimDataType, value: String, token: String): VimInt {
|
||||||
|
val valueToAdd = parseNumber(token) ?: throw ExException("E521: Number required after =: $token")
|
||||||
|
return VimInt((currentValue as VimInt).value - valueToAdd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open class StringOption(name: String, abbrev: String, defaultValue: VimString, private val isList: Boolean = false, private val boundedValues: Collection<String>? = null) : Option<VimString>(name, abbrev, defaultValue) {
|
open class StringOption(name: String, abbrev: String, defaultValue: VimString, private val isList: Boolean = false, private val boundedValues: Collection<String>? = null) : Option<VimString>(name, abbrev, defaultValue) {
|
||||||
constructor(name: String, abbrev: String, defaultValue: String, isList: Boolean = false, boundedValues: Collection<String>? = null) : this(name, abbrev, VimString(defaultValue), isList, boundedValues)
|
constructor(name: String, abbrev: String, defaultValue: String, isList: Boolean = false, boundedValues: Collection<String>? = null) : this(name, abbrev, VimString(defaultValue), isList, boundedValues)
|
||||||
|
|
||||||
|
@@ -16,17 +16,11 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.vimscript.services
|
package com.maddyhome.idea.vim.options
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.options.Option
|
|
||||||
import com.maddyhome.idea.vim.options.OptionChangeListener
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
||||||
|
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: Moved to a different package
|
|
||||||
*/
|
|
||||||
interface OptionService {
|
interface OptionService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +30,7 @@ interface OptionService {
|
|||||||
* @param token used in exception messages
|
* @param token used in exception messages
|
||||||
* @throws ExException("E518: Unknown option: $token")
|
* @throws ExException("E518: Unknown option: $token")
|
||||||
*/
|
*/
|
||||||
fun getOptionValue(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, token: String = optionName): VimDataType
|
fun getOptionValue(scope: OptionScope, optionName: String, token: String = optionName): VimDataType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets option value.
|
* Sets option value.
|
||||||
@@ -46,7 +40,7 @@ interface OptionService {
|
|||||||
* @param token used in exception messages
|
* @param token used in exception messages
|
||||||
* @throws ExException("E518: Unknown option: $token")
|
* @throws ExException("E518: Unknown option: $token")
|
||||||
*/
|
*/
|
||||||
fun setOptionValue(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, value: VimDataType, token: String = optionName)
|
fun setOptionValue(scope: OptionScope, optionName: String, value: VimDataType, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the [value] is contained in string option.
|
* Checks if the [value] is contained in string option.
|
||||||
@@ -56,7 +50,7 @@ interface OptionService {
|
|||||||
* @param optionName option name or alias
|
* @param optionName option name or alias
|
||||||
* @param value option value
|
* @param value option value
|
||||||
*/
|
*/
|
||||||
fun contains(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, value: String): Boolean
|
fun contains(scope: OptionScope, optionName: String, value: String): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits a string option into flags
|
* Splits a string option into flags
|
||||||
@@ -67,7 +61,7 @@ interface OptionService {
|
|||||||
* @param scope global/local option scope
|
* @param scope global/local option scope
|
||||||
* @param optionName option name or alias
|
* @param optionName option name or alias
|
||||||
*/
|
*/
|
||||||
fun getValues(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String): List<String>?
|
fun getValues(scope: OptionScope, optionName: String): List<String>?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as [setOptionValue], but automatically casts [value] to the required [VimDataType]
|
* Same as [setOptionValue], but automatically casts [value] to the required [VimDataType]
|
||||||
@@ -78,7 +72,7 @@ interface OptionService {
|
|||||||
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
||||||
* @throws ExException("E474: Invalid argument: $token") in case the cast to VimDataType is impossible
|
* @throws ExException("E474: Invalid argument: $token") in case the cast to VimDataType is impossible
|
||||||
*/
|
*/
|
||||||
fun setOptionValue(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, value: String, token: String = optionName)
|
fun setOptionValue(scope: OptionScope, optionName: String, value: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as `set {option}+={value}` in Vim documentation.
|
* Same as `set {option}+={value}` in Vim documentation.
|
||||||
@@ -91,7 +85,7 @@ interface OptionService {
|
|||||||
* @throws ExException("E474: Invalid argument: $token") in case the method was called for the [StringOption] and the argument is invalid (does not satisfy the option bounded values)
|
* @throws ExException("E474: Invalid argument: $token") in case the method was called for the [StringOption] and the argument is invalid (does not satisfy the option bounded values)
|
||||||
* @throws ExException("E521: Number required after =: $token") in case the cast to VimInt is impossible
|
* @throws ExException("E521: Number required after =: $token") in case the cast to VimInt is impossible
|
||||||
*/
|
*/
|
||||||
fun appendValue(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, value: String, token: String = optionName)
|
fun appendValue(scope: OptionScope, optionName: String, value: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as `set {option}^={value}` in Vim documentation.
|
* Same as `set {option}^={value}` in Vim documentation.
|
||||||
@@ -104,7 +98,7 @@ interface OptionService {
|
|||||||
* @throws ExException("E474: Invalid argument: $token") in case the method was called for the [StringOption] and the argument is invalid (does not satisfy the option bounded values)
|
* @throws ExException("E474: Invalid argument: $token") in case the method was called for the [StringOption] and the argument is invalid (does not satisfy the option bounded values)
|
||||||
* @throws ExException("E521: Number required after =: $token") in case the cast to VimInt is impossible
|
* @throws ExException("E521: Number required after =: $token") in case the cast to VimInt is impossible
|
||||||
*/
|
*/
|
||||||
fun prependValue(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, value: String, token: String = optionName)
|
fun prependValue(scope: OptionScope, optionName: String, value: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as `set {option}-={value}` in Vim documentation.
|
* Same as `set {option}-={value}` in Vim documentation.
|
||||||
@@ -117,7 +111,7 @@ interface OptionService {
|
|||||||
* @throws ExException("E474: Invalid argument: $token") in case the method was called for the [StringOption] and the argument is invalid (does not satisfy the option bounded values)
|
* @throws ExException("E474: Invalid argument: $token") in case the method was called for the [StringOption] and the argument is invalid (does not satisfy the option bounded values)
|
||||||
* @throws ExException("E521: Number required after =: $token") in case the cast to VimInt is impossible
|
* @throws ExException("E521: Number required after =: $token") in case the cast to VimInt is impossible
|
||||||
*/
|
*/
|
||||||
fun removeValue(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, value: String, token: String = optionName)
|
fun removeValue(scope: OptionScope, optionName: String, value: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the toggle option on.
|
* Checks if the toggle option on.
|
||||||
@@ -128,7 +122,7 @@ interface OptionService {
|
|||||||
* @param token used in exception messages
|
* @param token used in exception messages
|
||||||
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
||||||
*/
|
*/
|
||||||
fun isSet(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, token: String = optionName): Boolean
|
fun isSet(scope: OptionScope, optionName: String, token: String = optionName): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the option's value set to default.
|
* Checks if the option's value set to default.
|
||||||
@@ -138,7 +132,7 @@ interface OptionService {
|
|||||||
* @param token used in exception messages
|
* @param token used in exception messages
|
||||||
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
||||||
*/
|
*/
|
||||||
fun isDefault(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, token: String = optionName): Boolean
|
fun isDefault(scope: OptionScope, optionName: String, token: String = optionName): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets option's value to default.
|
* Resets option's value to default.
|
||||||
@@ -148,7 +142,7 @@ interface OptionService {
|
|||||||
* @param token used in exception messages
|
* @param token used in exception messages
|
||||||
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
||||||
*/
|
*/
|
||||||
fun resetDefault(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, token: String = optionName)
|
fun resetDefault(scope: OptionScope, optionName: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets all options back to default values.
|
* Resets all options back to default values.
|
||||||
@@ -169,12 +163,7 @@ interface OptionService {
|
|||||||
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
||||||
* @throws ExException("E474: Invalid argument: $token") in case the option is not a [ToggleOption]
|
* @throws ExException("E474: Invalid argument: $token") in case the option is not a [ToggleOption]
|
||||||
*/
|
*/
|
||||||
fun setOption(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, token: String = optionName)
|
fun setOption(scope: OptionScope, optionName: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: New method added
|
|
||||||
*/
|
|
||||||
fun setOption(scope: Scope, optionName: String, token: String = optionName)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets the option (false).
|
* Unsets the option (false).
|
||||||
@@ -184,7 +173,7 @@ interface OptionService {
|
|||||||
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
||||||
* @throws ExException("E474: Invalid argument: $token") in case the option is not a [ToggleOption]
|
* @throws ExException("E474: Invalid argument: $token") in case the option is not a [ToggleOption]
|
||||||
*/
|
*/
|
||||||
fun unsetOption(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, token: String = optionName)
|
fun unsetOption(scope: OptionScope, optionName: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inverts boolean option value true -> false / false -> true.
|
* Inverts boolean option value true -> false / false -> true.
|
||||||
@@ -194,7 +183,7 @@ interface OptionService {
|
|||||||
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
* @throws ExException("E518: Unknown option: $token") in case the option is not found
|
||||||
* @throws ExException("E474: Invalid argument: $token") in case the option is not a [ToggleOption]
|
* @throws ExException("E474: Invalid argument: $token") in case the option is not a [ToggleOption]
|
||||||
*/
|
*/
|
||||||
fun toggleOption(scope: com.maddyhome.idea.vim.options.OptionScope, optionName: String, token: String = optionName)
|
fun toggleOption(scope: OptionScope, optionName: String, token: String = optionName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list of all option names
|
* @return list of all option names
|
||||||
@@ -232,12 +221,4 @@ interface OptionService {
|
|||||||
* @param listener option listener
|
* @param listener option listener
|
||||||
*/
|
*/
|
||||||
fun removeListener(optionName: String, listener: OptionChangeListener<VimDataType>)
|
fun removeListener(optionName: String, listener: OptionChangeListener<VimDataType>)
|
||||||
|
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: Added this class
|
|
||||||
*/
|
|
||||||
sealed class Scope {
|
|
||||||
object GLOBAL : Scope()
|
|
||||||
class LOCAL(val editor: VimEditor) : Scope()
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -23,5 +23,5 @@ interface VimPut {
|
|||||||
updateVisualMarks: Boolean = false,
|
updateVisualMarks: Boolean = false,
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData, updateVisualMarks: Boolean = false): Boolean
|
fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData): Boolean
|
||||||
}
|
}
|
@@ -20,7 +20,6 @@ package com.maddyhome.idea.vim.register
|
|||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import org.jetbrains.annotations.TestOnly
|
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
interface VimRegisterGroup {
|
interface VimRegisterGroup {
|
||||||
@@ -31,7 +30,6 @@ interface VimRegisterGroup {
|
|||||||
* @return The register, null if no such register
|
* @return The register, null if no such register
|
||||||
*/
|
*/
|
||||||
val lastRegister: Register?
|
val lastRegister: Register?
|
||||||
val lastRegisterChar: Char
|
|
||||||
val currentRegister: Char
|
val currentRegister: Char
|
||||||
val defaultRegister: Char
|
val defaultRegister: Char
|
||||||
|
|
||||||
@@ -55,13 +53,6 @@ interface VimRegisterGroup {
|
|||||||
*/
|
*/
|
||||||
fun storeText(register: Char, text: String): Boolean
|
fun storeText(register: Char, text: String): Boolean
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores text to any writable register (used for multicaret tests)
|
|
||||||
*/
|
|
||||||
@TestOnly
|
|
||||||
// todo better tests
|
|
||||||
fun storeText(register: Char, text: String, selectionType: SelectionType): Boolean
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores text, character wise, in the given special register
|
* Stores text, character wise, in the given special register
|
||||||
*
|
*
|
||||||
|
@@ -36,7 +36,8 @@ abstract class VimRegisterGroupBase : VimRegisterGroup {
|
|||||||
@JvmField
|
@JvmField
|
||||||
protected var defaultRegisterChar = UNNAMED_REGISTER
|
protected var defaultRegisterChar = UNNAMED_REGISTER
|
||||||
|
|
||||||
override var lastRegisterChar = defaultRegisterChar
|
@JvmField
|
||||||
|
protected var lastRegisterChar = defaultRegisterChar
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the last register name selected by the user
|
* Gets the last register name selected by the user
|
||||||
@@ -292,7 +293,7 @@ abstract class VimRegisterGroupBase : VimRegisterGroup {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun storeText(register: Char, text: String, selectionType: SelectionType): Boolean {
|
override fun storeText(register: Char, text: String): Boolean {
|
||||||
if (!WRITABLE_REGISTERS.contains(register)) {
|
if (!WRITABLE_REGISTERS.contains(register)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -302,7 +303,7 @@ abstract class VimRegisterGroupBase : VimRegisterGroup {
|
|||||||
} else {
|
} else {
|
||||||
text
|
text
|
||||||
}
|
}
|
||||||
val reg = Register(register, selectionType, textToStore, ArrayList())
|
val reg = Register(register, SelectionType.CHARACTER_WISE, textToStore, ArrayList())
|
||||||
saveRegister(register, reg)
|
saveRegister(register, reg)
|
||||||
if (register == '/') {
|
if (register == '/') {
|
||||||
injector.searchGroup.lastSearchPattern = text // todo we should not have this field if we have the "/" register
|
injector.searchGroup.lastSearchPattern = text // todo we should not have this field if we have the "/" register
|
||||||
@@ -310,10 +311,6 @@ abstract class VimRegisterGroupBase : VimRegisterGroup {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun storeText(register: Char, text: String): Boolean {
|
|
||||||
return storeText(register, text, SelectionType.CHARACTER_WISE)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun guessSelectionType(text: String): SelectionType {
|
private fun guessSelectionType(text: String): SelectionType {
|
||||||
return if (text.endsWith("\n")) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
|
return if (text.endsWith("\n")) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
|
||||||
}
|
}
|
||||||
|
@@ -26,11 +26,7 @@ import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
|||||||
import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
|
import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
|
|
||||||
|
interface VimVariableService {
|
||||||
/**
|
|
||||||
* COMPATIBILITY-LAYER: Renamed from VimVariableService
|
|
||||||
*/
|
|
||||||
interface VariableService {
|
|
||||||
/**
|
/**
|
||||||
* Stores variable.
|
* Stores variable.
|
||||||
*
|
*
|
@@ -13,7 +13,7 @@ import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
|
|||||||
import com.maddyhome.idea.vim.vimscript.model.statements.FunctionDeclaration
|
import com.maddyhome.idea.vim.vimscript.model.statements.FunctionDeclaration
|
||||||
import com.maddyhome.idea.vim.vimscript.model.statements.FunctionFlag
|
import com.maddyhome.idea.vim.vimscript.model.statements.FunctionFlag
|
||||||
|
|
||||||
abstract class VimVariableServiceBase : VariableService {
|
abstract class VimVariableServiceBase : VimVariableService {
|
||||||
private var globalVariables: MutableMap<String, VimDataType> = mutableMapOf()
|
private var globalVariables: MutableMap<String, VimDataType> = mutableMapOf()
|
||||||
private val windowVariablesKey = Key<MutableMap<String, VimDataType>>("TabVariables")
|
private val windowVariablesKey = Key<MutableMap<String, VimDataType>>("TabVariables")
|
||||||
private val bufferVariablesKey = Key<MutableMap<String, VimDataType>>("BufferVariables")
|
private val bufferVariablesKey = Key<MutableMap<String, VimDataType>>("BufferVariables")
|
||||||
|
Reference in New Issue
Block a user