diff --git a/src/main/java/com/maddyhome/idea/vim/PluginStartup.kt b/src/main/java/com/maddyhome/idea/vim/PluginStartup.kt index a0994cdfde..cabfba67b7 100644 --- a/src/main/java/com/maddyhome/idea/vim/PluginStartup.kt +++ b/src/main/java/com/maddyhome/idea/vim/PluginStartup.kt @@ -12,11 +12,10 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx import com.intellij.openapi.project.Project import com.intellij.openapi.project.ProjectManagerListener import com.intellij.openapi.startup.StartupActivity -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.helper.EditorHelper import com.maddyhome.idea.vim.helper.localEditors +import com.maddyhome.idea.vim.newapi.globalIjOptions /** * @author Alex Plate @@ -42,7 +41,7 @@ internal class PluginStartup : StartupActivity.DumbAware/*, LightEditCompatible* // This is a temporal workaround for VIM-2487 internal class PyNotebooksCloseWorkaround : ProjectManagerListener { override fun projectClosingBeforeSave(project: Project) { - if (injector.globalOptions().isSet(IjOptions.closenotebooks)) { + if (injector.globalIjOptions().closenotebooks) { localEditors().forEach { editor -> val virtualFile = EditorHelper.getVirtualFile(editor) if (virtualFile?.extension == "ipynb") { diff --git a/src/main/java/com/maddyhome/idea/vim/VimTypedActionHandler.kt b/src/main/java/com/maddyhome/idea/vim/VimTypedActionHandler.kt index 152b725402..2206fa3df0 100644 --- a/src/main/java/com/maddyhome/idea/vim/VimTypedActionHandler.kt +++ b/src/main/java/com/maddyhome/idea/vim/VimTypedActionHandler.kt @@ -14,7 +14,6 @@ import com.intellij.openapi.editor.actionSystem.ActionPlan import com.intellij.openapi.editor.actionSystem.TypedActionHandler import com.intellij.openapi.editor.actionSystem.TypedActionHandlerEx import com.intellij.openapi.progress.ProcessCanceledException -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.helper.inInsertMode @@ -32,7 +31,7 @@ import javax.swing.KeyStroke */ internal class VimTypedActionHandler(origHandler: TypedActionHandler) : TypedActionHandlerEx { private val handler = KeyHandler.getInstance() - private val traceTime = injector.globalOptions().isSet(Options.ideatracetime) + private val traceTime = injector.globalOptions().ideatracetime init { KeyHandlerKeeper.getInstance().originalHandler = origHandler diff --git a/src/main/java/com/maddyhome/idea/vim/action/VimShortcutKeyAction.kt b/src/main/java/com/maddyhome/idea/vim/action/VimShortcutKeyAction.kt index 8087461580..059cd1e330 100644 --- a/src/main/java/com/maddyhome/idea/vim/action/VimShortcutKeyAction.kt +++ b/src/main/java/com/maddyhome/idea/vim/action/VimShortcutKeyAction.kt @@ -24,10 +24,8 @@ import com.intellij.openapi.util.Key import com.intellij.ui.KeyStrokeAdapter import com.maddyhome.idea.vim.KeyHandler import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.group.IjOptionConstants import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.handler.enableOctopus @@ -44,6 +42,7 @@ import com.maddyhome.idea.vim.key.ShortcutOwner import com.maddyhome.idea.vim.key.ShortcutOwnerInfo import com.maddyhome.idea.vim.listener.AceJumpService import com.maddyhome.idea.vim.listener.AppCodeTemplates.appCodeTemplateCaptured +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.vim import java.awt.event.InputEvent import java.awt.event.KeyEvent @@ -56,7 +55,7 @@ import javax.swing.KeyStroke * These keys are not passed to [com.maddyhome.idea.vim.VimTypedActionHandler] and should be handled by actions. */ internal class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatible*/ { - private val traceTime = injector.globalOptions().isSet(Options.ideatracetime) + private val traceTime = injector.globalOptions().ideatracetime override fun actionPerformed(e: AnActionEvent) { LOG.trace("Executing shortcut key action") @@ -211,7 +210,7 @@ internal class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatib } private fun isEnabledForEscape(editor: Editor): Boolean { - val ideaVimSupportDialog = injector.options(editor.vim).hasValue(IjOptions.ideavimsupport, IjOptionConstants.ideavimsupport_dialog) + val ideaVimSupportDialog = injector.globalIjOptions().ideavimsupport.contains(IjOptionConstants.ideavimsupport_dialog) return editor.isPrimaryEditor() || EditorHelper.isFileEditor(editor) && !editor.inNormalMode || ideaVimSupportDialog && !editor.inNormalMode @@ -264,7 +263,7 @@ internal class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatib fun isEnabledForLookup(keyStroke: KeyStroke): Boolean = keyStroke !in parsedLookupKeys - private fun parseLookupKeys() = injector.globalOptions().getStringListValues(IjOptions.lookupkeys) + private fun parseLookupKeys() = injector.globalIjOptions().lookupkeys .map { injector.parser.parseKeys(it) } .filter { it.isNotEmpty() } .map { it.first() } diff --git a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesAction.kt b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesAction.kt index 2cafa48a54..a4c2b190a3 100644 --- a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesAction.kt +++ b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesAction.kt @@ -11,12 +11,11 @@ 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.injector -import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.command.Argument import com.maddyhome.idea.vim.command.Command import com.maddyhome.idea.vim.command.OperatorArguments -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler +import com.maddyhome.idea.vim.newapi.ijOptions public class DeleteJoinLinesAction : ChangeEditorActionHandler.ConditionalSingleExecution() { override val type: Command.Type = Command.Type.DELETE @@ -26,7 +25,7 @@ public class DeleteJoinLinesAction : ChangeEditorActionHandler.ConditionalSingle cmd: Command, operatorArguments: OperatorArguments, ): Boolean { - return !injector.options(editor).isSet(IjOptions.ideajoin) + return !injector.ijOptions(editor).ideajoin } override fun execute( diff --git a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesSpacesAction.kt b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesSpacesAction.kt index e649d0dba3..e0765dc266 100644 --- a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesSpacesAction.kt +++ b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinLinesSpacesAction.kt @@ -10,12 +10,11 @@ package com.maddyhome.idea.vim.action.change.delete import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.command.Argument import com.maddyhome.idea.vim.command.Command import com.maddyhome.idea.vim.command.OperatorArguments -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler +import com.maddyhome.idea.vim.newapi.ijOptions public class DeleteJoinLinesSpacesAction : ChangeEditorActionHandler.SingleExecution() { override val type: Command.Type = Command.Type.DELETE @@ -27,7 +26,7 @@ public class DeleteJoinLinesSpacesAction : ChangeEditorActionHandler.SingleExecu operatorArguments: OperatorArguments, ): Boolean { if (editor.isOneLineMode()) return false - if (injector.options(editor).isSet(IjOptions.ideajoin)) { + if (injector.ijOptions(editor).ideajoin) { return injector.changeGroup.joinViaIdeaByCount(editor, context, operatorArguments.count1) } injector.editorGroup.notifyIdeaJoin(editor) diff --git a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesAction.kt b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesAction.kt index 9809033c8b..a08db49587 100644 --- a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesAction.kt +++ b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesAction.kt @@ -11,14 +11,13 @@ 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.injector -import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.command.Command import com.maddyhome.idea.vim.command.CommandFlags import com.maddyhome.idea.vim.command.OperatorArguments -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.group.visual.VimSelection import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler import com.maddyhome.idea.vim.helper.enumSetOf +import com.maddyhome.idea.vim.newapi.ijOptions import java.util.* /** @@ -37,7 +36,7 @@ public class DeleteJoinVisualLinesAction : VisualOperatorActionHandler.SingleExe operatorArguments: OperatorArguments, ): Boolean { if (editor.isOneLineMode()) return false - if (injector.options(editor).isSet(IjOptions.ideajoin)) { + if (injector.ijOptions(editor).ideajoin) { injector.changeGroup.joinViaIdeaBySelections(editor, context, caretsAndSelections) return true } diff --git a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesSpacesAction.kt b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesSpacesAction.kt index 226de74858..5f7aa3d88d 100644 --- a/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesSpacesAction.kt +++ b/src/main/java/com/maddyhome/idea/vim/action/change/delete/DeleteJoinVisualLinesSpacesAction.kt @@ -11,14 +11,13 @@ 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.injector -import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.command.Command import com.maddyhome.idea.vim.command.CommandFlags import com.maddyhome.idea.vim.command.OperatorArguments -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.group.visual.VimSelection import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler import com.maddyhome.idea.vim.helper.enumSetOf +import com.maddyhome.idea.vim.newapi.ijOptions import java.util.* /** @@ -37,7 +36,7 @@ public class DeleteJoinVisualLinesSpacesAction : VisualOperatorActionHandler.Sin operatorArguments: OperatorArguments, ): Boolean { if (editor.isOneLineMode()) return false - if (injector.options(editor).isSet(IjOptions.ideajoin)) { + if (injector.ijOptions(editor).ideajoin) { injector.changeGroup.joinViaIdeaBySelections(editor, context, caretsAndSelections) return true } diff --git a/src/main/java/com/maddyhome/idea/vim/extension/VimExtensionRegistrar.kt b/src/main/java/com/maddyhome/idea/vim/extension/VimExtensionRegistrar.kt index 2cba87d2dc..d85715a7e7 100644 --- a/src/main/java/com/maddyhome/idea/vim/extension/VimExtensionRegistrar.kt +++ b/src/main/java/com/maddyhome/idea/vim/extension/VimExtensionRegistrar.kt @@ -12,7 +12,6 @@ import com.intellij.openapi.extensions.ExtensionPointListener import com.intellij.openapi.extensions.PluginDescriptor import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.api.VimExtensionRegistrator -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.setToggleOption import com.maddyhome.idea.vim.key.MappingOwner.Plugin.Companion.remove @@ -65,7 +64,7 @@ internal object VimExtensionRegistrar : VimExtensionRegistrator { option, object : OptionChangeListener { override fun processGlobalValueChange(oldValue: VimInt?) { - if (injector.globalOptions().isSet(option)) { + if (injector.optionGroup.getOptionValue(option, OptionScope.GLOBAL).asBoolean()) { initExtension(extensionBean, name) PluginState.enabledExtensions.add(name) } else { diff --git a/src/main/java/com/maddyhome/idea/vim/extension/multiplecursors/VimMultipleCursorsExtension.kt b/src/main/java/com/maddyhome/idea/vim/extension/multiplecursors/VimMultipleCursorsExtension.kt index 75217c5df7..74c61f1ce0 100644 --- a/src/main/java/com/maddyhome/idea/vim/extension/multiplecursors/VimMultipleCursorsExtension.kt +++ b/src/main/java/com/maddyhome/idea/vim/extension/multiplecursors/VimMultipleCursorsExtension.kt @@ -17,7 +17,6 @@ import com.intellij.openapi.util.NlsSafe import com.maddyhome.idea.vim.KeyHandler import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.getText import com.maddyhome.idea.vim.api.injector @@ -319,7 +318,7 @@ internal class VimMultipleCursorsExtension : VimExtension { private fun findNextOccurrence(editor: Editor, startOffset: Int, text: String, whole: Boolean): Int { val searchOptions = enumSetOf(SearchOptions.WHOLE_FILE) - if (injector.options(editor.vim).isSet(Options.wrapscan)) { + if (injector.options(editor.vim).wrapscan) { searchOptions.add(SearchOptions.WRAP) } diff --git a/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.java b/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.java index 54087162ee..5d70ff5abd 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.java +++ b/src/main/java/com/maddyhome/idea/vim/group/ChangeGroup.java @@ -155,7 +155,7 @@ public void type(@NotNull VimEditor vimEditor, @NotNull ExecutionContext context */ @Override public boolean changeCaseToggleCharacter(@NotNull VimEditor editor, @NotNull VimCaret caret, int count) { - boolean allowWrap = options(injector, editor).hasValue(Options.whichwrap, "~"); + boolean allowWrap = options(injector, editor).getWhichwrap().contains("~"); Motion motion = injector.getMotion().getHorizontalMotion(editor, caret, count, true, allowWrap); if (motion instanceof Motion.Error) return false; @@ -571,7 +571,7 @@ public boolean changeNumberVisualMode(final @NotNull VimEditor editor, } } - List nf = options(injector, editor).getStringListValues(Options.nrformats); + List nf = options(injector, editor).getNrformats(); boolean alpha = nf.contains("alpha"); boolean hex = nf.contains("hex"); boolean octal = nf.contains("octal"); @@ -601,7 +601,7 @@ public boolean changeNumberVisualMode(final @NotNull VimEditor editor, @Override public boolean changeNumber(final @NotNull VimEditor editor, @NotNull VimCaret caret, final int count) { - final List nf = options(injector, editor).getStringListValues(Options.nrformats); + final List nf = options(injector, editor).getNrformats(); final boolean alpha = nf.contains("alpha"); final boolean hex = nf.contains("hex"); final boolean octal = nf.contains("octal"); diff --git a/src/main/java/com/maddyhome/idea/vim/group/EditorGroup.java b/src/main/java/com/maddyhome/idea/vim/group/EditorGroup.java index 064e5cf357..0a177d7c07 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/EditorGroup.java +++ b/src/main/java/com/maddyhome/idea/vim/group/EditorGroup.java @@ -23,14 +23,10 @@ import com.intellij.openapi.project.Project; import com.maddyhome.idea.vim.KeyHandler; import com.maddyhome.idea.vim.VimPlugin; -import com.maddyhome.idea.vim.api.ExecutionContext; -import com.maddyhome.idea.vim.api.Options; -import com.maddyhome.idea.vim.api.VimEditor; -import com.maddyhome.idea.vim.api.VimEditorGroup; +import com.maddyhome.idea.vim.api.*; import com.maddyhome.idea.vim.helper.*; import com.maddyhome.idea.vim.newapi.IjVimEditor; import com.maddyhome.idea.vim.options.LocalOptionChangeListener; -import com.maddyhome.idea.vim.options.OptionValueAccessor; import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt; import org.jdom.Element; import org.jetbrains.annotations.Contract; @@ -41,8 +37,10 @@ import java.util.Collection; import java.util.stream.Collectors; -import static com.maddyhome.idea.vim.api.VimInjectorKt.*; +import static com.maddyhome.idea.vim.api.VimInjectorKt.injector; +import static com.maddyhome.idea.vim.api.VimInjectorKt.options; import static com.maddyhome.idea.vim.helper.CaretVisualAttributesHelperKt.updateCaretsVisualAttributes; +import static com.maddyhome.idea.vim.newapi.IjVimInjectorKt.ijOptions; /** * @author vlan @@ -57,7 +55,7 @@ public class EditorGroup implements PersistentStateComponent, VimEditor @Override public void caretPositionChanged(@NotNull CaretEvent e) { final boolean requiresRepaint = e.getNewPosition().line != e.getOldPosition().line; - if (requiresRepaint && options(injector, new IjVimEditor(e.getEditor())).isSet(Options.relativenumber)) { + if (requiresRepaint && options(injector, new IjVimEditor(e.getEditor())).getRelativenumber()) { repaintRelativeLineNumbers(e.getEditor()); } } @@ -105,9 +103,9 @@ private static boolean isProjectDisposed(final @NotNull Editor editor) { } private static void updateLineNumbers(final @NotNull Editor editor) { - final OptionValueAccessor options = options(injector, new IjVimEditor(editor)); - final boolean relativeNumber = options.isSet(Options.relativenumber); - final boolean number = options.isSet(Options.number); + final EffectiveOptions options = options(injector, new IjVimEditor(editor)); + final boolean relativeNumber = options.getRelativenumber(); + final boolean number = options.getNumber(); final boolean showBuiltinEditorLineNumbers = shouldShowBuiltinLineNumbers(editor, number, relativeNumber); @@ -231,8 +229,8 @@ public void editorDeinit(@NotNull Editor editor, boolean isReleased) { CaretVisualAttributesHelperKt.removeCaretsVisualAttributes(editor); } - public void notifyIdeaJoin(@Nullable Project project) { - if (VimPlugin.getVimState().isIdeaJoinNotified() || globalOptions(injector).isSet(IjOptions.INSTANCE.getIdeajoin())) { + public void notifyIdeaJoin(@Nullable Project project, @NotNull VimEditor editor) { + if (VimPlugin.getVimState().isIdeaJoinNotified() || ijOptions(injector, editor).getIdeajoin()) { return; } @@ -255,7 +253,7 @@ public void loadState(@NotNull Element state) { @Override public void notifyIdeaJoin(@NotNull VimEditor editor) { - notifyIdeaJoin(((IjVimEditor) editor).getEditor().getProject()); + notifyIdeaJoin(((IjVimEditor) editor).getEditor().getProject(), editor); } public static class NumberChangeListener implements LocalOptionChangeListener { @@ -287,7 +285,7 @@ public void processLocalValueChange(@Nullable VimInt oldValue, @NotNull VimEdito private static class RelativeLineNumberConverter implements LineNumberConverter { @Override public Integer convert(@NotNull Editor editor, int lineNumber) { - final boolean number = options(injector, new IjVimEditor(editor)).isSet(Options.number); + final boolean number = options(injector, new IjVimEditor(editor)).getNumber(); final int caretLine = editor.getCaretModel().getLogicalPosition().line; // lineNumber is 1 based diff --git a/src/main/java/com/maddyhome/idea/vim/group/FileGroup.java b/src/main/java/com/maddyhome/idea/vim/group/FileGroup.java index 919ee2cc03..c2fb52a19a 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/FileGroup.java +++ b/src/main/java/com/maddyhome/idea/vim/group/FileGroup.java @@ -45,8 +45,8 @@ import java.io.File; import java.util.Collection; -import static com.maddyhome.idea.vim.api.VimInjectorKt.globalOptions; import static com.maddyhome.idea.vim.api.VimInjectorKt.injector; +import static com.maddyhome.idea.vim.newapi.IjVimInjectorKt.globalIjOptions; public class FileGroup extends VimFileBase { public boolean openFile(@NotNull String filename, @NotNull ExecutionContext context) { @@ -185,7 +185,7 @@ public void closeFile(int number, @NotNull ExecutionContext context) { @Override public void saveFile(@NotNull ExecutionContext context) { NativeAction action; - if (globalOptions(injector).hasValue(IjOptions.ideawrite, IjOptionConstants.ideawrite_all)) { + if (globalIjOptions(injector).getIdeawrite().contains(IjOptionConstants.ideawrite_all)) { action = injector.getNativeActionManager().getSaveAll(); } else { diff --git a/src/main/java/com/maddyhome/idea/vim/group/IjOptionProperties.kt b/src/main/java/com/maddyhome/idea/vim/group/IjOptionProperties.kt new file mode 100644 index 0000000000..7632391a2e --- /dev/null +++ b/src/main/java/com/maddyhome/idea/vim/group/IjOptionProperties.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2003-2023 The IdeaVim authors + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE.txt file or at + * https://opensource.org/licenses/MIT. + */ + +package com.maddyhome.idea.vim.group + +import com.maddyhome.idea.vim.api.GlobalOptions +import com.maddyhome.idea.vim.api.StringListOptionValue +import com.maddyhome.idea.vim.options.OptionScope + +/** + * An accessor class for IntelliJ implementation specific global options + * + * This class will only access IntelliJ specific global options. It does not provide access to Vim standard global + * options + */ +@Suppress("SpellCheckingInspection") +public open class GlobalIjOptions(scope: OptionScope = OptionScope.GLOBAL) : GlobalOptions(scope) { + public var closenotebooks: Boolean by optionProperty(IjOptions.closenotebooks) + public var ide: String by optionProperty(IjOptions.ide) + public var ideamarks: Boolean by optionProperty(IjOptions.ideamarks) + public var ideastatusicon: String by optionProperty(IjOptions.ideastatusicon) + public val ideavimsupport: StringListOptionValue by optionProperty(IjOptions.ideavimsupport) + public var ideawrite: String by optionProperty(IjOptions.ideawrite) + public val lookupkeys: StringListOptionValue by optionProperty(IjOptions.lookupkeys) + public var trackactionids: Boolean by optionProperty(IjOptions.trackactionids) + public var visualdelay: Int by optionProperty(IjOptions.visualdelay) + + // TODO: Handle these options as global-local + // Decide if they should live in global or effective options when we support global-local + // (I suspect they should live in effective, because we'll always want to read the local value. We are unlikely to + // ever set from code, but we'd expect normal `:set` behaviour, which appears to be to write to the global value). + // Also double check that these options should be global-local + public var ideajoin: Boolean by optionProperty(IjOptions.ideajoin) + public var idearefactormode: String by optionProperty(IjOptions.idearefactormode) + + // Temporary options to control work-in-progress behaviour + public var octopushandler: Boolean by optionProperty(IjOptions.octopushandler) + public var oldundo: Boolean by optionProperty(IjOptions.oldundo) + public var unifyjumps: Boolean by optionProperty(IjOptions.unifyjumps) +} + +/** + * An accessor class for IntelliJ implementation specific option values effective for the given local scope + * + * As a convenience, this class will also provide access to the global options that are effective for the local scope. + */ +public class EffectiveIjOptions(scope: OptionScope.LOCAL): GlobalIjOptions(scope) { + public var ideacopypreprocess: Boolean by optionProperty(IjOptions.ideacopypreprocess) +} diff --git a/src/main/java/com/maddyhome/idea/vim/group/IjOptions.kt b/src/main/java/com/maddyhome/idea/vim/group/IjOptions.kt index 7bc6ada69d..62444274a5 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/IjOptions.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/IjOptions.kt @@ -11,6 +11,7 @@ package com.maddyhome.idea.vim.group import com.intellij.openapi.application.ApplicationNamesInfo import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.options.Option +import com.maddyhome.idea.vim.options.StringListOption import com.maddyhome.idea.vim.options.StringOption import com.maddyhome.idea.vim.options.ToggleOption import com.maddyhome.idea.vim.options.UnsignedNumberOption @@ -42,7 +43,6 @@ public object IjOptions { "idearefactormode", "idearefactormode", "select", - isList = false, IjOptionConstants.ideaRefactorModeValues ) ) @@ -51,28 +51,24 @@ public object IjOptions { "ideastatusicon", "ideastatusicon", "enabled", - isList = false, IjOptionConstants.ideaStatusIconValues ) ) - public val ideavimsupport: StringOption = addOption( - StringOption( + public val ideavimsupport: StringListOption = addOption( + StringListOption( "ideavimsupport", "ideavimsupport", "dialog", - isList = true, IjOptionConstants.ideavimsupportValues ) ) @JvmField public val ideawrite: StringOption = - addOption(StringOption("ideawrite", "ideawrite", "all", isList = false, IjOptionConstants.ideaWriteValues)) - public val lookupkeys: StringOption = addOption( - StringOption( + addOption(StringOption("ideawrite", "ideawrite", "all", IjOptionConstants.ideaWriteValues)) + public val lookupkeys: StringListOption = addOption( + StringListOption( "lookupkeys", "lookupkeys", - ",,,,,,,,,,,", - isList = true - ) + ",,,,,,,,,,,") ) public val octopushandler: ToggleOption = addOption(ToggleOption("octopushandler", "octopushandler", false)) public val oldundo: ToggleOption = addOption(ToggleOption("oldundo", "oldundo", true)) diff --git a/src/main/java/com/maddyhome/idea/vim/group/MotionGroup.kt b/src/main/java/com/maddyhome/idea/vim/group/MotionGroup.kt index 129e176065..0ef47671e7 100755 --- a/src/main/java/com/maddyhome/idea/vim/group/MotionGroup.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/MotionGroup.kt @@ -27,7 +27,6 @@ import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.api.BufferPosition import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimCaret import com.maddyhome.idea.vim.api.VimChangeGroupBase import com.maddyhome.idea.vim.api.VimEditor @@ -251,7 +250,7 @@ internal class MotionGroup : VimMotionGroupBase() { line: Int, caret: ImmutableVimCaret, ): @Range(from = 0, to = Int.MAX_VALUE.toLong()) Int { - return if (injector.options(editor).isSet(Options.startofline)) { + return if (injector.options(editor).startofline) { moveCaretToLineStartSkipLeading(editor, line) } else { moveCaretToLineWithSameColumn(editor, line, caret) diff --git a/src/main/java/com/maddyhome/idea/vim/group/NotificationService.kt b/src/main/java/com/maddyhome/idea/vim/group/NotificationService.kt index 85658b9061..f18d008791 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/NotificationService.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/NotificationService.kt @@ -29,19 +29,15 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.ui.Messages import com.intellij.openapi.util.SystemInfo import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.Options +import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.api.modifyOptionValue -import com.maddyhome.idea.vim.api.setToggleOption -import com.maddyhome.idea.vim.api.unsetToggleOption import com.maddyhome.idea.vim.helper.MessageHelper import com.maddyhome.idea.vim.key.ShortcutOwner import com.maddyhome.idea.vim.key.ShortcutOwnerInfo +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.options.OptionConstants -import com.maddyhome.idea.vim.options.OptionScope import com.maddyhome.idea.vim.statistic.ActionTracker import com.maddyhome.idea.vim.ui.VimEmulationConfigurable -import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString import com.maddyhome.idea.vim.vimscript.services.VimRcService import java.awt.datatransfer.StringSelection import java.io.File @@ -71,12 +67,12 @@ internal class NotificationService(private val project: Project?) { notification.addAction( AppendToIdeaVimRcAction( notification, - "set clipboard+=ideaput", + "set clipboard^=ideaput", "ideaput", ) { - injector.optionGroup.modifyOptionValue(Options.clipboard, OptionScope.GLOBAL) { - appendValue(it, VimString(OptionConstants.clipboard_ideaput)) - } + // Technically, we're supposed to prepend values to clipboard so that it's not added to the "exclude" item. + // Since we don't handle exclude, it's safe to append. But let's be clean. + injector.globalOptions().clipboard.prependValue(OptionConstants.clipboard_ideaput) }, ) @@ -99,7 +95,7 @@ internal class NotificationService(private val project: Project?) { "set ideajoin", "idejoin" ) { - injector.optionGroup.setToggleOption(IjOptions.ideajoin, OptionScope.GLOBAL) + injector.globalIjOptions().ideajoin = true }, ) @@ -232,7 +228,7 @@ internal class NotificationService(private val project: Project?) { class StopTracking : DumbAwareAction("Stop Tracking") { override fun actionPerformed(e: AnActionEvent) { - injector.optionGroup.unsetToggleOption(IjOptions.trackactionids, OptionScope.GLOBAL) + injector.globalIjOptions().trackactionids = false notification?.expire() } } diff --git a/src/main/java/com/maddyhome/idea/vim/group/OptionGroup.kt b/src/main/java/com/maddyhome/idea/vim/group/OptionGroup.kt index ddc27cd954..4c03ac8bef 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/OptionGroup.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/OptionGroup.kt @@ -8,14 +8,34 @@ package com.maddyhome.idea.vim.group +import com.maddyhome.idea.vim.api.VimEditor +import com.maddyhome.idea.vim.api.VimOptionGroup import com.maddyhome.idea.vim.api.VimOptionGroupBase +import com.maddyhome.idea.vim.options.OptionScope + +internal interface IjVimOptionGroup: VimOptionGroup { + /** + * Return an accessor for options that only have a global value + */ + fun getGlobalIjOptions(): GlobalIjOptions + + /** + * Return an accessor for the effective value of local options + */ + fun getEffectiveIjOptions(editor: VimEditor): EffectiveIjOptions +} + +internal class OptionGroup : VimOptionGroupBase(), IjVimOptionGroup { + private val globalOptionsAccessor = GlobalIjOptions() -internal class OptionGroup : VimOptionGroupBase() { override fun initialiseOptions() { // We MUST call super! super.initialiseOptions() IjOptions.initialise() } + + override fun getGlobalIjOptions() = globalOptionsAccessor + override fun getEffectiveIjOptions(editor: VimEditor) = EffectiveIjOptions(OptionScope.LOCAL(editor)) } internal class IjOptionConstants { diff --git a/src/main/java/com/maddyhome/idea/vim/group/ProcessGroup.java b/src/main/java/com/maddyhome/idea/vim/group/ProcessGroup.java index 2403eb7a52..3cd4f845b6 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/ProcessGroup.java +++ b/src/main/java/com/maddyhome/idea/vim/group/ProcessGroup.java @@ -185,10 +185,10 @@ else if (cmd.getRawCount() > 0) { // Finally, we're also not bothering with the crazy space and backslash handling of the 'shell' options content. return ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> { - final String shell = globalOptions(injector).getStringValue(Options.shell); - final String shellcmdflag = globalOptions(injector).getStringValue(Options.shellcmdflag); - final String shellxescape = globalOptions(injector).getStringValue(Options.shellxescape); - final String shellxquote = globalOptions(injector).getStringValue(Options.shellxquote); + final String shell = globalOptions(injector).getShell(); + final String shellcmdflag = globalOptions(injector).getShellcmdflag(); + final String shellxescape = globalOptions(injector).getShellxescape(); + final String shellxquote = globalOptions(injector).getShellxquote(); // For Win32. See :help 'shellxescape' final String escapedCommand = shellxquote.equals("(") diff --git a/src/main/java/com/maddyhome/idea/vim/group/ScrollGroup.kt b/src/main/java/com/maddyhome/idea/vim/group/ScrollGroup.kt index 3fc80da5a3..6c05bb6426 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/ScrollGroup.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/ScrollGroup.kt @@ -9,16 +9,15 @@ package com.maddyhome.idea.vim.group import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.VisualPosition -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimCaret import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimScrollGroup import com.maddyhome.idea.vim.api.getVisualLineCount -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.normalizeLine import com.maddyhome.idea.vim.api.normalizeVisualColumn import com.maddyhome.idea.vim.api.normalizeVisualLine +import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.api.visualLineToBufferLine import com.maddyhome.idea.vim.helper.EditorHelper import com.maddyhome.idea.vim.helper.ScrollViewHelper @@ -30,7 +29,6 @@ import com.maddyhome.idea.vim.helper.vimEditorGroup import com.maddyhome.idea.vim.newapi.ij import com.maddyhome.idea.vim.newapi.vim import com.maddyhome.idea.vim.options.LocalOptionChangeListener -import com.maddyhome.idea.vim.options.OptionScope import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt import kotlin.math.abs import kotlin.math.max @@ -284,7 +282,7 @@ internal class ScrollGroup : VimScrollGroup { private fun getScrollScreenTargetCaretVisualLine(editor: Editor, rawCount: Int, down: Boolean): Int { val visibleArea = EditorHelper.getVisibleArea(editor) val caretVisualLine = editor.caretModel.visualPosition.line - val scrollOption = getScrollOption(rawCount) + val scrollOption = getScrollOption(editor.vim, rawCount) val targetCaretVisualLine = if (scrollOption == 0) { // Scroll up/down half window size by default. We can't use line count here because of block inlays val offset = if (down) visibleArea.height / 2 else editor.lineHeight - visibleArea.height / 2 @@ -295,12 +293,12 @@ internal class ScrollGroup : VimScrollGroup { return editor.vim.normalizeVisualLine(targetCaretVisualLine) } - private fun getScrollOption(rawCount: Int): Int { + private fun getScrollOption(editor: VimEditor, rawCount: Int): Int { if (rawCount == 0) { - return injector.globalOptions().getIntValue(Options.scroll) + return injector.options(editor).scroll } // TODO: This should be reset whenever the window size changes - injector.optionGroup.setOptionValue(Options.scroll, OptionScope.GLOBAL, VimInt(rawCount)) + injector.options(editor).scroll = rawCount return rawCount } } diff --git a/src/main/java/com/maddyhome/idea/vim/group/SearchGroup.java b/src/main/java/com/maddyhome/idea/vim/group/SearchGroup.java index 21bdcd2f93..fe5e46aa55 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/SearchGroup.java +++ b/src/main/java/com/maddyhome/idea/vim/group/SearchGroup.java @@ -43,7 +43,6 @@ import com.maddyhome.idea.vim.ui.ModalEntry; import com.maddyhome.idea.vim.ui.ex.ExEntryPanel; 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.datatypes.VimString; import com.maddyhome.idea.vim.vimscript.model.expressions.Expression; @@ -613,7 +612,7 @@ public boolean processSubstituteCommand(@NotNull VimEditor editor, } else { // :h :&& - "Note that :s and :& don't keep the flags" - do_all = options(injector, editor).isSet(Options.gdefault); + do_all = options(injector, editor).getGdefault(); do_ask = false; do_error = true; do_ic = 0; @@ -1095,7 +1094,7 @@ public void resetIncsearchHighlights() { } private void resetShowSearchHighlight() { - showSearchHighlight = globalOptions(injector).isSet(Options.hlsearch); + showSearchHighlight = globalOptions(injector).getHlsearch(); } private void highlightSearchLines(@NotNull Editor editor, int startLine, int endLine) { @@ -1207,7 +1206,7 @@ public void documentChanged(@NotNull DocumentEvent event) { * @return The offset to the occurrence or -1 if not found */ private int findItOffset(@NotNull Editor editor, int startOffset, int count, Direction dir) { - boolean wrap = globalOptions(injector).isSet(Options.wrapscan); + boolean wrap = globalOptions(injector).getWrapscan(); logger.debug("Perform search. Direction: " + dir + " wrap: " + wrap); int offset = 0; @@ -1369,7 +1368,7 @@ public void readData(@NotNull Element element) { } Element show = search.getChild("show-last"); - final boolean disableHighlight = globalOptions(injector).hasValue(Options.viminfo, "h"); + final boolean disableHighlight = globalOptions(injector).getViminfo().contains("h"); showSearchHighlight = !disableHighlight && Boolean.parseBoolean(show.getText()); if (logger.isDebugEnabled()) { logger.debug("show=" + show + "(" + show.getText() + ")"); @@ -1428,7 +1427,7 @@ private enum ReplaceConfirmationChoice { private @NotNull String lastPatternOffset = ""; // /{pattern}/{offset}. Do not confuse with caret offset! private boolean lastIgnoreSmartCase; private @NotNull Direction lastDir = Direction.FORWARDS; - private boolean showSearchHighlight = globalOptions(injector).isSet(Options.hlsearch); + private boolean showSearchHighlight = globalOptions(injector).getHlsearch(); private boolean do_all = false; /* do multiple substitutions per line */ private boolean do_ask = false; /* ask for confirmation */ diff --git a/src/main/java/com/maddyhome/idea/vim/group/SystemMarks.kt b/src/main/java/com/maddyhome/idea/vim/group/SystemMarks.kt index b66ae1ca45..7c81175bbf 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/SystemMarks.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/SystemMarks.kt @@ -16,14 +16,13 @@ import com.intellij.ide.bookmark.providers.LineBookmarkProvider import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.api.options -import com.maddyhome.idea.vim.newapi.vim +import com.maddyhome.idea.vim.newapi.globalIjOptions internal class SystemMarks { companion object { @JvmStatic fun createOrGetSystemMark(ch: Char, line: Int, editor: Editor): LineBookmark? { - if (!injector.options(editor.vim).isSet(IjOptions.ideamarks)) return null + if (!injector.globalIjOptions().ideamarks) return null val project = editor.project ?: return null val type = BookmarkType.get(ch) diff --git a/src/main/java/com/maddyhome/idea/vim/group/VimJumpServiceImpl.kt b/src/main/java/com/maddyhome/idea/vim/group/VimJumpServiceImpl.kt index 7e1a418ede..077740d245 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/VimJumpServiceImpl.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/VimJumpServiceImpl.kt @@ -18,11 +18,11 @@ import com.intellij.openapi.fileEditor.impl.IdeDocumentHistoryImpl.RecentPlacesL import com.intellij.openapi.util.text.StringUtil import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimJumpServiceBase -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.diagnostic.vimLogger import com.maddyhome.idea.vim.mark.Jump import com.maddyhome.idea.vim.newapi.IjVimEditor +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.ij import org.jdom.Element @@ -74,7 +74,7 @@ internal class VimJumpServiceImpl : VimJumpServiceBase(), PersistentStateCompone internal class JumpsListener : RecentPlacesListener { override fun recentPlaceAdded(changePlace: PlaceInfo, isChanged: Boolean) { - if (!injector.globalOptions().isSet(IjOptions.unifyjumps)) return + if (!injector.globalIjOptions().unifyjumps) return val jumpService = injector.jumpService if (!isChanged) { @@ -86,7 +86,7 @@ internal class JumpsListener : RecentPlacesListener { } override fun recentPlaceRemoved(changePlace: PlaceInfo, isChanged: Boolean) { - if (!injector.globalOptions().isSet(IjOptions.unifyjumps)) return + if (!injector.globalIjOptions().unifyjumps) return val jumpService = injector.jumpService if (!isChanged) { diff --git a/src/main/java/com/maddyhome/idea/vim/group/VimMarkServiceImpl.kt b/src/main/java/com/maddyhome/idea/vim/group/VimMarkServiceImpl.kt index d7fbcaa127..a2c295e70e 100755 --- a/src/main/java/com/maddyhome/idea/vim/group/VimMarkServiceImpl.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/VimMarkServiceImpl.kt @@ -27,7 +27,6 @@ import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimMarkService import com.maddyhome.idea.vim.api.VimMarkServiceBase -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.group.SystemMarks.Companion.createOrGetSystemMark import com.maddyhome.idea.vim.helper.EditorHelper @@ -36,6 +35,7 @@ import com.maddyhome.idea.vim.mark.IntellijMark import com.maddyhome.idea.vim.mark.Mark import com.maddyhome.idea.vim.mark.VimMark.Companion.create import com.maddyhome.idea.vim.newapi.IjVimEditor +import com.maddyhome.idea.vim.newapi.globalIjOptions import org.jdom.Element import java.util.* @@ -53,7 +53,7 @@ internal class VimMarkServiceImpl : VimMarkServiceBase(), PersistentStateCompone private fun saveData(element: Element) { val globalMarksElement = Element("globalmarks") - if (!injector.globalOptions().isSet(IjOptions.ideamarks)) { + if (!injector.globalIjOptions().ideamarks) { for (mark in globalMarks.values) { val markElem = Element("mark") markElem.setAttribute("key", mark.key.toString()) @@ -103,7 +103,7 @@ internal class VimMarkServiceImpl : VimMarkServiceBase(), PersistentStateCompone // Read access is allowed from event dispatch thread or inside read-action only // (see com.intellij.openapi.application.Application.runReadAction()) val marksElem = element.getChild("globalmarks") - if (marksElem != null && !injector.globalOptions().isSet(IjOptions.ideamarks)) { + if (marksElem != null && !injector.globalIjOptions().ideamarks) { val markList = marksElem.getChildren("mark") for (aMarkList in markList) { val mark: Mark? = create( @@ -166,7 +166,7 @@ internal class VimMarkServiceImpl : VimMarkServiceBase(), PersistentStateCompone } override fun createGlobalMark(editor: VimEditor, char: Char, offset: Int): Mark? { - if (!injector.globalOptions().isSet(IjOptions.ideamarks)) { + if (!injector.globalIjOptions().ideamarks) { return super.createGlobalMark(editor, char, offset) } val lp = editor.offsetToBufferPosition(offset) @@ -241,7 +241,7 @@ internal class VimMarkServiceImpl : VimMarkServiceBase(), PersistentStateCompone class VimBookmarksListener(private val myProject: Project) : BookmarksListener { override fun bookmarkAdded(group: BookmarkGroup, bookmark: Bookmark) { if (!VimPlugin.isEnabled()) return - if (!injector.globalOptions().isSet(IjOptions.ideamarks)) { + if (!injector.globalIjOptions().ideamarks) { return } if (bookmark !is LineBookmark) return @@ -254,7 +254,7 @@ internal class VimMarkServiceImpl : VimMarkServiceBase(), PersistentStateCompone override fun bookmarkRemoved(group: BookmarkGroup, bookmark: Bookmark) { if (!VimPlugin.isEnabled()) return - if (!injector.globalOptions().isSet(IjOptions.ideamarks)) { + if (!injector.globalIjOptions().ideamarks) { return } if (bookmark !is LineBookmark) return diff --git a/src/main/java/com/maddyhome/idea/vim/group/copy/PutGroup.kt b/src/main/java/com/maddyhome/idea/vim/group/copy/PutGroup.kt index e1fec9cc6c..1f20af66d3 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/copy/PutGroup.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/copy/PutGroup.kt @@ -21,7 +21,6 @@ import com.intellij.openapi.ide.CopyPasteManager import com.intellij.util.PlatformUtils import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimCaret import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.getLineEndOffset @@ -210,7 +209,7 @@ internal class PutGroup : VimPutBase() { override fun notifyAboutIdeaPut(editor: VimEditor?) { val project = editor?.ij?.project if (VimPlugin.getVimState().isIdeaPutNotified || ClipboardOptionHelper.ideaputDisabled || - injector.globalOptions().hasValue(Options.clipboard, OptionConstants.clipboard_ideaput) + injector.globalOptions().clipboard.contains(OptionConstants.clipboard_ideaput) ) { return } diff --git a/src/main/java/com/maddyhome/idea/vim/group/visual/IdeaSelectionControl.kt b/src/main/java/com/maddyhome/idea/vim/group/visual/IdeaSelectionControl.kt index 7ec00be650..e5237973bf 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/visual/IdeaSelectionControl.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/visual/IdeaSelectionControl.kt @@ -13,7 +13,6 @@ import com.intellij.openapi.diagnostic.trace import com.intellij.openapi.editor.Editor import com.maddyhome.idea.vim.KeyHandler import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.command.VimStateMachine @@ -139,7 +138,7 @@ internal object IdeaSelectionControl { selectionSource: VimListenerManager.SelectionSource, logReason: Boolean, ): VimStateMachine.Mode { - val selectmode = injector.options(editor.vim).getStringListValues(Options.selectmode) + val selectmode = injector.options(editor.vim).selectmode return when { editor.isOneLineMode -> { if (logReason) logger.debug("Enter select mode. Reason: one line mode") diff --git a/src/main/java/com/maddyhome/idea/vim/group/visual/VimVisualTimer.kt b/src/main/java/com/maddyhome/idea/vim/group/visual/VimVisualTimer.kt index 23e1689289..6fb3fcb26a 100644 --- a/src/main/java/com/maddyhome/idea/vim/group/visual/VimVisualTimer.kt +++ b/src/main/java/com/maddyhome/idea/vim/group/visual/VimVisualTimer.kt @@ -8,12 +8,11 @@ package com.maddyhome.idea.vim.group.visual -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.command.VimStateMachine -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.group.visual.VimVisualTimer.mode import com.maddyhome.idea.vim.group.visual.VimVisualTimer.singleTask +import com.maddyhome.idea.vim.newapi.globalIjOptions import java.awt.event.ActionEvent import javax.swing.Timer @@ -64,7 +63,7 @@ internal object VimVisualTimer { if (mode == null) mode = currentMode // Default delay - 100 ms - val timer = Timer(injector.globalOptions().getIntValue(IjOptions.visualdelay)) { timerAction(task) } + val timer = Timer(injector.globalIjOptions().visualdelay) { timerAction(task) } timer.isRepeats = false timer.start() swingTimer = timer diff --git a/src/main/java/com/maddyhome/idea/vim/handler/VimEnterHandler.kt b/src/main/java/com/maddyhome/idea/vim/handler/VimEnterHandler.kt index b337326974..03549bcdae 100644 --- a/src/main/java/com/maddyhome/idea/vim/handler/VimEnterHandler.kt +++ b/src/main/java/com/maddyhome/idea/vim/handler/VimEnterHandler.kt @@ -14,13 +14,12 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.actionSystem.EditorActionHandler import com.maddyhome.idea.vim.KeyHandler import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.key import com.maddyhome.idea.vim.command.CommandState -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.helper.mode import com.maddyhome.idea.vim.helper.vimStateMachine +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.runFromVimKey import com.maddyhome.idea.vim.newapi.vim import java.awt.event.KeyEvent @@ -133,6 +132,4 @@ internal fun isOctopusEnabled(s: KeyStroke, editor: Editor): Boolean { * what seems to be a way better solution as this is a correct way to override editor actions like enter, right, etc. */ internal val enableOctopus: Boolean - get() { - return injector.globalOptions().isSet(IjOptions.octopushandler) - } + get() = injector.globalIjOptions().octopushandler diff --git a/src/main/java/com/maddyhome/idea/vim/helper/EditorHelper.kt b/src/main/java/com/maddyhome/idea/vim/helper/EditorHelper.kt index 47f70de82b..78f504509c 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/EditorHelper.kt +++ b/src/main/java/com/maddyhome/idea/vim/helper/EditorHelper.kt @@ -16,10 +16,9 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.ex.util.EditorUtil import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx import com.intellij.util.ui.table.JBTableRowEditor -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.group.IjOptionConstants -import com.maddyhome.idea.vim.group.IjOptions +import com.maddyhome.idea.vim.newapi.globalIjOptions import java.awt.Component import javax.swing.JComponent import javax.swing.JTable @@ -34,7 +33,7 @@ public val Editor.fileSize: Int */ internal val Editor.isIdeaVimDisabledHere: Boolean get() { - val ideaVimSupportValue = injector.globalOptions().getStringListValues(IjOptions.ideavimsupport) + val ideaVimSupportValue = injector.globalIjOptions().ideavimsupport return disabledInDialog || (!ClientId.isCurrentlyUnderLocalId) || // CWM-927 (!ideaVimSupportValue.contains(IjOptionConstants.ideavimsupport_singleline) && isDatabaseCell()) || @@ -47,7 +46,7 @@ private fun Editor.isDatabaseCell(): Boolean { private val Editor.disabledInDialog: Boolean get() { - val ideaVimSupportValue = injector.globalOptions().getStringListValues(IjOptions.ideavimsupport) + val ideaVimSupportValue = injector.globalIjOptions().ideavimsupport return ( !ideaVimSupportValue.contains(IjOptionConstants.ideavimsupport_dialog) && !ideaVimSupportValue.contains(IjOptionConstants.ideavimsupport_dialoglegacy) diff --git a/src/main/java/com/maddyhome/idea/vim/helper/ScrollHelper.kt b/src/main/java/com/maddyhome/idea/vim/helper/ScrollHelper.kt index 2e6390bb6c..acb9935096 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/ScrollHelper.kt +++ b/src/main/java/com/maddyhome/idea/vim/helper/ScrollHelper.kt @@ -9,17 +9,16 @@ package com.maddyhome.idea.vim.helper import com.intellij.openapi.editor.Editor -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options import com.maddyhome.idea.vim.newapi.vim internal fun getNormalizedScrollOffset(editor: Editor): Int { - val scrollOffset = injector.options(editor.vim).getIntValue(Options.scrolloff) + val scrollOffset = injector.options(editor.vim).scrolloff return EditorHelper.normalizeScrollOffset(editor, scrollOffset) } internal fun getNormalizedSideScrollOffset(editor: Editor): Int { - val sideScrollOffset = injector.options(editor.vim).getIntValue(Options.sidescrolloff) + val sideScrollOffset = injector.options(editor.vim).sidescrolloff return EditorHelper.normalizeSideScrollOffset(editor, sideScrollOffset) } diff --git a/src/main/java/com/maddyhome/idea/vim/helper/ScrollViewHelper.kt b/src/main/java/com/maddyhome/idea/vim/helper/ScrollViewHelper.kt index a84ac256fd..3447a24616 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/ScrollViewHelper.kt +++ b/src/main/java/com/maddyhome/idea/vim/helper/ScrollViewHelper.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.helper import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.VisualPosition -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.getVisualLineCount import com.maddyhome.idea.vim.api.injector @@ -60,7 +59,7 @@ internal object ScrollViewHelper { val lastLine = vimEditor.getVisualLineCount() - 1 // We need the non-normalised value here, so we can handle cases such as so=999 to keep the current line centred - val scrollOffset = injector.options(vimEditor).getIntValue(Options.scrolloff) + val scrollOffset = injector.options(vimEditor).scrolloff val topBound = topLine + scrollOffset val bottomBound = max(topBound, bottomLine - scrollOffset) @@ -183,7 +182,7 @@ internal object ScrollViewHelper { // Default value is 1. Zero is a valid value, but we normalise to 1 - we always want to scroll at least one line // If the value is negative, it's a percentage of the height. if (scrollJump) { - val scrollJumpSize = injector.options(editor).getIntValue(Options.scrolljump) + val scrollJumpSize = injector.options(editor).scrolljump return if (scrollJumpSize < 0) { (height * (min(100, -scrollJumpSize) / 100.0)).toInt() } else { @@ -202,7 +201,7 @@ internal object ScrollViewHelper { val scrollOffset = getNormalizedSideScrollOffset(editor) val flags = VimStateMachine.getInstance(vimEditor).executingCommandFlags val allowSidescroll = !flags.contains(CommandFlags.FLAG_IGNORE_SIDE_SCROLL_JUMP) - val sidescroll = injector.options(vimEditor).getIntValue(Options.sidescroll) + val sidescroll = injector.options(vimEditor).sidescroll val offsetLeft = caretColumn - (currentVisualLeftColumn + scrollOffset) val offsetRight = caretColumn - (currentVisualRightColumn - scrollOffset) if (offsetLeft < 0 || offsetRight > 0) { diff --git a/src/main/java/com/maddyhome/idea/vim/helper/SearchHelper.java b/src/main/java/com/maddyhome/idea/vim/helper/SearchHelper.java index 774ee2fe82..e290a118fa 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/SearchHelper.java +++ b/src/main/java/com/maddyhome/idea/vim/helper/SearchHelper.java @@ -33,7 +33,6 @@ import com.maddyhome.idea.vim.options.OptionChangeListener; import com.maddyhome.idea.vim.regexp.CharPointer; import com.maddyhome.idea.vim.regexp.RegExp; -import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType; import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString; import kotlin.Pair; import org.jetbrains.annotations.Contract; @@ -2230,7 +2229,7 @@ public void processGlobalValueChange(@Nullable VimString oldValue) { } private static @NotNull String parseMatchPairsOption() { - List pairs = globalOptions(injector).getStringListValues(Options.matchpairs); + List pairs = globalOptions(injector).getMatchpairs(); StringBuilder res = new StringBuilder(); for (String s : pairs) { if (s.length() == 3) { diff --git a/src/main/java/com/maddyhome/idea/vim/helper/SearchHelperKt.kt b/src/main/java/com/maddyhome/idea/vim/helper/SearchHelperKt.kt index d8a3f931ed..831512cccf 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/SearchHelperKt.kt +++ b/src/main/java/com/maddyhome/idea/vim/helper/SearchHelperKt.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.helper -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.common.Direction @@ -169,8 +168,8 @@ private fun quoteChanges(chars: CharSequence, begin: Int) = sequence { * history, the smartcase option is applied, and `\` will only match `Work`. */ internal fun shouldIgnoreCase(pattern: String, ignoreSmartCaseOption: Boolean): Boolean { - val sc = injector.globalOptions().isSet(Options.smartcase) && !ignoreSmartCaseOption - return injector.globalOptions().isSet(Options.ignorecase) && !(sc && containsUpperCase(pattern)) + val sc = injector.globalOptions().smartcase && !ignoreSmartCaseOption + return injector.globalOptions().ignorecase && !(sc && containsUpperCase(pattern)) } private fun containsUpperCase(pattern: String): Boolean { diff --git a/src/main/java/com/maddyhome/idea/vim/helper/SearchHighlightsHelper.kt b/src/main/java/com/maddyhome/idea/vim/helper/SearchHighlightsHelper.kt index 716acbc3bf..52625b902a 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/SearchHighlightsHelper.kt +++ b/src/main/java/com/maddyhome/idea/vim/helper/SearchHighlightsHelper.kt @@ -21,7 +21,6 @@ import com.intellij.openapi.editor.markup.TextAttributes import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.ProjectManager import com.intellij.ui.ColorUtil -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -51,7 +50,7 @@ internal fun updateIncsearchHighlights( ): Int { val searchStartOffset = if (searchRange != null) editor.vim.getLineStartOffset(searchRange.startLine) else caretOffset - val showHighlights = injector.options(editor.vim).isSet(Options.hlsearch) + val showHighlights = injector.options(editor.vim).hlsearch return updateSearchHighlights(pattern, false, showHighlights, searchStartOffset, searchRange, forwards, false) } @@ -115,7 +114,7 @@ private fun updateSearchHighlights( } else if (shouldAddCurrentMatchSearchHighlight(pattern, showHighlights, initialOffset)) { // nohlsearch + incsearch val searchOptions = EnumSet.of(SearchOptions.WHOLE_FILE) - if (injector.globalOptions().isSet(Options.wrapscan)) { + if (injector.globalOptions().wrapscan) { searchOptions.add(SearchOptions.WRAP) } if (shouldIgnoreSmartCase) searchOptions.add(SearchOptions.IGNORE_SMARTCASE) @@ -177,7 +176,7 @@ private fun findClosestMatch(editor: Editor, results: List, initialOf } d2 - d1 } - if (!injector.globalOptions().isSet(Options.wrapscan)) { + if (!injector.globalOptions().wrapscan) { val start = max.startOffset if (forwards && start < initialOffset) { return -1 diff --git a/src/main/java/com/maddyhome/idea/vim/helper/UndoRedoHelper.kt b/src/main/java/com/maddyhome/idea/vim/helper/UndoRedoHelper.kt index f6e28a812b..753ecc7799 100644 --- a/src/main/java/com/maddyhome/idea/vim/helper/UndoRedoHelper.kt +++ b/src/main/java/com/maddyhome/idea/vim/helper/UndoRedoHelper.kt @@ -17,11 +17,11 @@ import com.intellij.openapi.components.Service import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.VimEditor -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.common.ChangesListener import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.ij import com.maddyhome.idea.vim.undo.UndoRedoBase @@ -32,7 +32,7 @@ import com.maddyhome.idea.vim.undo.UndoRedoBase internal class UndoRedoHelper : UndoRedoBase() { init { injector.optionGroup.addListener(IjOptions.oldundo, { - UndoManagerImpl.ourNeverAskUser = !injector.globalOptions().isSet(IjOptions.oldundo) + UndoManagerImpl.ourNeverAskUser = !injector.globalIjOptions().oldundo }, true) } @@ -45,7 +45,7 @@ internal class UndoRedoHelper : UndoRedoBase() { val scrollingModel = editor.getScrollingModel() scrollingModel.accumulateViewportChanges() - if (injector.globalOptions().isSet(IjOptions.oldundo)) { + if (injector.globalIjOptions().oldundo) { SelectionVimListenerSuppressor.lock().use { undoManager.undo(fileEditor) } } else { performUntilFileChanges(editor, { undoManager.isUndoAvailable(fileEditor) }, { undoManager.undo(fileEditor) }) @@ -76,7 +76,7 @@ internal class UndoRedoHelper : UndoRedoBase() { val fileEditor = TextEditorProvider.getInstance().getTextEditor(editor.ij) val undoManager = UndoManager.getInstance(project) if (undoManager.isRedoAvailable(fileEditor)) { - if (injector.globalOptions().isSet(IjOptions.oldundo)) { + if (injector.globalIjOptions().oldundo) { SelectionVimListenerSuppressor.lock().use { undoManager.redo(fileEditor) } } else { performUntilFileChanges(editor, { undoManager.isRedoAvailable(fileEditor) }, { undoManager.redo(fileEditor) }) diff --git a/src/main/java/com/maddyhome/idea/vim/listener/IdeaSpecifics.kt b/src/main/java/com/maddyhome/idea/vim/listener/IdeaSpecifics.kt index 282de0d7ad..c6a7460b72 100644 --- a/src/main/java/com/maddyhome/idea/vim/listener/IdeaSpecifics.kt +++ b/src/main/java/com/maddyhome/idea/vim/listener/IdeaSpecifics.kt @@ -32,17 +32,14 @@ import com.intellij.openapi.util.TextRange import com.maddyhome.idea.vim.KeyHandler import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.action.VimShortcutKeyAction -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.api.invertToggleOption import com.maddyhome.idea.vim.command.VimStateMachine -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.group.NotificationService import com.maddyhome.idea.vim.helper.inNormalMode import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere import com.maddyhome.idea.vim.helper.vimStateMachine +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.vim -import com.maddyhome.idea.vim.options.OptionScope import com.maddyhome.idea.vim.vimscript.model.options.helpers.IdeaRefactorModeHelper import org.jetbrains.annotations.NonNls import java.awt.event.KeyEvent @@ -69,7 +66,7 @@ internal object IdeaSpecifics { } val isVimAction = (action as? AnActionWrapper)?.delegate is VimShortcutKeyAction - if (!isVimAction && injector.globalOptions().isSet(IjOptions.trackactionids)) { + if (!isVimAction && injector.globalIjOptions().trackactionids) { if (action !is NotificationService.ActionIdNotifier.CopyActionId && action !is NotificationService.ActionIdNotifier.StopTracking) { val id: String? = ActionManager.getInstance().getId(action) ?: (action.shortcutSet as? ProxyShortcutSet)?.actionId VimPlugin.getNotifications(event.dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id) @@ -212,10 +209,10 @@ internal object IdeaSpecifics { //region Find action ID internal class FindActionIdAction : DumbAwareToggleAction() { - override fun isSelected(e: AnActionEvent): Boolean = injector.globalOptions().isSet(IjOptions.trackactionids) + override fun isSelected(e: AnActionEvent): Boolean = injector.globalIjOptions().trackactionids override fun setSelected(e: AnActionEvent, state: Boolean) { - injector.optionGroup.invertToggleOption(IjOptions.trackactionids, OptionScope.GLOBAL) + injector.globalIjOptions().trackactionids = !injector.globalIjOptions().trackactionids } } //endregion diff --git a/src/main/java/com/maddyhome/idea/vim/newapi/IjClipboardManager.kt b/src/main/java/com/maddyhome/idea/vim/newapi/IjClipboardManager.kt index ea246c2fa0..35c9cfb62f 100644 --- a/src/main/java/com/maddyhome/idea/vim/newapi/IjClipboardManager.kt +++ b/src/main/java/com/maddyhome/idea/vim/newapi/IjClipboardManager.kt @@ -23,12 +23,10 @@ import com.intellij.openapi.project.IndexNotReadyException import com.intellij.psi.PsiDocumentManager import com.maddyhome.idea.vim.api.VimClipboardManager import com.maddyhome.idea.vim.api.VimEditor -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.common.TextRange import com.maddyhome.idea.vim.diagnostic.debug import com.maddyhome.idea.vim.diagnostic.vimLogger -import com.maddyhome.idea.vim.group.IjOptions import java.awt.HeadlessException import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.Transferable @@ -120,7 +118,7 @@ internal class IjClipboardManager : VimClipboardManager { "\n", transferableData as Collection, ) - if (injector.globalOptions().isSet(IjOptions.ideacopypreprocess)) { + if (injector.ijOptions(vimEditor).ideacopypreprocess) { for (processor in CopyPastePreProcessor.EP_NAME.extensionList) { val escapedText = processor.preprocessOnCopy(file, textRange.startOffsets, textRange.endOffsets, rawText) if (escapedText != null) { diff --git a/src/main/java/com/maddyhome/idea/vim/newapi/IjVimInjector.kt b/src/main/java/com/maddyhome/idea/vim/newapi/IjVimInjector.kt index 427319cd18..f4c2141275 100644 --- a/src/main/java/com/maddyhome/idea/vim/newapi/IjVimInjector.kt +++ b/src/main/java/com/maddyhome/idea/vim/newapi/IjVimInjector.kt @@ -30,6 +30,7 @@ import com.maddyhome.idea.vim.api.VimExOutputPanel import com.maddyhome.idea.vim.api.VimExOutputPanelService import com.maddyhome.idea.vim.api.VimExtensionRegistrator import com.maddyhome.idea.vim.api.VimFile +import com.maddyhome.idea.vim.api.VimInjector import com.maddyhome.idea.vim.api.VimInjectorBase import com.maddyhome.idea.vim.api.VimJumpService import com.maddyhome.idea.vim.api.VimKeyGroup @@ -58,8 +59,11 @@ import com.maddyhome.idea.vim.ex.ExOutputModel import com.maddyhome.idea.vim.extension.VimExtensionRegistrar import com.maddyhome.idea.vim.group.CommandGroup import com.maddyhome.idea.vim.group.EditorGroup +import com.maddyhome.idea.vim.group.EffectiveIjOptions import com.maddyhome.idea.vim.group.FileGroup +import com.maddyhome.idea.vim.group.GlobalIjOptions import com.maddyhome.idea.vim.group.HistoryGroup +import com.maddyhome.idea.vim.group.IjVimOptionGroup import com.maddyhome.idea.vim.group.MacroGroup import com.maddyhome.idea.vim.group.MotionGroup import com.maddyhome.idea.vim.group.SearchGroup @@ -212,3 +216,14 @@ internal class IjVimInjector : VimInjectorBase() { override val editorGroup: VimEditorGroup get() = service() } + +/** + * Convenience function to get the IntelliJ implementation specific global option accessor + */ +public fun VimInjector.globalIjOptions(): GlobalIjOptions = (this.optionGroup as IjVimOptionGroup).getGlobalIjOptions() + +/** + * Convenience function to get the IntelliJ implementation specific option accessor for the given editor's scope + */ +public fun VimInjector.ijOptions(editor: VimEditor): EffectiveIjOptions = + (this.optionGroup as IjVimOptionGroup).getEffectiveIjOptions(editor) diff --git a/src/main/java/com/maddyhome/idea/vim/newapi/IjVimMessages.kt b/src/main/java/com/maddyhome/idea/vim/newapi/IjVimMessages.kt index b114e65a89..a136bfbcf1 100644 --- a/src/main/java/com/maddyhome/idea/vim/newapi/IjVimMessages.kt +++ b/src/main/java/com/maddyhome/idea/vim/newapi/IjVimMessages.kt @@ -12,7 +12,6 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.Service import com.intellij.openapi.project.ProjectManager import com.intellij.openapi.wm.WindowManager -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimMessagesBase import com.maddyhome.idea.vim.api.globalOptions @@ -51,7 +50,7 @@ internal class IjVimMessages : VimMessagesBase() { override fun indicateError() { error = true if (!ApplicationManager.getApplication().isUnitTestMode) { - if (!injector.globalOptions().isSet(Options.visualbell)) { + if (!injector.globalOptions().visualbell) { // Vim only allows a beep once every half second - :help 'visualbell' val currentTimeMillis = System.currentTimeMillis() if (currentTimeMillis - lastBeepTimeMillis > 500) { diff --git a/src/main/java/com/maddyhome/idea/vim/statistic/OptionsState.kt b/src/main/java/com/maddyhome/idea/vim/statistic/OptionsState.kt index 9d2be3ac27..a23d2caeba 100644 --- a/src/main/java/com/maddyhome/idea/vim/statistic/OptionsState.kt +++ b/src/main/java/com/maddyhome/idea/vim/statistic/OptionsState.kt @@ -12,18 +12,14 @@ import com.intellij.internal.statistic.beans.MetricEvent import com.intellij.internal.statistic.eventLog.EventLogGroup import com.intellij.internal.statistic.eventLog.events.BooleanEventField import com.intellij.internal.statistic.eventLog.events.EventFields -import com.intellij.internal.statistic.eventLog.events.StringEventField -import com.intellij.internal.statistic.eventLog.events.StringListEventField import com.intellij.internal.statistic.eventLog.events.VarargEventId import com.intellij.internal.statistic.service.fus.collectors.ApplicationUsagesCollector -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.group.IjOptionConstants import com.maddyhome.idea.vim.group.IjOptions +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.options.OptionConstants -import com.maddyhome.idea.vim.options.StringOption -import com.maddyhome.idea.vim.options.ToggleOption internal class OptionsState : ApplicationUsagesCollector() { @@ -31,30 +27,22 @@ internal class OptionsState : ApplicationUsagesCollector() { override fun getMetrics(): Set { val globalOptions = injector.globalOptions() + val globalIjOptions = injector.globalIjOptions() return setOf( OPTIONS.metric( - IDEAJOIN withOption IjOptions.ideajoin, - IDEAMARKS withOption IjOptions.ideamarks, - IDEAREFACTOR withOption IjOptions.idearefactormode, - IDEAPUT with globalOptions.hasValue(Options.clipboard, OptionConstants.clipboard_ideaput), - IDEASTATUSICON withOption IjOptions.ideastatusicon, - IDEAWRITE withOption IjOptions.ideawrite, - IDEASELECTION with globalOptions.hasValue(Options.selectmode, "ideaselection"), - IDEAVIMSUPPORT withOption IjOptions.ideavimsupport, + IDEAJOIN with globalIjOptions.ideajoin, + IDEAMARKS with globalIjOptions.ideamarks, + IDEAREFACTOR with globalIjOptions.idearefactormode, + IDEAPUT with globalOptions.clipboard.contains(OptionConstants.clipboard_ideaput), + IDEASTATUSICON with globalIjOptions.ideastatusicon, + IDEAWRITE with globalIjOptions.ideawrite, + IDEASELECTION with globalOptions.selectmode.contains(OptionConstants.selectmode_ideaselection), + IDEAVIMSUPPORT with globalIjOptions.ideavimsupport, ), ) } - private infix fun BooleanEventField.withOption(option: ToggleOption) = - this.with(injector.globalOptions().isSet(option)) - - private infix fun StringEventField.withOption(option: StringOption) = - this.with(injector.globalOptions().getStringValue(option)) - - private infix fun StringListEventField.withOption(option: StringOption) = - this.with(injector.globalOptions().getStringListValues(option)) - companion object { private val GROUP = EventLogGroup("vim.options", 1) @@ -62,10 +50,10 @@ internal class OptionsState : ApplicationUsagesCollector() { private val IDEAMARKS = BooleanEventField(IjOptions.ideamarks.name) // TODO: This looks like the wrong name!! private val IDEAREFACTOR = EventFields.String(IjOptions.ideamarks.name, IjOptionConstants.ideaRefactorModeValues.toList()) - private val IDEAPUT = BooleanEventField("ideaput") + private val IDEAPUT = BooleanEventField(OptionConstants.clipboard_ideaput) private val IDEASTATUSICON = EventFields.String(IjOptions.ideastatusicon.name, IjOptionConstants.ideaStatusIconValues.toList()) private val IDEAWRITE = EventFields.String(IjOptions.ideawrite.name, IjOptionConstants.ideaWriteValues.toList()) - private val IDEASELECTION = BooleanEventField("ideaselection") + private val IDEASELECTION = BooleanEventField(OptionConstants.selectmode_ideaselection) private val IDEAVIMSUPPORT = EventFields.StringList(IjOptions.ideavimsupport.name, IjOptionConstants.ideavimsupportValues.toList()) private val OPTIONS: VarargEventId = GROUP.registerVarargEvent( diff --git a/src/main/java/com/maddyhome/idea/vim/ui/ExOutputPanel.java b/src/main/java/com/maddyhome/idea/vim/ui/ExOutputPanel.java index 9c4389990a..2570139680 100644 --- a/src/main/java/com/maddyhome/idea/vim/ui/ExOutputPanel.java +++ b/src/main/java/com/maddyhome/idea/vim/ui/ExOutputPanel.java @@ -18,7 +18,6 @@ import com.maddyhome.idea.vim.KeyHandler; import com.maddyhome.idea.vim.VimPlugin; import com.maddyhome.idea.vim.api.ExecutionContext; -import com.maddyhome.idea.vim.api.Options; import com.maddyhome.idea.vim.helper.HelperKt; import com.maddyhome.idea.vim.helper.MessageHelper; import com.maddyhome.idea.vim.helper.UiHelper; @@ -275,7 +274,7 @@ private void positionPanel() { setBounds(bounds); myScrollPane.getVerticalScrollBar().setValue(0); - if (!globalOptions(injector).isSet(Options.more)) { + if (!globalOptions(injector).getMore()) { // FIX scrollOffset(100000); } diff --git a/src/main/java/com/maddyhome/idea/vim/ui/ShowCmd.kt b/src/main/java/com/maddyhome/idea/vim/ui/ShowCmd.kt index a3a3fe4ea3..1e66dafe1d 100644 --- a/src/main/java/com/maddyhome/idea/vim/ui/ShowCmd.kt +++ b/src/main/java/com/maddyhome/idea/vim/ui/ShowCmd.kt @@ -21,7 +21,6 @@ import com.intellij.openapi.wm.WindowManager import com.intellij.openapi.wm.impl.status.EditorBasedWidget import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsManager import com.intellij.util.Consumer -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.helper.EngineStringHelper @@ -59,7 +58,7 @@ internal object ShowCmd { } fun getFullText(editor: Editor?): String { - if (!injector.globalOptions().isSet(Options.showcmd) || editor == null || editor.isDisposed) return "" + if (!injector.globalOptions().showcmd || editor == null || editor.isDisposed) return "" val editorState = editor.vim.vimStateMachine return EngineStringHelper.toPrintableCharacters(editorState.commandBuilder.keys + editorState.mappingState.keys) @@ -88,7 +87,7 @@ internal class ShowCmdStatusBarWidgetFactory : StatusBarWidgetFactory/*, LightEd // Nothing } - override fun isAvailable(project: Project): Boolean = injector.globalOptions().isSet(Options.showcmd) + override fun isAvailable(project: Project): Boolean = injector.globalOptions().showcmd override fun createWidget(project: Project): StatusBarWidget = Widget(project) diff --git a/src/main/java/com/maddyhome/idea/vim/ui/StatusBar.kt b/src/main/java/com/maddyhome/idea/vim/ui/StatusBar.kt index 3f7cf8c83b..a71cdad9ef 100644 --- a/src/main/java/com/maddyhome/idea/vim/ui/StatusBar.kt +++ b/src/main/java/com/maddyhome/idea/vim/ui/StatusBar.kt @@ -40,13 +40,13 @@ import com.intellij.ui.awt.RelativePoint import com.intellij.util.Consumer import com.intellij.util.ui.LafIconLookup import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.group.IjOptionConstants import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.group.NotificationService import com.maddyhome.idea.vim.helper.MessageHelper import com.maddyhome.idea.vim.icons.VimIcons +import com.maddyhome.idea.vim.newapi.globalIjOptions import org.jetbrains.annotations.NonNls import java.awt.Point import java.awt.event.MouseEvent @@ -68,7 +68,7 @@ internal class StatusBarIconFactory : StatusBarWidgetFactory/*, LightEditCompati } override fun isAvailable(project: Project): Boolean { - return !injector.globalOptions().hasValue(IjOptions.ideastatusicon, IjOptionConstants.ideastatusicon_disabled) + return injector.globalIjOptions().ideastatusicon != IjOptionConstants.ideastatusicon_disabled } override fun createWidget(project: Project): StatusBarWidget { @@ -118,7 +118,7 @@ internal class VimStatusBar : StatusBarWidget, StatusBarWidget.IconPresentation override fun getTooltipText() = STATUS_BAR_DISPLAY_NAME override fun getIcon(): Icon { - if (injector.globalOptions().hasValue(IjOptions.ideastatusicon, IjOptionConstants.ideastatusicon_gray)) { + if (injector.globalIjOptions().ideastatusicon == IjOptionConstants.ideastatusicon_gray) { return VimIcons.IDEAVIM_DISABLED } return if (VimPlugin.isEnabled()) VimIcons.IDEAVIM else VimIcons.IDEAVIM_DISABLED diff --git a/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java b/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java index e94aaed210..567dc5ed0d 100644 --- a/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java +++ b/src/main/java/com/maddyhome/idea/vim/ui/ex/ExEntryPanel.java @@ -19,7 +19,6 @@ import com.intellij.ui.DocumentAdapter; import com.intellij.util.IJSwingUtilities; import com.maddyhome.idea.vim.VimPlugin; -import com.maddyhome.idea.vim.api.Options; import com.maddyhome.idea.vim.ex.ranges.LineRange; import com.maddyhome.idea.vim.helper.SearchHighlightsHelper; import com.maddyhome.idea.vim.helper.UiHelper; @@ -423,7 +422,7 @@ private void positionPanel() { } private boolean isIncSearchEnabled() { - return globalOptions(injector).isSet(Options.incsearch); + return globalOptions(injector).getIncsearch(); } private boolean active; diff --git a/src/main/java/com/maddyhome/idea/vim/vimscript/model/functions/handlers/ColLineFunctionHandler.kt b/src/main/java/com/maddyhome/idea/vim/vimscript/model/functions/handlers/ColLineFunctionHandler.kt index e744a1f76c..38ac965c28 100644 --- a/src/main/java/com/maddyhome/idea/vim/vimscript/model/functions/handlers/ColLineFunctionHandler.kt +++ b/src/main/java/com/maddyhome/idea/vim/vimscript/model/functions/handlers/ColLineFunctionHandler.kt @@ -9,7 +9,6 @@ package com.maddyhome.idea.vim.vimscript.model.functions.handlers import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.lineLength @@ -68,7 +67,7 @@ private fun currentCol(editor: VimEditor): VimInt { // If virtualedit is set, the col is one more // XXX Should we also check the current mode? - if (injector.options(editor).getStringListValues(Options.virtualedit).isNotEmpty()) { + if (injector.options(editor).virtualedit.isNotEmpty()) { lineLength += 1 } diff --git a/src/main/java/com/maddyhome/idea/vim/vimscript/model/options/helpers/IdeaRefactorModeHelper.kt b/src/main/java/com/maddyhome/idea/vim/vimscript/model/options/helpers/IdeaRefactorModeHelper.kt index c51690eef8..38960741dc 100644 --- a/src/main/java/com/maddyhome/idea/vim/vimscript/model/options/helpers/IdeaRefactorModeHelper.kt +++ b/src/main/java/com/maddyhome/idea/vim/vimscript/model/options/helpers/IdeaRefactorModeHelper.kt @@ -15,23 +15,22 @@ import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.codeInsight.template.impl.TemplateManagerImpl import com.intellij.openapi.editor.Editor import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.group.IjOptionConstants -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.helper.editorMode import com.maddyhome.idea.vim.helper.hasBlockOrUnderscoreCaret import com.maddyhome.idea.vim.helper.hasVisualSelection import com.maddyhome.idea.vim.helper.subMode import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.vim internal object IdeaRefactorModeHelper { fun keepMode() = - injector.globalOptions().hasValue(IjOptions.idearefactormode, IjOptionConstants.idearefactormode_keep) + injector.globalIjOptions().idearefactormode.contains(IjOptionConstants.idearefactormode_keep) fun selectMode() = - injector.globalOptions().hasValue(IjOptions.idearefactormode, IjOptionConstants.idearefactormode_select) + injector.globalIjOptions().idearefactormode.contains(IjOptionConstants.idearefactormode_select) fun correctSelection(editor: Editor) { val action: () -> Unit = { diff --git a/src/test/java/org/jetbrains/plugins/ideavim/TestHelper.kt b/src/test/java/org/jetbrains/plugins/ideavim/TestHelper.kt index f20d8083e1..8ea353c90b 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/TestHelper.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/TestHelper.kt @@ -14,12 +14,11 @@ import com.intellij.openapi.editor.LogicalPosition import com.intellij.testFramework.EditorTestUtil import com.intellij.testFramework.fixtures.CodeInsightTestFixture import com.intellij.util.containers.toArray -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.command.VimStateMachine import com.maddyhome.idea.vim.common.TextRange -import com.maddyhome.idea.vim.group.IjOptions import com.maddyhome.idea.vim.helper.editorMode +import com.maddyhome.idea.vim.newapi.globalIjOptions import org.junit.jupiter.params.provider.Arguments import kotlin.test.fail @@ -71,7 +70,7 @@ fun waitAndAssertMode( mode: VimStateMachine.Mode, timeInMillis: Int? = null, ) { - val timeout = timeInMillis ?: (injector.globalOptions().getIntValue(IjOptions.visualdelay) + 1000) + val timeout = timeInMillis ?: (injector.globalIjOptions().visualdelay + 1000) waitAndAssert(timeout) { fixture.editor.editorMode == mode } } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/VimTestCase.kt b/src/test/java/org/jetbrains/plugins/ideavim/VimTestCase.kt index f0c3c54fb3..0b227085b5 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/VimTestCase.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/VimTestCase.kt @@ -40,7 +40,7 @@ import com.intellij.util.ui.EmptyClipboardOwner import com.maddyhome.idea.vim.KeyHandler import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.action.VimShortcutKeyAction -import com.maddyhome.idea.vim.api.Options +import com.maddyhome.idea.vim.api.EffectiveOptions import com.maddyhome.idea.vim.api.VimOptionGroup import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector @@ -52,6 +52,7 @@ import com.maddyhome.idea.vim.command.VimStateMachine import com.maddyhome.idea.vim.command.VimStateMachine.SubMode import com.maddyhome.idea.vim.ex.ExException import com.maddyhome.idea.vim.ex.ExOutputModel.Companion.getInstance +import com.maddyhome.idea.vim.group.GlobalIjOptions import com.maddyhome.idea.vim.group.visual.VimVisualTimer.swingTimer import com.maddyhome.idea.vim.handler.isOctopusEnabled import com.maddyhome.idea.vim.helper.EditorHelper @@ -66,10 +67,10 @@ import com.maddyhome.idea.vim.key.MappingOwner import com.maddyhome.idea.vim.key.ToKeysMappingInfo import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor import com.maddyhome.idea.vim.newapi.IjVimEditor +import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.ij import com.maddyhome.idea.vim.newapi.vim import com.maddyhome.idea.vim.options.OptionScope -import com.maddyhome.idea.vim.options.OptionValueAccessor import com.maddyhome.idea.vim.options.ToggleOption import com.maddyhome.idea.vim.options.helpers.GuiCursorOptionHelper import com.maddyhome.idea.vim.options.helpers.GuiCursorType @@ -127,7 +128,7 @@ abstract class VimTestCase { VimPlugin.getKey().resetKeyMappings() VimPlugin.getSearch().resetState() if (!VimPlugin.isEnabled()) VimPlugin.setEnabled(true) - injector.optionGroup.setToggleOption(Options.ideastrictmode, OptionScope.GLOBAL) + injector.globalOptions().ideastrictmode = true GuicursorChangeListener.processGlobalValueChange(null) Checks.reset() clearClipboard() @@ -300,8 +301,8 @@ abstract class VimTestCase { // Note that it is possible to request a position which would be invalid under normal Vim! // We disable scrolloff + scrolljump, position as requested, and reset. When resetting scrolloff, Vim will // recalculate the correct offsets, and that could move the top and/or caret line - val scrolloff = options().getIntValue(Options.scrolloff) - val scrolljump = options().getIntValue(Options.scrolljump) + val scrolloff = options().scrolloff + val scrolljump = options().scrolljump enterCommand("set scrolloff=0") enterCommand("set scrolljump=1") @@ -363,7 +364,7 @@ abstract class VimTestCase { * options (e.g. 'iskeyword', 'relativenumber' or 'scrolloff' respectively). Tests are only expected to require * effective values. To test other global/local values, use [VimOptionGroup]. */ - protected fun options(): OptionValueAccessor { + protected fun options(): EffectiveOptions { assertNotNull( fixture.editor, "Editor is null! Move the call to after editor is initialised, or use optionsNoEditor", @@ -381,9 +382,9 @@ abstract class VimTestCase { * Note that this isn't handled automatically by [options] to avoid the scenario of trying to use effective values * before the editor has been initialised. */ - protected fun optionsNoEditor(): OptionValueAccessor { + protected fun optionsNoEditor(): GlobalIjOptions { assertNull(fixture.editor, "Editor is not null! Use options() to access effective option values") - return injector.globalOptions() + return injector.globalIjOptions() } fun assertState(textAfter: String) { diff --git a/src/test/java/org/jetbrains/plugins/ideavim/action/change/UndoActionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/action/change/UndoActionTest.kt index 785931606f..5018b863d9 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/action/change/UndoActionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/action/change/UndoActionTest.kt @@ -9,7 +9,6 @@ package org.jetbrains.plugins.ideavim.action.change import com.maddyhome.idea.vim.command.VimStateMachine -import com.maddyhome.idea.vim.group.IjOptions import org.jetbrains.plugins.ideavim.VimTestCase import org.junit.jupiter.api.Test @@ -72,7 +71,7 @@ class UndoActionTest : VimTestCase() { @Test fun `test cursor movements do not require additional undo`() { - if (!optionsNoEditor().isSet(IjOptions.oldundo)) { + if (!optionsNoEditor().oldundo) { val keys = listOf("a1ea2ea3", "uu") val before = """ Lorem Ipsum diff --git a/src/test/java/org/jetbrains/plugins/ideavim/action/copy/PutTestAfterCursorActionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/action/copy/PutTestAfterCursorActionTest.kt index fa76d5ec85..91a941f619 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/action/copy/PutTestAfterCursorActionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/action/copy/PutTestAfterCursorActionTest.kt @@ -16,16 +16,13 @@ import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiFile import com.intellij.testFramework.ExtensionTestUtil import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.Options +import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.api.modifyOptionValue import com.maddyhome.idea.vim.command.SelectionType import com.maddyhome.idea.vim.command.VimStateMachine import com.maddyhome.idea.vim.helper.VimBehaviorDiffers import com.maddyhome.idea.vim.newapi.vim import com.maddyhome.idea.vim.options.OptionConstants -import com.maddyhome.idea.vim.options.OptionScope -import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString import org.jetbrains.plugins.ideavim.VimTestCase import org.jetbrains.plugins.ideavim.rangeOf import org.junit.jupiter.api.Test @@ -34,9 +31,8 @@ import java.awt.datatransfer.Transferable class PutTestAfterCursorActionTest : VimTestCase() { @Test fun `test platform handlers are called`() { - injector.optionGroup.modifyOptionValue(Options.clipboard, OptionScope.GLOBAL) { - Options.clipboard.prependValue(it, VimString(OptionConstants.clipboard_ideaput)) - } + injector.globalOptions().clipboard.prependValue(OptionConstants.clipboard_ideaput) + val extension = TestExtension() ExtensionTestUtil.maskExtensions( CopyPastePostProcessor.EP_NAME, diff --git a/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionHomeActionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionHomeActionTest.kt index c484acd5ef..d6d2bfe3a3 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionHomeActionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionHomeActionTest.kt @@ -10,7 +10,6 @@ package org.jetbrains.plugins.ideavim.action.motion.leftright -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.command.VimStateMachine import com.maddyhome.idea.vim.options.OptionConstants import org.jetbrains.plugins.ideavim.SkipNeovimReason @@ -20,6 +19,7 @@ import org.jetbrains.plugins.ideavim.VimTestCase import org.jetbrains.plugins.ideavim.impl.OptionTest import org.jetbrains.plugins.ideavim.impl.TraceOptions import org.jetbrains.plugins.ideavim.impl.VimOption +import kotlin.test.assertTrue @TraceOptions(TestOptionConstants.keymodel) class MotionHomeActionTest : VimTestCase() { @@ -48,8 +48,8 @@ class MotionHomeActionTest : VimTestCase() { @OptionTest(VimOption(TestOptionConstants.keymodel, doesntAffectTest = true)) fun `test default stop select`() { - val keymodel = optionsNoEditor().getStringListValues(Options.keymodel) - kotlin.test.assertTrue(OptionConstants.keymodel_stopselect in keymodel) + val keymodel = optionsNoEditor().keymodel + assertTrue(OptionConstants.keymodel_stopselect in keymodel) } @TestWithoutNeovim(SkipNeovimReason.OPTION) diff --git a/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionShiftHomeActionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionShiftHomeActionTest.kt index 92b4476d0e..125318fa8e 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionShiftHomeActionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/action/motion/leftright/MotionShiftHomeActionTest.kt @@ -10,7 +10,6 @@ package org.jetbrains.plugins.ideavim.action.motion.leftright -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.command.VimStateMachine import com.maddyhome.idea.vim.options.OptionConstants @@ -21,6 +20,7 @@ import org.jetbrains.plugins.ideavim.VimTestCase import org.jetbrains.plugins.ideavim.impl.OptionTest import org.jetbrains.plugins.ideavim.impl.TraceOptions import org.jetbrains.plugins.ideavim.impl.VimOption +import kotlin.test.assertTrue @TraceOptions(TestOptionConstants.keymodel, TestOptionConstants.selectmode) class MotionShiftHomeActionTest : VimTestCase() { @@ -55,8 +55,8 @@ class MotionShiftHomeActionTest : VimTestCase() { VimOption(TestOptionConstants.selectmode, doesntAffectTest = true), ) fun `test default continueselect`() { - val keymodel = optionsNoEditor().getStringListValues(Options.keymodel) - kotlin.test.assertTrue(OptionConstants.keymodel_continueselect in keymodel) + val keymodel = optionsNoEditor().keymodel + assertTrue(OptionConstants.keymodel_continueselect in keymodel) } @TestWithoutNeovim(SkipNeovimReason.OPTION) diff --git a/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageDownActionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageDownActionTest.kt index 37d1cdc2d0..0f653925ba 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageDownActionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageDownActionTest.kt @@ -8,12 +8,13 @@ package org.jetbrains.plugins.ideavim.action.scroll -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import org.jetbrains.plugins.ideavim.SkipNeovimReason import org.jetbrains.plugins.ideavim.TestWithoutNeovim import org.jetbrains.plugins.ideavim.VimTestCase import org.junit.jupiter.api.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue /* *CTRL-D* @@ -48,7 +49,7 @@ class ScrollHalfPageDownActionTest : VimTestCase() { typeText("") assertPosition(175, 0) assertVisibleArea(146, 175) - kotlin.test.assertTrue(injector.messages.isError()) + assertTrue(injector.messages.isError()) } @TestWithoutNeovim(SkipNeovimReason.SCROLL) @@ -114,7 +115,7 @@ class ScrollHalfPageDownActionTest : VimTestCase() { setPositionAndScroll(100, 110) typeText("10") - kotlin.test.assertEquals(10, options().getIntValue(Options.scroll)) + assertEquals(10, options().scroll) } @TestWithoutNeovim(SkipNeovimReason.SCROLL) diff --git a/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageUpActionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageUpActionTest.kt index 97ca302789..cdd3fbcdba 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageUpActionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/action/scroll/ScrollHalfPageUpActionTest.kt @@ -8,12 +8,13 @@ package org.jetbrains.plugins.ideavim.action.scroll -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import org.jetbrains.plugins.ideavim.SkipNeovimReason import org.jetbrains.plugins.ideavim.TestWithoutNeovim import org.jetbrains.plugins.ideavim.VimTestCase import org.junit.jupiter.api.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue /* *CTRL-U* @@ -46,7 +47,7 @@ class ScrollHalfPageUpActionTest : VimTestCase() { typeText("") assertPosition(0, 0) assertVisibleArea(0, 34) - kotlin.test.assertTrue(injector.messages.isError()) + assertTrue(injector.messages.isError()) } @TestWithoutNeovim(SkipNeovimReason.SCROLL) @@ -86,7 +87,7 @@ class ScrollHalfPageUpActionTest : VimTestCase() { configureByPages(5) setPositionAndScroll(50, 53) typeText("10") - kotlin.test.assertEquals(10, options().getIntValue(Options.scroll)) + assertEquals(10, options().scroll) } @TestWithoutNeovim(SkipNeovimReason.SCROLL) diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/ExEntryTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/ExEntryTest.kt index fa9dfa38e8..dd683e53cf 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/ex/ExEntryTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/ExEntryTest.kt @@ -9,7 +9,6 @@ package org.jetbrains.plugins.ideavim.ex import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.helper.VimBehaviorDiffers import com.maddyhome.idea.vim.ui.ex.ExDocument @@ -22,6 +21,9 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInfo import java.awt.event.KeyEvent import javax.swing.KeyStroke +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue class ExEntryTest : VimTestCase() { @BeforeEach @@ -32,47 +34,47 @@ class ExEntryTest : VimTestCase() { @Test fun `test cancel entry`() { - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) typeExInput(":set incsearch") - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) assertIsDeactivated() deactivateExEntry() - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) typeExInput(":set incsearch") - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) assertIsDeactivated() deactivateExEntry() - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) typeExInput(":set incsearch") - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) assertIsDeactivated() } @Test fun `test complete entry`() { - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) typeExInput(":set incsearch") - kotlin.test.assertTrue(options().isSet(Options.incsearch)) + assertTrue(options().incsearch) assertIsDeactivated() deactivateExEntry() VimPlugin.getOptionGroup().resetAllOptions() - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) typeExInput(":set incsearch") - kotlin.test.assertTrue(options().isSet(Options.incsearch)) + assertTrue(options().incsearch) assertIsDeactivated() deactivateExEntry() VimPlugin.getOptionGroup().resetAllOptions() - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) typeExInput(":set incsearch") - kotlin.test.assertTrue(options().isSet(Options.incsearch)) + assertTrue(options().incsearch) assertIsDeactivated() } @@ -82,22 +84,22 @@ class ExEntryTest : VimTestCase() { // Show vertical bar in insert mode // Show horizontal bar in replace mode typeExInput(":") - kotlin.test.assertEquals("BLOCK 100", exEntryPanel.entry.caretShape) + assertEquals("BLOCK 100", exEntryPanel.entry.caretShape) typeText("set") - kotlin.test.assertEquals("BLOCK 100", exEntryPanel.entry.caretShape) + assertEquals("BLOCK 100", exEntryPanel.entry.caretShape) deactivateExEntry() typeExInput(":set") - kotlin.test.assertEquals("VER 25", exEntryPanel.entry.caretShape) + assertEquals("VER 25", exEntryPanel.entry.caretShape) deactivateExEntry() typeExInput(":set") - kotlin.test.assertEquals("HOR 20", exEntryPanel.entry.caretShape) + assertEquals("HOR 20", exEntryPanel.entry.caretShape) deactivateExEntry() typeExInput(":set") - kotlin.test.assertEquals("VER 25", exEntryPanel.entry.caretShape) + assertEquals("VER 25", exEntryPanel.entry.caretShape) } @Test @@ -105,22 +107,22 @@ class ExEntryTest : VimTestCase() { enterCommand("set guicursor=c:ver50,ci:hor75,cr:block") typeExInput(":") - kotlin.test.assertEquals("VER 50", exEntryPanel.entry.caretShape) + assertEquals("VER 50", exEntryPanel.entry.caretShape) typeText("set") - kotlin.test.assertEquals("VER 50", exEntryPanel.entry.caretShape) + assertEquals("VER 50", exEntryPanel.entry.caretShape) deactivateExEntry() typeExInput(":set") - kotlin.test.assertEquals("HOR 75", exEntryPanel.entry.caretShape) + assertEquals("HOR 75", exEntryPanel.entry.caretShape) deactivateExEntry() typeExInput(":set") - kotlin.test.assertEquals("BLOCK 100", exEntryPanel.entry.caretShape) + assertEquals("BLOCK 100", exEntryPanel.entry.caretShape) deactivateExEntry() typeExInput(":set") - kotlin.test.assertEquals("HOR 75", exEntryPanel.entry.caretShape) + assertEquals("HOR 75", exEntryPanel.entry.caretShape) } @Test @@ -369,18 +371,18 @@ class ExEntryTest : VimTestCase() { @Test fun `test toggle insert replace`() { val exDocument = exEntryPanel.entry.document as ExDocument - kotlin.test.assertFalse(exDocument.isOverwrite) + assertFalse(exDocument.isOverwrite) typeExInput(":setdigraph") assertExText("digraphset") deactivateExEntry() typeExInput(":setdigraph") - kotlin.test.assertTrue(exDocument.isOverwrite) + assertTrue(exDocument.isOverwrite) assertExText("digraph") typeText("set ") - kotlin.test.assertFalse(exDocument.isOverwrite) + assertFalse(exDocument.isOverwrite) assertExText("set digraph") } @@ -476,7 +478,7 @@ class ExEntryTest : VimTestCase() { // this isn't true - digraph entry is stopped, but command line mode continues typeExInput(":OK") assertIsActive() - kotlin.test.assertEquals("K", exEntryPanel.text) + assertEquals("K", exEntryPanel.text) deactivateExEntry() } @@ -630,7 +632,7 @@ class ExEntryTest : VimTestCase() { } private fun typeExInput(text: String) { - kotlin.test.assertTrue( + assertTrue( text.startsWith(":") || text.startsWith('/') || text.startsWith('?'), "Ex command must start with ':', '/' or '?'", ) @@ -662,22 +664,21 @@ class ExEntryTest : VimTestCase() { } } - @Suppress("DEPRECATION") private fun assertExText(expected: String) { // Get the text directly from the text field. This will include any "prompt" chars for e.g. digraphs - kotlin.test.assertEquals(expected, exEntryPanel.entry.text) + assertEquals(expected, exEntryPanel.entry.text) } private fun assertIsActive() { - kotlin.test.assertTrue(exEntryPanel.isActive) + assertTrue(exEntryPanel.isActive) } private fun assertIsDeactivated() { - kotlin.test.assertFalse(exEntryPanel.isActive) + assertFalse(exEntryPanel.isActive) } private fun assertExOffset(expected: Int) { - kotlin.test.assertEquals(expected, caret.dot) + assertEquals(expected, caret.dot) } private val exEntryPanel diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/MultipleCaretsTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/MultipleCaretsTest.kt index 7bc5403b13..0cdf5eb92b 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/ex/MultipleCaretsTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/MultipleCaretsTest.kt @@ -9,7 +9,6 @@ package org.jetbrains.plugins.ideavim.ex import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.command.SelectionType import com.maddyhome.idea.vim.common.TextRange @@ -120,7 +119,7 @@ class MultipleCaretsTest : VimTestCase() { fun testPutText() { // This test produces double ${c}zxc on 3rd line if non-idea paste is used // TODO: Investigate differences and reconcile - assertContains(optionsNoEditor().getStringListValues(Options.clipboard), OptionConstants.clipboard_ideaput) + assertContains(optionsNoEditor().clipboard, OptionConstants.clipboard_ideaput) val before = """ ${c}qwe diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/LetCommandTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/LetCommandTest.kt index 9a57ec2115..0489c185b3 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/LetCommandTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/LetCommandTest.kt @@ -8,13 +8,15 @@ package org.jetbrains.plugins.ideavim.ex.implementation.commands -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment import org.jetbrains.plugins.ideavim.SkipNeovimReason import org.jetbrains.plugins.ideavim.TestWithoutNeovim import org.jetbrains.plugins.ideavim.VimTestCase import org.junit.jupiter.api.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue class LetCommandTest : VimTestCase() { @@ -130,20 +132,20 @@ class LetCommandTest : VimTestCase() { fun `test let option`() { configureByText("\n") typeText(commandToKeys("set noincsearch")) - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) typeText(commandToKeys("let &incsearch = 12")) - kotlin.test.assertTrue(options().isSet(Options.incsearch)) + assertTrue(options().incsearch) typeText(commandToKeys("set noincsearch")) - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) } @Test fun `test let option2`() { configureByText("\n") typeText(commandToKeys("set incsearch")) - kotlin.test.assertTrue(options().isSet(Options.incsearch)) + assertTrue(options().incsearch) typeText(commandToKeys("let &incsearch = 0")) - kotlin.test.assertFalse(options().isSet(Options.incsearch)) + assertFalse(options().incsearch) } @Test @@ -160,7 +162,7 @@ class LetCommandTest : VimTestCase() { typeText(commandToKeys("let g:WhichKey_ShowVimActions = \"true\"")) typeText(commandToKeys("echo g:WhichKey_ShowVimActions")) assertExOutput("true\n") - kotlin.test.assertEquals("true", VimScriptGlobalEnvironment.getInstance().variables["g:WhichKey_ShowVimActions"]) + assertEquals("true", VimScriptGlobalEnvironment.getInstance().variables["g:WhichKey_ShowVimActions"]) } @Test diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/SetCommandTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/SetCommandTest.kt index 71d7023fe1..accae14817 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/SetCommandTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/SetCommandTest.kt @@ -15,6 +15,9 @@ import org.jetbrains.plugins.ideavim.SkipNeovimReason import org.jetbrains.plugins.ideavim.TestWithoutNeovim import org.jetbrains.plugins.ideavim.VimTestCase import org.junit.jupiter.api.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue class SetCommandTest : VimTestCase() { @@ -30,9 +33,9 @@ class SetCommandTest : VimTestCase() { fun `test toggle option`() { configureByText("\n") enterCommand("set rnu") - kotlin.test.assertTrue(options().isSet(Options.relativenumber)) + assertTrue(options().relativenumber) enterCommand("set rnu!") - kotlin.test.assertFalse(options().isSet(Options.relativenumber)) + assertFalse(options().relativenumber) } // todo we have spaces in assertExOutput because of pad(20) in the com.maddyhome.idea.vim.vimscript.model.commands.SetCommandKt#showOptions method @@ -41,11 +44,11 @@ class SetCommandTest : VimTestCase() { fun `test number option`() { configureByText("\n") enterCommand("set scrolloff&") - kotlin.test.assertEquals(0, options().getIntValue(Options.scrolloff)) + assertEquals(0, options().scrolloff) enterCommand("set scrolloff?") assertExOutput("scrolloff=0 \n") enterCommand("set scrolloff=5") - kotlin.test.assertEquals(5, options().getIntValue(Options.scrolloff)) + assertEquals(5, options().scrolloff) enterCommand("set scrolloff?") assertExOutput("scrolloff=5 \n") } @@ -55,11 +58,11 @@ class SetCommandTest : VimTestCase() { fun `test toggle option as a number`() { configureByText("\n") enterCommand("set number&") - kotlin.test.assertEquals(0, injector.optionGroup.getOptionValue(Options.number, OptionScope.GLOBAL).asDouble().toInt()) + assertEquals(0, injector.optionGroup.getOptionValue(Options.number, OptionScope.GLOBAL).asDouble().toInt()) enterCommand("set number?") assertExOutput("nonumber \n") enterCommand("let &nu=1000") - kotlin.test.assertEquals(1000, injector.optionGroup.getOptionValue(Options.number, OptionScope.GLOBAL).asDouble().toInt()) + assertEquals(1000, injector.optionGroup.getOptionValue(Options.number, OptionScope.GLOBAL).asDouble().toInt()) enterCommand("set number?") assertExOutput(" number \n") } @@ -118,11 +121,11 @@ class SetCommandTest : VimTestCase() { fun `test string option`() { configureByText("\n") enterCommand("set selection&") - kotlin.test.assertEquals("inclusive", options().getStringValue(Options.selection)) + assertEquals("inclusive", options().selection) enterCommand("set selection?") assertExOutput("selection=inclusive \n") enterCommand("set selection=exclusive") - kotlin.test.assertEquals("exclusive", options().getStringValue(Options.selection)) + assertEquals("exclusive", options().selection) enterCommand("set selection?") assertExOutput("selection=exclusive \n") } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/extension/replacewithregister/ReplaceWithRegisterTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/extension/replacewithregister/ReplaceWithRegisterTest.kt index c0267d8b9a..8e5493a562 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/extension/replacewithregister/ReplaceWithRegisterTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/extension/replacewithregister/ReplaceWithRegisterTest.kt @@ -10,7 +10,6 @@ package org.jetbrains.plugins.ideavim.extension.replacewithregister import com.intellij.testFramework.UsefulTestCase.assertContainsElements import com.maddyhome.idea.vim.VimPlugin -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.command.SelectionType import com.maddyhome.idea.vim.command.VimStateMachine @@ -23,6 +22,7 @@ import org.jetbrains.plugins.ideavim.rangeOf import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInfo +import kotlin.test.assertEquals class ReplaceWithRegisterTest : VimTestCase() { @@ -52,7 +52,7 @@ class ReplaceWithRegisterTest : VimTestCase() { .storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false) typeText(injector.parser.parseKeys("griw")) assertState("one on${c}e three") - kotlin.test.assertEquals("one", VimPlugin.getRegister().lastRegister?.text) + assertEquals("one", VimPlugin.getRegister().lastRegister?.text) } @Test @@ -82,10 +82,10 @@ class ReplaceWithRegisterTest : VimTestCase() { configureByText(text) typeText(injector.parser.parseKeys("\"ayiw" + "w" + "\"agriw")) assertState("one two tw${c}o four") - kotlin.test.assertEquals("two", VimPlugin.getRegister().lastRegister?.text) + assertEquals("two", VimPlugin.getRegister().lastRegister?.text) typeText(injector.parser.parseKeys("w" + "griw")) assertState("one two two tw${c}o") - kotlin.test.assertEquals("two", VimPlugin.getRegister().lastRegister?.text) + assertEquals("two", VimPlugin.getRegister().lastRegister?.text) } @Test @@ -95,7 +95,7 @@ class ReplaceWithRegisterTest : VimTestCase() { configureByText(text) typeText(injector.parser.parseKeys("\"+yiw" + "w" + "\"+griw" + "w" + "\"+griw")) assertState("one two two tw${c}o") - kotlin.test.assertEquals("two", VimPlugin.getRegister().lastRegister?.text) + assertEquals("two", VimPlugin.getRegister().lastRegister?.text) } @Test @@ -172,7 +172,7 @@ class ReplaceWithRegisterTest : VimTestCase() { .storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false) typeText(injector.parser.parseKeys("3griw")) assertState("one on${c}e four") - kotlin.test.assertEquals("one", VimPlugin.getRegister().lastRegister?.text) + assertEquals("one", VimPlugin.getRegister().lastRegister?.text) } @VimBehaviorDiffers("one on${c}e on${c}e four") @@ -186,7 +186,7 @@ class ReplaceWithRegisterTest : VimTestCase() { .storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false) typeText(injector.parser.parseKeys("griw")) assertState("one two one four") - kotlin.test.assertEquals("one", VimPlugin.getRegister().lastRegister?.text) + assertEquals("one", VimPlugin.getRegister().lastRegister?.text) } @Test @@ -199,7 +199,7 @@ class ReplaceWithRegisterTest : VimTestCase() { .storeText(vimEditor, vimEditor.primaryCaret(), text rangeOf "one", SelectionType.CHARACTER_WISE, false) typeText(injector.parser.parseKeys("griw" + "w" + ".")) assertState("one one on${c}e four") - kotlin.test.assertEquals("one", VimPlugin.getRegister().lastRegister?.text) + assertEquals("one", VimPlugin.getRegister().lastRegister?.text) } // --------------------------------------- grr -------------------------- @@ -226,7 +226,7 @@ class ReplaceWithRegisterTest : VimTestCase() { Cras id tellus in ex imperdiet egestas. """.trimIndent(), ) - kotlin.test.assertEquals("legendary", VimPlugin.getRegister().lastRegister?.text) + assertEquals("legendary", VimPlugin.getRegister().lastRegister?.text) } @Test @@ -393,7 +393,7 @@ class ReplaceWithRegisterTest : VimTestCase() { Cras id tellus in ex imperdiet egestas. """.trimIndent(), ) - kotlin.test.assertEquals("legendary", VimPlugin.getRegister().lastRegister?.text) + assertEquals("legendary", VimPlugin.getRegister().lastRegister?.text) assertMode(VimStateMachine.Mode.COMMAND) } @@ -494,7 +494,7 @@ class ReplaceWithRegisterTest : VimTestCase() { fun `test multiple carets`() { // Behaviour of pasting a full line with multiple carets is undefined in Vim and has different implementation in // IdeaVim depending on if ideaput is specified in 'clipboard' or not - assertContainsElements(optionsNoEditor().getStringListValues(Options.clipboard), OptionConstants.clipboard_ideaput) + assertContainsElements(optionsNoEditor().clipboard, OptionConstants.clipboard_ideaput) enableExtensions("multiple-cursors") val text = """ diff --git a/src/test/java/org/jetbrains/plugins/ideavim/impl/OptionsVerificator.kt b/src/test/java/org/jetbrains/plugins/ideavim/impl/OptionsVerificator.kt index 375e5094e2..cb23568b06 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/impl/OptionsVerificator.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/impl/OptionsVerificator.kt @@ -12,15 +12,15 @@ import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.fixtures.CodeInsightTestFixture import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl -import com.maddyhome.idea.vim.api.VimEditor -import com.maddyhome.idea.vim.api.VimOptionGroup +import com.maddyhome.idea.vim.api.VimInjector import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.diagnostic.vimLogger +import com.maddyhome.idea.vim.group.IjVimOptionGroup import com.maddyhome.idea.vim.options.NumberOption import com.maddyhome.idea.vim.options.Option import com.maddyhome.idea.vim.options.OptionChangeListener import com.maddyhome.idea.vim.options.OptionScope -import com.maddyhome.idea.vim.options.OptionValueAccessor +import com.maddyhome.idea.vim.options.StringListOption import com.maddyhome.idea.vim.options.StringOption import com.maddyhome.idea.vim.options.ToggleOption import com.maddyhome.idea.vim.options.UnsignedNumberOption @@ -114,6 +114,7 @@ private class OptionsVerificator : BeforeTestExecutionCallback, AfterTestExecuti val testInjector = TestInjector(injector) val traceCollector = OptionsTraceCollector() val ignore = AtomicBoolean(false) + getStore(context).put("OriginalInjector", injector) getStore(context).put("TraceCollector", traceCollector) testInjector.setTracer(OptionsTracer, traceCollector) testInjector.setTracer("OptionTracerIgnore", ignore) @@ -121,6 +122,7 @@ private class OptionsVerificator : BeforeTestExecutionCallback, AfterTestExecuti } override fun afterTestExecution(context: ExtensionContext) { + injector = getStore(context).get("OriginalInjector", VimInjector::class.java) val collector = getStore(context).get("TraceCollector", OptionsTraceCollector::class.java) val usedOptions = collector.requestedKeys .mapNotNull { injector.optionGroup.getOption(it)?.name } @@ -179,10 +181,10 @@ internal class OptionsTraceCollector { } internal class OptionsTracer( - private val vimOptionGroup: VimOptionGroup, + private val vimOptionGroup: IjVimOptionGroup, private val trace: OptionsTraceCollector, private val ignoreFlag: AtomicBoolean, -) : VimOptionGroup by vimOptionGroup { +) : IjVimOptionGroup by vimOptionGroup { override fun getOption(key: String): Option? { if (!ignoreFlag.get()) { trace.requestedKeys += key @@ -223,13 +225,6 @@ internal class OptionsTracer( } } - override fun getValueAccessor(editor: VimEditor?): OptionValueAccessor { - // I don't like this solution. Would love to see something better without re-wrapping. - // The point is that OptionValueAccessor should use our group to be property traced - val accessor = vimOptionGroup.getValueAccessor(editor) - return OptionValueAccessor(this, accessor.scope) - } - companion object } @@ -275,7 +270,7 @@ private class VimOptionsInvocator : TestTemplateInvocationContextProvider { when (option) { is ToggleOption -> vimOption.limitedValues.map { option to if (it == "true") VimInt.ONE else VimInt.ZERO } is NumberOption -> vimOption.limitedValues.map { option to VimInt(it) } - is StringOption -> { + is StringOption, is StringListOption -> { vimOption.limitedValues.map { limitedValue -> option to VimString(limitedValue) } } @@ -308,21 +303,21 @@ private class VimOptionsInvocator : TestTemplateInvocationContextProvider { } is StringOption -> { - if (option.isList) { - val boundedValues = option.boundedValues - if (boundedValues != null) { - val valuesCombinations = boundedValues.indices.map { index -> - kCombinations(boundedValues.toList(), index + 1) - .map { VimString(it.joinToString(",")) } - }.flatten() - valuesCombinations.map { option to it } - } else { - fail("Cannot generate values automatically. Please specify option values explicitly using 'limitedValues' field") - } + val boundedValues = option.boundedValues + boundedValues?.map { option to VimString(it) } + ?: fail("Cannot generate values automatically. Please specify option values explicitly using 'limitedValues' field") + } + + is StringListOption -> { + val boundedValues = option.boundedValues + if (boundedValues != null) { + val valuesCombinations = boundedValues.indices.map { index -> + kCombinations(boundedValues.toList(), index + 1) + .map { VimString(it.joinToString(",")) } + }.flatten() + valuesCombinations.map { option to it } } else { - val boundedValues = option.boundedValues - boundedValues?.map { option to VimString(it) } - ?: fail("Cannot generate values automatically. Please specify option values explicitly using 'limitedValues' field") + fail("Cannot generate values automatically. Please specify option values explicitly using 'limitedValues' field") } } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/impl/TestInjector.kt b/src/test/java/org/jetbrains/plugins/ideavim/impl/TestInjector.kt index 588d5f44d3..d1ffced2f0 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/impl/TestInjector.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/impl/TestInjector.kt @@ -10,6 +10,7 @@ package org.jetbrains.plugins.ideavim.impl import com.maddyhome.idea.vim.api.VimInjector import com.maddyhome.idea.vim.api.VimOptionGroup +import com.maddyhome.idea.vim.group.IjVimOptionGroup import java.util.concurrent.atomic.AtomicBoolean /** @@ -31,7 +32,7 @@ class TestInjector(val injector: VimInjector) : VimInjector by injector { val tracer = tracers[OptionsTracer] as? OptionsTraceCollector return if (tracer != null) { val ignoreFlag = tracers["OptionTracerIgnore"] as AtomicBoolean - OptionsTracer(injector.optionGroup, tracer, ignoreFlag) + OptionsTracer(injector.optionGroup as IjVimOptionGroup, tracer, ignoreFlag) } else { injector.optionGroup } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/option/BoundedStringListOptionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/option/BoundedStringListOptionTest.kt index 1e492669ca..28979e8495 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/option/BoundedStringListOptionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/option/BoundedStringListOptionTest.kt @@ -9,7 +9,9 @@ package org.jetbrains.plugins.ideavim.option import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.options.StringOption +import com.maddyhome.idea.vim.newapi.vim +import com.maddyhome.idea.vim.options.OptionScope +import com.maddyhome.idea.vim.options.StringListOption import org.jetbrains.plugins.ideavim.SkipNeovimReason import org.jetbrains.plugins.ideavim.TestWithoutNeovim import org.jetbrains.plugins.ideavim.VimTestCase @@ -17,15 +19,15 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInfo +import kotlin.test.assertEquals class BoundedStringListOptionTest : VimTestCase() { private val optionName = "myOpt" private val defaultValue = "Monday,Tuesday" - private val option = StringOption( + private val option = StringListOption( optionName, optionName, defaultValue, - true, setOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"), ) @@ -42,11 +44,14 @@ class BoundedStringListOptionTest : VimTestCase() { injector.optionGroup.removeOption(optionName) } + private fun getOptionValue() = + injector.optionGroup.getOptionValue(option, OptionScope.LOCAL(fixture.editor.vim)).value + @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @Test fun `test set valid list`() { enterCommand("set $optionName=Thursday,Friday") - kotlin.test.assertEquals("Thursday,Friday", options().getStringValue(option)) + assertEquals("Thursday,Friday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @@ -55,14 +60,14 @@ class BoundedStringListOptionTest : VimTestCase() { enterCommand("set $optionName=Blue") assertPluginError(true) assertPluginErrorMessageContains("E474: Invalid argument: $optionName") - kotlin.test.assertEquals(defaultValue, options().getStringValue(option)) + assertEquals(defaultValue, getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @Test fun `test append single item`() { enterCommand("set $optionName+=Wednesday") - kotlin.test.assertEquals("Monday,Tuesday,Wednesday", options().getStringValue(option)) + assertEquals("Monday,Tuesday,Wednesday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @@ -71,14 +76,14 @@ class BoundedStringListOptionTest : VimTestCase() { enterCommand("set $optionName+=Blue") assertPluginError(true) assertPluginErrorMessageContains("E474: Invalid argument: $optionName") - kotlin.test.assertEquals("Monday,Tuesday", options().getStringValue(option)) + assertEquals("Monday,Tuesday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @Test fun `test append list`() { enterCommand("set $optionName+=Wednesday,Thursday") - kotlin.test.assertEquals("Monday,Tuesday,Wednesday,Thursday", options().getStringValue(option)) + assertEquals("Monday,Tuesday,Wednesday,Thursday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @@ -87,14 +92,14 @@ class BoundedStringListOptionTest : VimTestCase() { enterCommand("set $optionName+=Wednesday,Blue") assertPluginError(true) assertPluginErrorMessageContains("E474: Invalid argument: $optionName") - kotlin.test.assertEquals("Monday,Tuesday", options().getStringValue(option)) + assertEquals("Monday,Tuesday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @Test fun `test prepend item`() { enterCommand("set $optionName^=Wednesday") - kotlin.test.assertEquals("Wednesday,Monday,Tuesday", options().getStringValue(option)) + assertEquals("Wednesday,Monday,Tuesday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @@ -103,14 +108,14 @@ class BoundedStringListOptionTest : VimTestCase() { enterCommand("set $optionName^=Blue") assertPluginError(true) assertPluginErrorMessageContains("E474: Invalid argument: $optionName") - kotlin.test.assertEquals("Monday,Tuesday", options().getStringValue(option)) + assertEquals("Monday,Tuesday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @Test fun `test prepend list`() { enterCommand("set $optionName^=Wednesday,Thursday") - kotlin.test.assertEquals("Wednesday,Thursday,Monday,Tuesday", options().getStringValue(option)) + assertEquals("Wednesday,Thursday,Monday,Tuesday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @@ -119,31 +124,31 @@ class BoundedStringListOptionTest : VimTestCase() { enterCommand("set $optionName^=Wednesday,Blue") assertPluginError(true) assertPluginErrorMessageContains("E474: Invalid argument: $optionName") - kotlin.test.assertEquals("Monday,Tuesday", options().getStringValue(option)) + assertEquals("Monday,Tuesday", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @Test fun `test remove item`() { enterCommand("set $optionName-=Monday") - kotlin.test.assertEquals("Tuesday", options().getStringValue(option)) + assertEquals("Tuesday", getOptionValue()) } @Test fun `test remove list`() { enterCommand("set $optionName-=Monday,Tuesday") - kotlin.test.assertEquals("", options().getStringValue(option)) + assertEquals("", getOptionValue()) } @Test fun `test remove list with wrong order`() { enterCommand("set $optionName-=Tuesday,Monday") - kotlin.test.assertEquals("Monday,Tuesday", options().getStringValue(option)) + assertEquals("Monday,Tuesday", getOptionValue()) } @Test fun `test remove list with invalid value`() { enterCommand("set $optionName-=Monday,Blue") - kotlin.test.assertEquals("Monday,Tuesday", options().getStringValue(option)) + assertEquals("Monday,Tuesday", getOptionValue()) } } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/option/GuiCursorOptionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/option/GuiCursorOptionTest.kt index 706f4acc6f..9ed6c2591d 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/option/GuiCursorOptionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/option/GuiCursorOptionTest.kt @@ -27,11 +27,10 @@ class GuiCursorOptionTest : VimTestCase() { } private fun getGuiCursorEntries() = - options().getStringListValues(Options.guicursor).map { GuiCursorOptionHelper.convertToken(it) } + options().guicursor.map { GuiCursorOptionHelper.convertToken(it) } private fun assertHasDefaultValue() { - val defaultValue = Options.guicursor.defaultValue.asString() - assertEquals(defaultValue, options().getStringValue(Options.guicursor)) + assertEquals(Options.guicursor.defaultValue.value, options().guicursor.value) } @Suppress("SpellCheckingInspection") diff --git a/src/test/java/org/jetbrains/plugins/ideavim/option/KeywordOptionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/option/KeywordOptionTest.kt index fc7da94acb..44571d6e1a 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/option/KeywordOptionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/option/KeywordOptionTest.kt @@ -8,16 +8,17 @@ package org.jetbrains.plugins.ideavim.option import com.intellij.testFramework.UsefulTestCase.assertDoesntContain -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.helper.CharacterHelper import com.maddyhome.idea.vim.helper.CharacterHelper.charType -import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper.parseValues +import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper.toRegex import org.jetbrains.plugins.ideavim.VimTestCase import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInfo +import kotlin.test.assertEquals import kotlin.test.assertSame +import kotlin.test.assertTrue class KeywordOptionTest : VimTestCase() { @BeforeEach @@ -26,8 +27,8 @@ class KeywordOptionTest : VimTestCase() { configureByText("\n") } - private val values: List? - get() = parseValues(options().getStringValue(Options.iskeyword)) + private val values: List + get() = KeywordOptionHelper.parseValues(options().iskeyword.value)!! private fun setKeyword(value: String) { enterCommand("set iskeyword=$value") @@ -46,44 +47,44 @@ class KeywordOptionTest : VimTestCase() { @Test fun testSingleCommaIsAValue() { setKeyword(",") - kotlin.test.assertEquals(",", values!![0]) + assertEquals(",", values[0]) } @Test fun testSingleCommaIsAValueAsAppend() { enterCommand("set iskeyword^=,") - kotlin.test.assertTrue(values!!.contains(",")) + assertTrue(values.contains(",")) } @Test fun testSingleNegatedCommaIsAValue() { setKeyword("^,") - kotlin.test.assertEquals("^,", values!![0]) + assertEquals("^,", values[0]) } @Test fun testCommaInARangeIsAValue() { setKeyword("+-,") - kotlin.test.assertEquals("+-,", values!![0]) + assertEquals("+-,", values[0]) } @Test fun testSecondCommaIsASeparator() { setKeyword(",,a") - kotlin.test.assertEquals(",", values!![0]) - kotlin.test.assertEquals("a", values!![1]) + assertEquals(",", values[0]) + assertEquals("a", values[1]) } @Test fun testSingleHyphenIsAValue() { setKeyword("-") - kotlin.test.assertEquals("-", values!![0]) + assertEquals("-", values[0]) } @Test fun testHyphenBetweenCharNumsIsARange() { setKeyword("a-b") - kotlin.test.assertEquals("a-b", values!![0]) + assertEquals("a-b", values[0]) } @Test @@ -92,7 +93,7 @@ class KeywordOptionTest : VimTestCase() { assertPluginError(true) assertPluginErrorMessageContains("E474: Invalid argument: iskeyword=b-a") assertDoesntContain( - values!!, + values, object : ArrayList() { init { add("b-a") @@ -107,7 +108,7 @@ class KeywordOptionTest : VimTestCase() { assertPluginError(true) assertPluginErrorMessageContains("E474: Invalid argument: iskeyword=ab") assertDoesntContain( - values!!, + values, object : ArrayList() { init { add("ab") @@ -180,15 +181,15 @@ class KeywordOptionTest : VimTestCase() { fun testToRegex() { setKeyword("-,a-c") val res = toRegex() - kotlin.test.assertEquals(2, res.size) - kotlin.test.assertTrue(res.contains("-")) - kotlin.test.assertTrue(res.contains("[a-c]")) + assertEquals(2, res.size) + assertTrue(res.contains("-")) + assertTrue(res.contains("[a-c]")) } @Test fun testAllLettersToRegex() { setKeyword("@") val res = toRegex() - kotlin.test.assertEquals(res[0], "\\p{L}") + assertEquals(res[0], "\\p{L}") } } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/option/StringListOptionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/option/StringListOptionTest.kt index 174b553a9a..11edc97702 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/option/StringListOptionTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/option/StringListOptionTest.kt @@ -9,7 +9,9 @@ package org.jetbrains.plugins.ideavim.option import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.options.StringOption +import com.maddyhome.idea.vim.newapi.vim +import com.maddyhome.idea.vim.options.OptionScope +import com.maddyhome.idea.vim.options.StringListOption import org.jetbrains.plugins.ideavim.SkipNeovimReason import org.jetbrains.plugins.ideavim.TestWithoutNeovim import org.jetbrains.plugins.ideavim.VimTestCase @@ -17,10 +19,11 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInfo +import kotlin.test.assertEquals class StringListOptionTest : VimTestCase() { private val optionName = "myOpt" - private val option = StringOption(optionName, optionName, "", true, null) + private val option = StringListOption(optionName, optionName, "", null) @BeforeEach override fun setUp(testInfo: TestInfo) { @@ -35,6 +38,9 @@ class StringListOptionTest : VimTestCase() { injector.optionGroup.removeOption(optionName) } + private fun getOptionValue() = + injector.optionGroup.getOptionValue(option, OptionScope.LOCAL(fixture.editor.vim)).value + @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @Test fun `test append existing value`() { @@ -42,7 +48,7 @@ class StringListOptionTest : VimTestCase() { enterCommand("set $optionName+=456") enterCommand("set $optionName+=123") - kotlin.test.assertEquals("123,456", options().getStringValue(option)) + assertEquals("123,456", getOptionValue()) } @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) @@ -52,6 +58,6 @@ class StringListOptionTest : VimTestCase() { enterCommand("set $optionName+=123") enterCommand("set $optionName^=123") - kotlin.test.assertEquals("456,123", options().getStringValue(option)) + assertEquals("456,123", getOptionValue()) } } diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ui/ShowCmdTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ui/ShowCmdTest.kt index 73241b9df6..ba397dd7a3 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/ui/ShowCmdTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/ui/ShowCmdTest.kt @@ -8,7 +8,6 @@ package org.jetbrains.plugins.ideavim.ui -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.helper.VimBehaviorDiffers import com.maddyhome.idea.vim.ui.ShowCmd @@ -20,6 +19,8 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInfo +import kotlin.test.assertEquals +import kotlin.test.assertTrue class ShowCmdTest : VimTestCase() { @BeforeEach @@ -32,7 +33,7 @@ class ShowCmdTest : VimTestCase() { @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd on by default`() { - kotlin.test.assertTrue(options().isSet(Options.showcmd)) + assertTrue(options().showcmd) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @@ -40,42 +41,42 @@ class ShowCmdTest : VimTestCase() { fun `test showcmd shows nothing if disabled`() { enterCommand("set noshowcmd") typeText(injector.parser.parseKeys("3")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd count`() { typeText(injector.parser.parseKeys("3")) - kotlin.test.assertEquals("3", getShowCmdText()) + assertEquals("3", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd multiple count`() { typeText(injector.parser.parseKeys("320")) - kotlin.test.assertEquals("320", getShowCmdText()) + assertEquals("320", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd incomplete command`() { typeText(injector.parser.parseKeys("3d2")) - kotlin.test.assertEquals("3d2", getShowCmdText()) + assertEquals("3d2", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd clears on completed command`() { typeText(injector.parser.parseKeys("3d2w")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd clears on Escape`() { typeText(injector.parser.parseKeys("3d2")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @@ -83,7 +84,7 @@ class ShowCmdTest : VimTestCase() { fun `test showcmd expands mapped keys`() { enterCommand("nmap rrrr d") typeText(injector.parser.parseKeys("32rrrr")) - kotlin.test.assertEquals("32d", getShowCmdText()) + assertEquals("32d", getShowCmdText()) } // TODO: This test fails because IdeaVim's mapping handler doesn't correctly expand unhandled keys on timeout @@ -102,63 +103,63 @@ class ShowCmdTest : VimTestCase() { fun `test showcmd updates count when expanding mapped keys`() { enterCommand("nmap rrrr 55d") typeText(injector.parser.parseKeys("32rrrr")) - kotlin.test.assertEquals("3255d", getShowCmdText()) + assertEquals("3255d", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd removes count on Delete`() { typeText(injector.parser.parseKeys("32")) - kotlin.test.assertEquals("3", getShowCmdText()) + assertEquals("3", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd clears if Delete all count chars`() { typeText(injector.parser.parseKeys("32")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd removes motion count on Delete`() { typeText(injector.parser.parseKeys("32d44")) - kotlin.test.assertEquals("32d", getShowCmdText()) + assertEquals("32d", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd clears if Delete on operator`() { typeText(injector.parser.parseKeys("32d")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd shows nothing in insert mode`() { typeText(injector.parser.parseKeys("i" + "hello world")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd shows digraph entry in insert mode`() { typeText(injector.parser.parseKeys("i" + "O")) - kotlin.test.assertEquals("^KO", getShowCmdText()) + assertEquals("^KO", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd clears when cancelling digraph entry in insert mode`() { typeText(injector.parser.parseKeys("i" + "O" + "")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd shows literal entry in insert mode`() { typeText(injector.parser.parseKeys("i" + "12")) - kotlin.test.assertEquals("^V12", getShowCmdText()) + assertEquals("^V12", getShowCmdText()) } // Vim seems to hard code and swaps it for @@ -167,28 +168,28 @@ class ShowCmdTest : VimTestCase() { @Test fun `test showcmd shows literal entry with CTRL-Q in insert mode`() { typeText(injector.parser.parseKeys("i" + "12")) - kotlin.test.assertEquals("^Q12", getShowCmdText()) + assertEquals("^Q12", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd clears when cancelling literal entry in insert mode`() { typeText(injector.parser.parseKeys("i" + "1" + "")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd shows register entry in insert mode`() { typeText(injector.parser.parseKeys("i" + "")) - kotlin.test.assertEquals("^R", getShowCmdText()) + assertEquals("^R", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd clears when cancelling registry entry in insert mode`() { typeText(injector.parser.parseKeys("i" + "" + "")) - kotlin.test.assertEquals("", getShowCmdText()) + assertEquals("", getShowCmdText()) } // Note that Vim shows the number of lines, or rows x cols for visual mode. We don't because IntelliJ already @@ -197,50 +198,50 @@ class ShowCmdTest : VimTestCase() { @Test fun `test showcmd works in visual mode`() { typeText(injector.parser.parseKeys("v" + "32f")) - kotlin.test.assertEquals("32f", getShowCmdText()) + assertEquals("32f", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd works in single command mode`() { typeText(injector.parser.parseKeys("i" + "" + "32f")) - kotlin.test.assertEquals("32f", getShowCmdText()) + assertEquals("32f", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd only shows last 10 characters of buffer`() { typeText(injector.parser.parseKeys("12345678900987654321")) - kotlin.test.assertEquals("0987654321", getShowCmdText()) + assertEquals("0987654321", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd tooltip shows full buffer`() { typeText(injector.parser.parseKeys("12345678900987654321")) - kotlin.test.assertEquals("12345678900987654321", getShowCmdTooltipText()) + assertEquals("12345678900987654321", getShowCmdTooltipText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd shows select register command`() { typeText(injector.parser.parseKeys("\"a32d")) - kotlin.test.assertEquals("\"a32d", getShowCmdText()) + assertEquals("\"a32d", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd shows count and select register command`() { typeText(injector.parser.parseKeys("32\"ad")) - kotlin.test.assertEquals("32\"ad", getShowCmdText()) + assertEquals("32\"ad", getShowCmdText()) } @TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD) @Test fun `test showcmd shows repeated select register with counts`() { typeText(injector.parser.parseKeys("22\"a22\"a22\"a22\"a22d22")) - kotlin.test.assertEquals("a22\"a22d22", getShowCmdText()) - kotlin.test.assertEquals("22\"a22\"a22\"a22\"a22d22", getShowCmdTooltipText()) + assertEquals("a22\"a22d22", getShowCmdText()) + assertEquals("22\"a22\"a22\"a22\"a22d22", getShowCmdTooltipText()) } private fun getShowCmdText() = ShowCmd.getWidgetText(fixture.editor!!) diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt index 7d5be38b11..bf1186a9bd 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/KeyHandler.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimActionsInitiator import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.globalOptions @@ -88,7 +87,7 @@ public class KeyHandler { Key: $key """.trimIndent() } - val maxMapDepth = injector.globalOptions().getIntValue(Options.maxmapdepth) + val maxMapDepth = injector.globalOptions().maxmapdepth if (handleKeyRecursionCount >= maxMapDepth) { injector.messages.showStatusBarMessage(editor, injector.messages.message("E223")) injector.messages.indicateError() diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowLeftAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowLeftAction.kt index 710518044c..a1b7b71d63 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowLeftAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowLeftAction.kt @@ -11,7 +11,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.action.ComplicatedKeysAction import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -36,7 +35,7 @@ public class MotionArrowLeftAction : NonShiftedSpecialKeyHandler(), ComplicatedK argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, "<") + val allowWrap = injector.options(editor).whichwrap.contains("<") val allowEnd = operatorArguments.isOperatorPending // d deletes \n with wrap enabled return injector.motion.getHorizontalMotion(editor, caret, -operatorArguments.count1, allowEnd, allowWrap) } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowRightAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowRightAction.kt index 66e91ea8ca..6a743e2a13 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowRightAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionArrowRightAction.kt @@ -11,7 +11,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.action.ComplicatedKeysAction import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -42,7 +41,7 @@ public class MotionArrowRightAction : NonShiftedSpecialKeyHandler(), Complicated ): Motion { val allowPastEnd = usesVirtualSpace || editor.isEndAllowed || operatorArguments.isOperatorPending // because of `d` removing the last character - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, ">") + val allowWrap = injector.options(editor).whichwrap.contains(">") return injector.motion.getHorizontalMotion(editor, caret, operatorArguments.count1, allowPastEnd, allowWrap) } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionBackspaceAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionBackspaceAction.kt index a1477059da..0040a43ba3 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionBackspaceAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionBackspaceAction.kt @@ -9,7 +9,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -27,7 +26,7 @@ public class MotionBackspaceAction : MotionActionHandler.ForEachCaret() { argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, "b") + val allowWrap = injector.options(editor).whichwrap.contains("b") return injector.motion.getHorizontalMotion(editor, caret, -operatorArguments.count1, allowPastEnd = false, allowWrap) } @@ -42,7 +41,7 @@ public class MotionSpaceAction : MotionActionHandler.ForEachCaret() { argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, "s") + val allowWrap = injector.options(editor).whichwrap.contains("s") return injector.motion.getHorizontalMotion(editor, caret, operatorArguments.count1, allowPastEnd = false, allowWrap) } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionEndAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionEndAction.kt index 33f5c63901..e2a7d83342 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionEndAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionEndAction.kt @@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimMotionGroupBase import com.maddyhome.idea.vim.api.injector @@ -38,7 +37,7 @@ public class MotionEndAction : NonShiftedSpecialKeyHandler() { if (editor.inInsertMode) { allow = true } else if (editor.inVisualMode || editor.inSelectMode) { - allow = !injector.options(editor).hasValue(Options.selection, "old") + allow = injector.options(editor).selection != "old" } val offset = injector.motion.moveCaretToRelativeLineEnd(editor, caret, operatorArguments.count1 - 1, allow) diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastColumnAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastColumnAction.kt index 36f69a0f40..3caaac53ee 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastColumnAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastColumnAction.kt @@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimMotionGroupBase import com.maddyhome.idea.vim.api.injector @@ -41,7 +40,7 @@ public open class MotionLastColumnAction : MotionActionHandler.ForEachCaret() { operatorArguments: OperatorArguments, ): Motion { val allow = if (editor.inVisualMode) { - !injector.options(editor).hasValue(Options.selection, "old") + injector.options(editor).selection != "old" } else { if (operatorArguments.isOperatorPending) false else editor.isEndAllowed } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastScreenColumnAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastScreenColumnAction.kt index ae0f9fd3ef..9102ba4c71 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastScreenColumnAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLastScreenColumnAction.kt @@ -9,7 +9,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimMotionGroupBase import com.maddyhome.idea.vim.api.injector @@ -34,7 +33,7 @@ public class MotionLastScreenColumnAction : MotionActionHandler.ForEachCaret() { if (editor.inInsertMode) { allow = true } else if (editor.inVisualMode) { - allow = !injector.options(editor).hasValue(Options.selection, "old") + allow = injector.options(editor).selection != "old" } val motion = injector.motion.moveCaretToCurrentDisplayLineEnd(editor, caret, allow) return when (motion) { diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLeftAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLeftAction.kt index f2a55059c7..dca7405f4a 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLeftAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionLeftAction.kt @@ -11,7 +11,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.action.ComplicatedKeysAction import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -33,7 +32,7 @@ public class MotionLeftAction : MotionActionHandler.ForEachCaret() { argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, "h") + val allowWrap = injector.options(editor).whichwrap.contains("h") val allowEnd = operatorArguments.isOperatorPending // dh deletes \n with wrap enabled return injector.motion.getHorizontalMotion(editor, caret, -operatorArguments.count1, allowEnd, allowWrap) } @@ -54,7 +53,7 @@ public class MotionLeftInsertModeAction : MotionActionHandler.ForEachCaret(), Co argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, "[") + val allowWrap = injector.options(editor).whichwrap.contains("[") return injector.motion.getHorizontalMotion(editor, caret, -operatorArguments.count1, true, allowWrap) } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionRightAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionRightAction.kt index 6ef6d0851c..6d1d55d74d 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionRightAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionRightAction.kt @@ -11,7 +11,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.action.ComplicatedKeysAction import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -35,7 +34,7 @@ public class MotionRightAction : MotionActionHandler.ForEachCaret() { argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, "l") + val allowWrap = injector.options(editor).whichwrap.contains("l") val allowEnd = usesVirtualSpace || editor.isEndAllowed || operatorArguments.isOperatorPending // because of `dl` removing the last character return injector.motion.getHorizontalMotion(editor, caret, operatorArguments.count1, allowPastEnd = allowEnd, allowWrap) @@ -57,7 +56,7 @@ public class MotionRightInsertAction : MotionActionHandler.ForEachCaret(), Compl argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val allowWrap = injector.options(editor).hasValue(Options.whichwrap, "]") + val allowWrap = injector.options(editor).whichwrap.contains("]") return injector.motion.getHorizontalMotion(editor, caret, operatorArguments.count1, allowPastEnd = true, allowWrap) } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionShiftEndAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionShiftEndAction.kt index d3e3da5ec6..23928e79b2 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionShiftEndAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/leftright/MotionShiftEndAction.kt @@ -9,7 +9,6 @@ package com.maddyhome.idea.vim.action.motion.leftright import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimCaret import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimMotionGroupBase @@ -30,7 +29,7 @@ public class MotionShiftEndAction : ShiftedSpecialKeyHandler() { if (editor.inInsertMode) { allow = true } else if (editor.inVisualMode || editor.inSelectMode) { - allow = !injector.options(editor).hasValue(Options.selection, "old") + allow = injector.options(editor).selection != "old" } val newOffset = injector.motion.moveCaretToRelativeLineEnd(editor, caret, cmd.count - 1, allow) diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionLeftAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionLeftAction.kt index b2c5fc8ca3..d6540b6f72 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionLeftAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionLeftAction.kt @@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.action.motion.select.motion import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector @@ -37,7 +36,7 @@ public class SelectMotionLeftAction : MotionActionHandler.ForEachCaret() { argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val keymodel = injector.globalOptions().getStringListValues(Options.keymodel) + val keymodel = injector.globalOptions().keymodel if (OptionConstants.keymodel_stopsel in keymodel || OptionConstants.keymodel_stopselect in keymodel) { logger.debug("Keymodel option has stopselect. Exiting select mode") val startSelection = caret.selectionStart diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionRightAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionRightAction.kt index b942fb9986..17136bf9ac 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionRightAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/select/motion/SelectMotionRightAction.kt @@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.action.motion.select.motion import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector @@ -37,7 +36,7 @@ public class SelectMotionRightAction : MotionActionHandler.ForEachCaret() { argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val keymodel = injector.globalOptions().getStringListValues(Options.keymodel) + val keymodel = injector.globalOptions().keymodel if (OptionConstants.keymodel_stopsel in keymodel || OptionConstants.keymodel_stopselect in keymodel) { logger.debug("Keymodel option has stopselect. Exiting select mode") val startSelection = caret.selectionStart diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/updown/MotionGotoLineLastEndAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/updown/MotionGotoLineLastEndAction.kt index a3bc05f691..8dd5a49803 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/updown/MotionGotoLineLastEndAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/updown/MotionGotoLineLastEndAction.kt @@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.action.motion.updown import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.normalizeLine @@ -43,7 +42,7 @@ public class MotionGotoLineLastEndAction : MotionActionHandler.ForEachCaret() { if (editor.inInsertMode) { allow = true } else if (editor.inVisualMode) { - allow = !injector.options(editor).hasValue(Options.selection, "old") + allow = injector.options(editor).selection != "old" } return moveCaretGotoLineLastEnd(editor, operatorArguments.count0, operatorArguments.count1 - 1, allow).toMotion() @@ -66,7 +65,7 @@ public class MotionGotoLineLastEndInsertAction : MotionActionHandler.ForEachCare if (editor.inInsertMode) { allow = true } else if (editor.inVisualMode) { - allow = !injector.options(editor).hasValue(Options.selection, "old") + allow = injector.options(editor).selection != "old" } return moveCaretGotoLineLastEnd(editor, operatorArguments.count0, operatorArguments.count1 - 1, allow).toMotion() diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleBlockModeAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleBlockModeAction.kt index c2f582c0a3..6f01f980dd 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleBlockModeAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleBlockModeAction.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.action.motion.visual import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -27,7 +26,7 @@ public class VisualToggleBlockModeAction : VimActionHandler.SingleExecution() { cmd: Command, operatorArguments: OperatorArguments, ): Boolean { - return if (injector.options(editor).hasValue(Options.selectmode, OptionConstants.selectmode_cmd)) { + return if (injector.options(editor).selectmode.contains(OptionConstants.selectmode_cmd)) { injector.visualMotionGroup.enterSelectMode(editor, VimStateMachine.SubMode.VISUAL_BLOCK) } else { injector.visualMotionGroup diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleCharacterModeAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleCharacterModeAction.kt index 21894316c2..1fbb0d564e 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleCharacterModeAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleCharacterModeAction.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.action.motion.visual import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -27,7 +26,7 @@ public class VisualToggleCharacterModeAction : VimActionHandler.SingleExecution( cmd: Command, operatorArguments: OperatorArguments, ): Boolean { - return if (injector.options(editor).hasValue(Options.selectmode, OptionConstants.selectmode_cmd)) { + return if (injector.options(editor).selectmode.contains(OptionConstants.selectmode_cmd)) { injector.visualMotionGroup.enterSelectMode(editor, VimStateMachine.SubMode.VISUAL_CHARACTER) } else { injector.visualMotionGroup diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleLineModeAction.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleLineModeAction.kt index 330b19bafa..b46c312a3d 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleLineModeAction.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/motion/visual/VisualToggleLineModeAction.kt @@ -9,7 +9,6 @@ package com.maddyhome.idea.vim.action.motion.visual import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimCaret import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector @@ -30,7 +29,7 @@ public class VisualToggleLineModeAction : VimActionHandler.ConditionalMulticaret cmd: Command, operatorArguments: OperatorArguments, ): Boolean { - return if (injector.options(editor).hasValue(Options.selectmode, OptionConstants.selectmode_cmd)) { + return if (injector.options(editor).selectmode.contains(OptionConstants.selectmode_cmd)) { injector.visualMotionGroup.enterSelectMode(editor, VimStateMachine.SubMode.VISUAL_LINE) true } else { diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/OptionProperties.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/OptionProperties.kt new file mode 100644 index 0000000000..10dc77c7a0 --- /dev/null +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/OptionProperties.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2003-2023 The IdeaVim authors + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE.txt file or at + * https://opensource.org/licenses/MIT. + */ + +package com.maddyhome.idea.vim.api + +import com.maddyhome.idea.vim.options.OptionScope + +/** + * An accessor class for global options + * + * This class provides access to options that only have a global value, and do not have a separate value local to a + * buffer (document) or window (editor). + */ +@Suppress("unused", "SpellCheckingInspection") +public open class GlobalOptions(scope: OptionScope = OptionScope.GLOBAL): OptionsPropertiesBase(scope) { + public val clipboard: StringListOptionValue by optionProperty(Options.clipboard) + public var digraph: Boolean by optionProperty(Options.digraph) + public var gdefault: Boolean by optionProperty(Options.gdefault) + public val guicursor: StringListOptionValue by optionProperty(Options.guicursor) + public var history: Int by optionProperty(Options.history) + public var hlsearch: Boolean by optionProperty(Options.hlsearch) + public var ignorecase: Boolean by optionProperty(Options.ignorecase) + public var incsearch: Boolean by optionProperty(Options.incsearch) + public val keymodel: StringListOptionValue by optionProperty(Options.keymodel) + public var maxmapdepth: Int by optionProperty(Options.maxmapdepth) + public var more: Boolean by optionProperty(Options.more) + public var scrolljump: Int by optionProperty(Options.scrolljump) + public var selection: String by optionProperty(Options.selection) + public val selectmode: StringListOptionValue by optionProperty(Options.selectmode) + public var shell: String by optionProperty(Options.shell) + public var shellcmdflag: String by optionProperty(Options.shellcmdflag) + public var shellxescape: String by optionProperty(Options.shellxescape) + public var shellxquote: String by optionProperty(Options.shellxquote) + public var showcmd: Boolean by optionProperty(Options.showcmd) + public var showmode: Boolean by optionProperty(Options.showmode) + public var sidescroll: Int by optionProperty(Options.sidescroll) + public var smartcase: Boolean by optionProperty(Options.smartcase) + public var startofline: Boolean by optionProperty(Options.startofline) + public val timeout: Boolean by optionProperty(Options.timeout) + public var timeoutlen: Int by optionProperty(Options.timeoutlen) + public val viminfo: StringListOptionValue by optionProperty(Options.viminfo) + public var visualbell: Boolean by optionProperty(Options.visualbell) + public val whichwrap: StringListOptionValue by optionProperty(Options.whichwrap) + public var wrapscan: Boolean by optionProperty(Options.wrapscan) + + // TODO: Make these options local + public val iskeyword: StringListOptionValue by optionProperty(Options.iskeyword) + public val matchpairs: StringListOptionValue by optionProperty(Options.matchpairs) + public val virtualedit: StringListOptionValue by optionProperty(Options.virtualedit) + + // IdeaVim specific options. Put any editor or IDE specific options in IjVimOptionService + public var ideaglobalmode: Boolean by optionProperty(Options.ideaglobalmode) + public var ideastrictmode: Boolean by optionProperty(Options.ideastrictmode) + public var ideatracetime: Boolean by optionProperty(Options.ideatracetime) +} + +/** + * An accessor class for the values of options in effect for the given scope + * + * As a convenience, this class can also access the global options that are effective in the given scope. The values + * will be the same as in the global scope. + */ +@Suppress("unused") +public open class EffectiveOptions(scope: OptionScope.LOCAL): GlobalOptions(scope) { +// public val iskeyword: StringListOptionValue by optionProperty(Options.iskeyword) +// public val matchpairs: StringListOptionValue by optionProperty(Options.matchpairs) + public val nrformats: StringListOptionValue by optionProperty(Options.nrformats) + public var number: Boolean by optionProperty(Options.number) + public var relativenumber: Boolean by optionProperty(Options.relativenumber) + public var scroll: Int by optionProperty(Options.scroll) + public var scrolloff: Int by optionProperty(Options.scrolloff) + public var sidescrolloff: Int by optionProperty(Options.sidescrolloff) + public var undolevels: Int by optionProperty(Options.undolevels) +// public val virtualedit: StringListOptionValue by optionProperty(Options.virtualedit) +} diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/Options.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/Options.kt index 4edb2257d4..75911fc0d5 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/Options.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/Options.kt @@ -15,6 +15,7 @@ import com.maddyhome.idea.vim.options.NumberOption import com.maddyhome.idea.vim.options.Option import com.maddyhome.idea.vim.options.OptionConstants import com.maddyhome.idea.vim.options.OptionScope +import com.maddyhome.idea.vim.options.StringListOption import com.maddyhome.idea.vim.options.StringOption import com.maddyhome.idea.vim.options.ToggleOption import com.maddyhome.idea.vim.options.UnsignedNumberOption @@ -67,37 +68,64 @@ public object Options { option.overrideDefaultValue(newDefaultValue) } + /* + * Option declarations + * + * Options are declared as strongly typed public properties. The GlobalOptions and EffectiveOptions classes provide + * strongly typed properties that make it easy to get/set option values from code using native types. + * A small note on history: Options were originally declared as simple strongly typed properties that wrapped a single + * global value. This was refactored into a name-based API with the introduction of global and local values (as + * required by scripting). The downside to this approach was that it naturally became loosely typed, and consuming + * code was required to upcast option values to the expected type before use. Reintroducing strongly typed properties + * allows us to build a strongly typed accessor API that makes it easy to get/set option values. We'd like to avoid + * such API churn in the future of options, if possible. + * + * To add an option: + * * Add a new public property below, sorted alphabetically. Note that the options are grouped into simple + * declarations, typically one-liners, followed by options with more complex splitting or validation logic, and then + * followed by IdeaVim specific (but implementation agnostic) options + * * The property should be named the same as the Vim option. Add the name to the ideavim.dic dictionary to avoid + * spelling inspections in ~/.ideavimrc + * * If the option is to be accessed from Java, add @JvmField. This is usually only required for adding a change + * listener, and should probably be avoided (or migrated to Kotlin) + * * Create an instance of the option type, wrapped in a call to addOption. Do not forget to call addOption! + * If the option requires additional validation or custom splitting, derive from one of the option types and + * implement inline + * * Add a public var delegated property in GlobalOptions (for global options) or EffectiveOptions (for options that + * are local-to-buffer, local-to-window or global-local). The delegated property will handle getting and setting the + * option value, as a native type, at the correct scope + * * Add tests :) + */ + // Simple options, sorted by name - // Note that we expose options as strongly typed properties to make it easier to consume them. The VimOptionGroup API - // will return strongly typed VimDataType derived instances if given a strongly typed option, but fetching by name - // loses that type information, and we also have to check that the option is not null, even if we know it exists. - // types public val digraph: ToggleOption = addOption(ToggleOption("digraph", "dg", false)) - @JvmField public val gdefault: ToggleOption = addOption(ToggleOption("gdefault", "gd", false)) + public val gdefault: ToggleOption = addOption(ToggleOption("gdefault", "gd", false)) public val history: UnsignedNumberOption = addOption(UnsignedNumberOption("history", "hi", 50)) @JvmField public val hlsearch: ToggleOption = addOption(ToggleOption("hlsearch", "hls", false)) @JvmField public val ignorecase: ToggleOption = addOption(ToggleOption("ignorecase", "ic", false)) - @JvmField public val incsearch: ToggleOption = addOption(ToggleOption("incsearch", "is", false)) - public val keymodel: StringOption = addOption(StringOption( - "keymodel", - "km", - "${OptionConstants.keymodel_continueselect},${OptionConstants.keymodel_stopselect}", - isList = true, - setOf( - OptionConstants.keymodel_startsel, - OptionConstants.keymodel_stopsel, - OptionConstants.keymodel_stopselect, - OptionConstants.keymodel_stopvisual, - OptionConstants.keymodel_continueselect, - OptionConstants.keymodel_continuevisual + public val incsearch: ToggleOption = addOption(ToggleOption("incsearch", "is", false)) + public val keymodel: StringListOption = addOption( + StringListOption( + "keymodel", + "km", + "${OptionConstants.keymodel_continueselect},${OptionConstants.keymodel_stopselect}", + setOf( + OptionConstants.keymodel_startsel, + OptionConstants.keymodel_stopsel, + OptionConstants.keymodel_stopselect, + OptionConstants.keymodel_stopvisual, + OptionConstants.keymodel_continueselect, + OptionConstants.keymodel_continuevisual + ) ) - )) + ) public val maxmapdepth: NumberOption = addOption(NumberOption("maxmapdepth", "mmd", 20)) - @JvmField public val more: ToggleOption = addOption(ToggleOption("more", "more", true)) - @JvmField public val nrformats: StringOption = - addOption(StringOption("nrformats", "nf", "hex", isList = true, setOf("octal", "hex", "alpha"))) - @JvmField public val number: ToggleOption = addOption(ToggleOption("number", "nu", false)) - @JvmField public val relativenumber: ToggleOption = addOption(ToggleOption("relativenumber", "rnu", false)) + public val more: ToggleOption = addOption(ToggleOption("more", "more", true)) + public val nrformats: StringListOption = addOption( + StringListOption("nrformats", "nf", "hex", setOf("octal", "hex", "alpha")) + ) + public val number: ToggleOption = addOption(ToggleOption("number", "nu", false)) + public val relativenumber: ToggleOption = addOption(ToggleOption("relativenumber", "rnu", false)) public val scroll: NumberOption = addOption(NumberOption("scroll", "scr", 0)) public val scrolloff: NumberOption = addOption(NumberOption("scrolloff", "so", 0)) public val selection: StringOption = addOption( @@ -105,13 +133,12 @@ public object Options { "selection", "sel", "inclusive", - isList = false, setOf("old", "inclusive", "exclusive") ) ) - public val selectmode: StringOption = addOption( - StringOption( - "selectmode", "slm", "", isList = true, + public val selectmode: StringListOption = addOption( + StringListOption( + "selectmode", "slm", "", setOf( OptionConstants.selectmode_mouse, OptionConstants.selectmode_key, @@ -120,19 +147,18 @@ public object Options { ) ) ) - @JvmField public val shell: StringOption = addOption( + public val shell: StringOption = addOption( StringOption( "shell", "sh", if (injector.systemInfoService.isWindows) "cmd.exe" else System.getenv("SHELL") ?: "sh" ) ) - @JvmField public val shellxescape: StringOption = addOption( + public val shellxescape: StringOption = addOption( StringOption( "shellxescape", "sxe", - if (injector.systemInfoService.isWindows) "\"&|<>()@^" else "", - isList = false + if (injector.systemInfoService.isWindows) "\"&|<>()@^" else "" ) ) public val showcmd: ToggleOption = addOption(ToggleOption("showcmd", "sc", true)) @@ -144,40 +170,36 @@ public object Options { public val timeout: ToggleOption = addOption(ToggleOption("timeout", "to", true)) public val timeoutlen: UnsignedNumberOption = addOption(UnsignedNumberOption("timeoutlen", "tm", 1000)) public val undolevels: UnsignedNumberOption = addOption(UnsignedNumberOption("undolevels", "ul", 1000)) - @JvmField public val viminfo: StringOption = addOption(StringOption("viminfo", "vi", "'100,<50,s10,h", isList = true)) - public val virtualedit: StringOption = addOption( - StringOption( + public val viminfo: StringListOption = addOption(StringListOption("viminfo", "vi", "'100,<50,s10,h")) + public val virtualedit: StringListOption = addOption( + StringListOption( "virtualedit", "ve", "", - isList = false, setOf("onemore", "block", "insert", "all") ) ) public val visualbell: ToggleOption = addOption(ToggleOption("visualbell", "vb", false)) - @JvmField public val whichwrap: StringOption = addOption( - StringOption( + public val whichwrap: StringListOption = addOption( + StringListOption( "whichwrap", "ww", "b,s", - true, setOf("b", "s", "h", "l", "<", ">", "~", "[", "]") ) ) - @JvmField public val wrapscan: ToggleOption = addOption(ToggleOption("wrapscan", "ws", true)) + public val wrapscan: ToggleOption = addOption(ToggleOption("wrapscan", "ws", true)) // More complex options, with additional validation, etc. - public val guicursor: StringOption = addOption(object : StringOption( + public val guicursor: StringListOption = addOption(object : StringListOption( "guicursor", "gcr", "n-v-c:block-Cursor/lCursor," + "ve:ver35-Cursor," + "o:hor50-Cursor," + "i-ci:ver25-Cursor/lCursor," + "r-cr:hor20-Cursor/lCursor," + - "sm:block-Cursor-blinkwait175-blinkoff150-blinkon175", - isList = true - ) { + "sm:block-Cursor-blinkwait175-blinkoff150-blinkon175") { override fun checkIfValueValid(value: VimDataType, token: String) { super.checkIfValueValid(value, token) val valueAsString = (value as VimString).value @@ -185,7 +207,7 @@ public object Options { } }) - public val iskeyword: StringOption = addOption(object : StringOption("iskeyword", "isk", "@,48-57,_", isList = true) { + public val iskeyword: StringListOption = addOption(object : StringListOption("iskeyword", "isk", "@,48-57,_") { override fun checkIfValueValid(value: VimDataType, token: String) { super.checkIfValueValid(value, token) if (KeywordOptionHelper.isValueInvalid((value as VimString).value)) { @@ -204,8 +226,7 @@ public object Options { } }) - @JvmField - public val matchpairs: StringOption = addOption(object : StringOption("matchpairs", "mps", "(:),{:},[:]", isList = true) { + @JvmField public val matchpairs: StringListOption = addOption(object : StringListOption("matchpairs", "mps", "(:),{:},[:]") { override fun checkIfValueValid(value: VimDataType, token: String) { super.checkIfValueValid(value, token) for (v in split((value as VimString).value)) { @@ -225,7 +246,6 @@ public object Options { } }) - @JvmField public val shellcmdflag: StringOption = addOption(object : StringOption("shellcmdflag", "shcf", "") { override val defaultValue: VimString get() { @@ -241,7 +261,6 @@ public object Options { } }) - @JvmField public val shellxquote: StringOption = addOption(object : StringOption("shellxquote", "sxq", "") { override val defaultValue: VimString get() { @@ -259,14 +278,8 @@ public object Options { // Note that IntelliJ overrides clipboard's default value to include the `ideaput` option. // TODO: Technically, we should validate values, but that requires handling exclude, which is irrelevant to us - public val clipboard: StringOption = addOption( - StringOption( - "clipboard", - "cb", - "autoselect,exclude:cons\\|linux", - isList = true - ) - ) + public val clipboard: StringListOption = + addOption(StringListOption("clipboard", "cb", "autoselect,exclude:cons\\|linux")) // IdeaVim specific options. Put any editor or IDE specific options in IjVimOptionService public val ideaglobalmode: ToggleOption = addOption(ToggleOption("ideaglobalmode", "ideaglobalmode", false)) diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/OptionsPropertiesBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/OptionsPropertiesBase.kt new file mode 100644 index 0000000000..f225d2d968 --- /dev/null +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/OptionsPropertiesBase.kt @@ -0,0 +1,152 @@ +/* + * Copyright 2003-2023 The IdeaVim authors + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE.txt file or at + * https://opensource.org/licenses/MIT. + */ + +package com.maddyhome.idea.vim.api + +import com.maddyhome.idea.vim.options.NumberOption +import com.maddyhome.idea.vim.options.Option +import com.maddyhome.idea.vim.options.OptionScope +import com.maddyhome.idea.vim.options.StringListOption +import com.maddyhome.idea.vim.options.StringOption +import com.maddyhome.idea.vim.options.ToggleOption +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.asVimInt +import kotlin.properties.ReadOnlyProperty +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + +/** + * Base class to provide mechanisms to delegate properties to get/set option values + */ +public abstract class OptionsPropertiesBase(private val scope: OptionScope = OptionScope.GLOBAL) { + /** + * Provide a delegate property to get/set boolean option values + */ + private inner class ToggleOptionProperty(private val option: ToggleOption) : + ReadWriteProperty { + + override fun getValue(thisRef: OptionsPropertiesBase, property: KProperty<*>) = getOptionValue(option).asBoolean() + override fun setValue(thisRef: OptionsPropertiesBase, property: KProperty<*>, value: Boolean) = + setOptionValue(option, value.asVimInt()) + } + + /** + * Provide a delegate property to get/set int option values + */ + private inner class NumberOptionProperty(private val option: NumberOption) : + ReadWriteProperty { + + override fun getValue(thisRef: OptionsPropertiesBase, property: KProperty<*>) = getOptionValue(option).value + override fun setValue(thisRef: OptionsPropertiesBase, property: KProperty<*>, value: Int) = + setOptionValue(option, VimInt(value)) + } + + /** + * Provide a delegate property to get/set string option values + */ + private inner class StringOptionProperty(private val option: StringOption) : + ReadWriteProperty { + + override fun getValue(thisRef: OptionsPropertiesBase, property: KProperty<*>) = getOptionValue(option).value + override fun setValue(thisRef: OptionsPropertiesBase, property: KProperty<*>, value: String) = + setOptionValue(option, VimString(value)) + } + + /** + * Provide a delegate property to get, query and modify string list options + * + * Note that this is a read only property delegate. It does not return a plain string, but a [StringListOptionValue] + * which has functions to append or remove values, as well as check for the existence of a value. + */ + private inner class StringListOptionProperty(private val option: StringListOption) : + ReadOnlyProperty { + + override fun getValue(thisRef: OptionsPropertiesBase, property: KProperty<*>) = + StringListOptionValue(option, scope) + } + + private fun getOptionValue(option: Option) = + injector.optionGroup.getOptionValue(option, scope) + + private fun setOptionValue(option: Option, value: T) = + injector.optionGroup.setOptionValue(option, scope, value) + + // Note that if StringOption and StringListOption were combined, we'd lose the simple overloaded API here, and we'd + // have to create delegated properties directly: + // val foo: String by optionProperty(myStringOption) + // val bar: StringListOptionValue by optionProperty(myStringListOption) + // vs + // val foo: String = StringOptionProperty(myStringOption, scope) + // val bar: StringListOptionValue = StringListOptionProperty(myStringListOption, scope) + // This is arguably simpler, and StringListOption gives us more type safety about using a string vs a list + protected fun optionProperty(option: ToggleOption): ReadWriteProperty = + ToggleOptionProperty(option) + protected fun optionProperty(option: NumberOption): ReadWriteProperty = + NumberOptionProperty(option) + protected fun optionProperty(option: StringOption): ReadWriteProperty = + StringOptionProperty(option) + protected fun optionProperty(option: StringListOption): ReadOnlyProperty = + StringListOptionProperty(option) +} + +/** + * Provides a class to work with a string list option + * + * It provides functions to modify the list as well as get the actual string value. It also implements `List`, + * so can be iterated, and [List.contains] can be used to check for existence of an item. + * + * Note that this class should be short-lived and not cached. It assumes the underlying option value is not changed + * except via its own methods! + */ +public class StringListOptionValue( + private val option: StringListOption, + private val scope: OptionScope +) : AbstractList() { + + // We cache the value at creation time, and update whenever it's changed via one of its own methods. We lazily fetch + // and cache the string list. This class does not expect the value to be changed behind its back! + private var currentValue: VimString = injector.optionGroup.getOptionValue(option, scope) + private var stringListValues: List? = null + + public val value: String + get() = currentValue.value + + public fun appendValue(value: String) { + val parsedValue = option.parseValue(value, value) + val newValue = option.appendValue(currentValue, parsedValue) + injector.optionGroup.setOptionValue(option, scope, newValue) + currentValue = newValue + stringListValues = null + } + + public fun prependValue(value: String) { + val parsedValue = option.parseValue(value, value) + val newValue = option.prependValue(currentValue, parsedValue) + injector.optionGroup.setOptionValue(option, scope, newValue) + currentValue = newValue + stringListValues = null + } + + public fun removeValue(value: String) { + val parsedValue = option.parseValue(value, value) + val newValue = option.removeValue(currentValue, parsedValue) + injector.optionGroup.setOptionValue(option, scope, newValue) + currentValue = newValue + stringListValues = null + } + + override val size: Int + get() = getStringListValues().size + + override fun get(index: Int): String = getStringListValues()[index] + + private fun getStringListValues() = + stringListValues ?: injector.optionGroup.getStringListValues(option, scope).also { stringListValues = it } +} diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt index 49d635a28e..90136c5bb7 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt @@ -947,7 +947,7 @@ public abstract class VimChangeGroupBase : VimChangeGroup { var endOffset = range.endOffset val fileSize = editor.fileSize().toInt() if (endOffset > fileSize) { - check(!injector.globalOptions().isSet(Options.ideastrictmode)) { + check(!injector.globalOptions().ideastrictmode) { "Incorrect offset. File size: $fileSize, offset: $endOffset" } endOffset = fileSize diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimInjector.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimInjector.kt index 1d093552f4..dfc732e92f 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimInjector.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimInjector.kt @@ -15,7 +15,6 @@ import com.maddyhome.idea.vim.group.VimWindowGroup import com.maddyhome.idea.vim.helper.VimCommandLineHelper import com.maddyhome.idea.vim.history.VimHistory import com.maddyhome.idea.vim.macro.VimMacro -import com.maddyhome.idea.vim.options.OptionValueAccessor import com.maddyhome.idea.vim.put.VimPut import com.maddyhome.idea.vim.register.VimRegisterGroup import com.maddyhome.idea.vim.undo.VimUndoRedo @@ -195,7 +194,7 @@ public lateinit var injector: VimInjector * [VimInjector.options] and pass in a [VimEditor] for context. This will return local or global public values as * appropriate. */ -public fun VimInjector.globalOptions(): OptionValueAccessor = this.optionGroup.getValueAccessor(null) +public fun VimInjector.globalOptions(): GlobalOptions = this.optionGroup.getGlobalOptions() /** * Gets an API for consuming all options @@ -205,4 +204,4 @@ public fun VimInjector.globalOptions(): OptionValueAccessor = this.optionGroup.g * If an editor isn't available to the calling code, the [globalOptions] function can be used to access global * options. It should not be used to access options that are local to buffer, local to window or global-local. */ -public fun VimInjector.options(editor: VimEditor): OptionValueAccessor = this.optionGroup.getValueAccessor(editor) +public fun VimInjector.options(editor: VimEditor): EffectiveOptions = this.optionGroup.getEffectiveOptions(editor) diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroup.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroup.kt index 27c883ab77..e72991f73f 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroup.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroup.kt @@ -11,8 +11,7 @@ package com.maddyhome.idea.vim.api import com.maddyhome.idea.vim.options.Option import com.maddyhome.idea.vim.options.OptionChangeListener import com.maddyhome.idea.vim.options.OptionScope -import com.maddyhome.idea.vim.options.OptionValueAccessor -import com.maddyhome.idea.vim.options.StringOption +import com.maddyhome.idea.vim.options.StringListOption import com.maddyhome.idea.vim.options.ToggleOption import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt @@ -83,17 +82,6 @@ public interface VimOptionGroup { */ public fun removeListener(option: Option, listener: OptionChangeListener) - /** - * Return an accessor class to easily retrieve options values - * - * Note that passing `null` as an editor means that you're only interested in global options - NOT global values of - * local to buffer or local to window or global-local options! For that, use [getOptionValue]. - * - * @param editor The editor to use to retrieve local option values. If `null`, then only global values are available - * @return An instance of [OptionValueAccessor] to provide easy API to get option values - */ - public fun getValueAccessor(editor: VimEditor?): OptionValueAccessor - /** * Override the original default value of the option with an implementation specific value * @@ -101,6 +89,16 @@ public interface VimOptionGroup { * This function should be used with care! */ public fun overrideDefaultValue(option: Option, newDefaultValue: T) + + /** + * Return an accessor for options that only have a global value + */ + public fun getGlobalOptions(): GlobalOptions + + /** + * Return an accessor for the effective value of local options + */ + public fun getEffectiveOptions(editor: VimEditor): EffectiveOptions } /** @@ -116,18 +114,12 @@ public fun VimOptionGroup.resetDefaultValue(option: Option, setOptionValue(option, scope, option.defaultValue) } -/** - * Checks if the given string option matches the value, or a string list contains the value - */ -public fun VimOptionGroup.hasValue(option: StringOption, scope: OptionScope, value: String): Boolean = - value in option.split(getOptionValue(option, scope).asString()) - /** * Splits a string list option into flags, or returns a list with a single string value * * E.g. the `fileencodings` option with value "ucs-bom,utf-8,default,latin1" will result listOf("ucs-bom", "utf-8", "default", "latin1") */ -public fun VimOptionGroup.getStringListValues(option: StringOption, scope: OptionScope): List { +public fun VimOptionGroup.getStringListValues(option: StringListOption, scope: OptionScope): List { return option.split(getOptionValue(option, scope).asString()) } @@ -152,15 +144,3 @@ public fun VimOptionGroup.invertToggleOption(option: ToggleOption, scope: Option val optionValue = getOptionValue(option, scope) setOptionValue(option, scope, if (optionValue.asBoolean()) VimInt.ZERO else VimInt.ONE) } - - -/** - * Modifies the value of an option by calling the given transform function - */ -public inline fun , TDataType : VimDataType> VimOptionGroup.modifyOptionValue( - option: T, - scope: OptionScope, - transform: T.(TDataType) -> TDataType? -) { - option.transform(getOptionValue(option, scope))?.let { setOptionValue(option, scope, it) } -} diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroupBase.kt index 1ebd2ad394..ed5b83ca21 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimOptionGroupBase.kt @@ -11,13 +11,12 @@ package com.maddyhome.idea.vim.api import com.maddyhome.idea.vim.options.Option import com.maddyhome.idea.vim.options.OptionChangeListener import com.maddyhome.idea.vim.options.OptionScope -import com.maddyhome.idea.vim.options.OptionValueAccessor import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType public abstract class VimOptionGroupBase : VimOptionGroup { + private val globalOptionsAccessor = GlobalOptions() private val globalValues = mutableMapOf() private val localOptionsKey = Key>("localOptions") - private val globalOptionValueAccessor by lazy { OptionValueAccessor(this, OptionScope.GLOBAL) } override fun initialiseOptions() { Options.initialise() @@ -106,11 +105,11 @@ public abstract class VimOptionGroupBase : VimOptionGroup { option.removeOptionChangeListener(listener) } - override fun getValueAccessor(editor: VimEditor?): OptionValueAccessor = - if (editor == null) globalOptionValueAccessor else OptionValueAccessor(this, OptionScope.LOCAL(editor)) - - final override fun overrideDefaultValue(option: Option, newDefaultValue: T) { option.overrideDefaultValue(newDefaultValue) } + + override fun getGlobalOptions(): GlobalOptions = globalOptionsAccessor + + override fun getEffectiveOptions(editor: VimEditor): EffectiveOptions = EffectiveOptions(OptionScope.LOCAL(editor)) } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt index a3d43c5316..50d280fbad 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimVisualMotionGroupBase.kt @@ -23,7 +23,7 @@ import com.maddyhome.idea.vim.helper.vimStateMachine public abstract class VimVisualMotionGroupBase : VimVisualMotionGroup { override val exclusiveSelection: Boolean - get() = injector.globalOptions().hasValue(Options.selection, "exclusive") + get() = injector.globalOptions().selection.contains("exclusive") override val selectionAdj: Int get() = if (exclusiveSelection) 0 else 1 diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingProcessor.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingProcessor.kt index 4d3cb41cde..f8ab4d24dc 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingProcessor.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingProcessor.kt @@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.command import com.maddyhome.idea.vim.KeyHandler import com.maddyhome.idea.vim.api.ExecutionContext -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -97,8 +96,7 @@ public object MappingProcessor { // Every time a key is pressed and handled, the timer is stopped. E.g. if there is a mapping for "dweri", and the // user has typed "dw" wait for the timeout, and then replay "d" and "w" without any mapping (which will of course // delete a word) - if (injector.options(editor).isSet(Options.timeout) - ) { + if (injector.options(editor).timeout) { log.trace("timeout is set. schedule a mapping timer") // XXX There is a strange issue that reports that mapping state is empty at the moment of the function call. // At the moment, I see the only one possibility this to happen - other key is handled after the timer executed, diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt index c2aecc6904..fc72903a77 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.command -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.diagnostic.trace @@ -38,7 +37,7 @@ public class MappingState { public var mappingMode: MappingMode = MappingMode.NORMAL - private val timer = Timer(injector.globalOptions().getIntValue(Options.timeoutlen), null) + private val timer = Timer(injector.globalOptions().timeoutlen, null) private var keyList = mutableListOf() init { @@ -46,7 +45,7 @@ public class MappingState { } public fun startMappingTimer(actionListener: ActionListener) { - timer.initialDelay = injector.globalOptions().getIntValue(Options.timeoutlen) + timer.initialDelay = injector.globalOptions().timeoutlen timer.actionListeners.forEach { timer.removeActionListener(it) } timer.addActionListener(actionListener) timer.start() diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/VimStateMachine.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/VimStateMachine.kt index 5a607cfc9a..c1768e699d 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/VimStateMachine.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/VimStateMachine.kt @@ -7,7 +7,6 @@ */ package com.maddyhome.idea.vim.command -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimActionsInitiator import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.globalOptions @@ -284,7 +283,7 @@ public class VimStateMachine(private val editor: VimEditor?) { private fun doShowMode() { val msg = StringBuilder() - if (injector.globalOptions().isSet(Options.showmode)) { + if (injector.globalOptions().showmode) { msg.append(getStatusString()) } if (isRecording) { @@ -376,7 +375,7 @@ public class VimStateMachine(private val editor: VimEditor?) { */ @JvmStatic public fun getInstance(editor: Any?): VimStateMachine { - return if (editor == null || injector.globalOptions().isSet(Options.ideaglobalmode)) { + return if (editor == null || injector.globalOptions().ideaglobalmode) { globalState } else { injector.commandStateFor(editor) diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt index 77695bd811..ca2e49e03d 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt @@ -7,7 +7,6 @@ */ package com.maddyhome.idea.vim.common -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.api.options @@ -53,9 +52,7 @@ public class DigraphSequence { return when (digraphState) { DIG_STATE_PENDING -> { logger.debug("DIG_STATE_PENDING") - if (key.keyCode == KeyEvent.VK_BACK_SPACE && - injector.options(editor).isSet(Options.digraph) - ) { + if (key.keyCode == KeyEvent.VK_BACK_SPACE && injector.options(editor).digraph) { digraphState = DIG_STATE_BACK_SPACE } else if (key.keyChar != KeyEvent.CHAR_UNDEFINED) { digraphChar = key.keyChar diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/VimVisualGroup.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/VimVisualGroup.kt index f69f0991e6..2867be6488 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/VimVisualGroup.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/VimVisualGroup.kt @@ -9,7 +9,6 @@ package com.maddyhome.idea.vim.group.visual import com.maddyhome.idea.vim.api.BufferPosition -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.getLineEndForOffset import com.maddyhome.idea.vim.api.getLineStartForOffset @@ -42,7 +41,7 @@ public fun lineToNativeSelection(editor: VimEditor, start: Int, end: Int): Pair< public fun > sort(a: T, b: T): Pair = if (a > b) b to a else a to b -private fun isExclusiveSelection() = injector.globalOptions().hasValue(Options.selection, "exclusive") +private fun isExclusiveSelection() = injector.globalOptions().selection.contains("exclusive") public fun blockToNativeSelection( editor: VimEditor, diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt index 2ade9ba07b..effd1407f9 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/handler/SpecialKeyHandlers.kt @@ -10,7 +10,6 @@ package com.maddyhome.idea.vim.handler import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimCaret import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.globalOptions @@ -56,9 +55,9 @@ public abstract class ShiftedSpecialKeyHandler : VimActionHandler.ConditionalMul cmd: Command, operatorArguments: OperatorArguments, ): Boolean { - val startSel = injector.globalOptions().hasValue(Options.keymodel, OptionConstants.keymodel_startsel) + val startSel = injector.globalOptions().keymodel.contains(OptionConstants.keymodel_startsel) if (startSel && !editor.inVisualMode && !editor.inSelectMode) { - if (injector.globalOptions().hasValue(Options.selectmode, OptionConstants.selectmode_key)) { + if (injector.globalOptions().selectmode.contains(OptionConstants.selectmode_key)) { injector.visualMotionGroup.enterSelectMode(editor, VimStateMachine.SubMode.VISUAL_CHARACTER) } else { injector.visualMotionGroup @@ -93,7 +92,7 @@ public abstract class ShiftedArrowKeyHandler(private val runBothCommandsAsMultic val (inVisualMode, inSelectMode, withKey) = withKeyOrNot(editor) if (withKey) { if (!inVisualMode && !inSelectMode) { - if (injector.globalOptions().hasValue(Options.selectmode, OptionConstants.selectmode_key)) { + if (injector.globalOptions().selectmode.contains(OptionConstants.selectmode_key)) { injector.visualMotionGroup.enterSelectMode(editor, VimStateMachine.SubMode.VISUAL_CHARACTER) } else { injector.visualMotionGroup @@ -107,7 +106,7 @@ public abstract class ShiftedArrowKeyHandler(private val runBothCommandsAsMultic } private fun withKeyOrNot(editor: VimEditor): Triple { - val keymodelOption = injector.globalOptions().getStringListValues(Options.keymodel) + val keymodelOption = injector.globalOptions().keymodel val startSel = OptionConstants.keymodel_startsel in keymodelOption val inVisualMode = editor.inVisualMode val inSelectMode = editor.inSelectMode @@ -171,7 +170,7 @@ public abstract class NonShiftedSpecialKeyHandler : MotionActionHandler.ForEachC argument: Argument?, operatorArguments: OperatorArguments, ): Motion { - val keymodel = injector.globalOptions().getStringListValues(Options.keymodel) + val keymodel = injector.globalOptions().keymodel if (editor.inSelectMode && (OptionConstants.keymodel_stopsel in keymodel || OptionConstants.keymodel_stopselect in keymodel)) { editor.exitSelectModeNative(false) } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineHelper.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineHelper.kt index 75a4bdff1d..8ce7035846 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineHelper.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineHelper.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.helper -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector @@ -60,7 +59,7 @@ public val VimStateMachine.Mode.isEndAllowed: Boolean } public val usesVirtualSpace: Boolean - get() = injector.globalOptions().hasValue(Options.virtualedit, OptionConstants.virtualedit_onemore) + get() = injector.globalOptions().virtualedit.contains(OptionConstants.virtualedit_onemore) public val VimEditor.isEndAllowed: Boolean get() = when (this.mode) { diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/StrictMode.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/StrictMode.kt index 20be2c835f..f760c812ff 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/StrictMode.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/StrictMode.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.helper -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector @@ -21,7 +20,7 @@ public object StrictMode { } public fun fail(message: String) { - if (injector.globalOptions().isSet(Options.ideastrictmode)) { + if (injector.globalOptions().ideastrictmode) { error(message) } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/history/HistoryBlock.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/history/HistoryBlock.kt index e6c3cf883d..c14b0cf41e 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/history/HistoryBlock.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/history/HistoryBlock.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.history -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector @@ -36,6 +35,6 @@ public class HistoryBlock { } public companion object { - private fun maxLength() = injector.globalOptions().getIntValue(Options.history) + private fun maxLength() = injector.globalOptions().history } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/StrictMode.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/StrictMode.kt index b34400f29e..64c572929d 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/StrictMode.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/StrictMode.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.option -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector @@ -22,7 +21,7 @@ public object StrictMode { } public fun fail(message: String) { - if (injector.globalOptions().isSet(Options.ideastrictmode)) { + if (injector.globalOptions().ideastrictmode) { error(message) } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/ToggleOption.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/ToggleOption.kt index 8ca31401b2..dc1c30d62e 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/ToggleOption.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/option/ToggleOption.kt @@ -8,8 +8,8 @@ package com.maddyhome.idea.vim.option -import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector +import com.maddyhome.idea.vim.options.OptionScope /** * COMPATIBILITY-LAYER: Moved out of class and to a different package @@ -23,5 +23,5 @@ public open class ToggleOption(private val option: com.maddyhome.idea.vim.option * COMPATIBILITY-LAYER: Method added * Please see: https://jb.gg/zo8n0r */ - public fun isSet(): Boolean = injector.globalOptions().isSet(option) + public fun isSet(): Boolean = injector.optionGroup.getOptionValue(option, OptionScope.GLOBAL).asBoolean() } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/Option.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/Option.kt index b8f14fdc36..cc6cdbf206 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/Option.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/Option.kt @@ -71,8 +71,55 @@ public abstract class Option(public val name: String, public va public abstract fun parseValue(value: String, token: String): VimDataType } -public open class StringOption(name: String, abbrev: String, defaultValue: VimString, public val isList: Boolean = false, public val boundedValues: Collection? = null) : Option(name, abbrev, defaultValue) { - public constructor(name: String, abbrev: String, defaultValue: String, isList: Boolean = false, boundedValues: Collection? = null) : this(name, abbrev, VimString(defaultValue), isList, boundedValues) +public open class StringOption(name: String, abbrev: String, defaultValue: VimString, public val boundedValues: Collection? = null) : Option(name, abbrev, defaultValue) { + public constructor(name: String, abbrev: String, defaultValue: String, boundedValues: Collection? = null) : this(name, abbrev, VimString(defaultValue), boundedValues) + + override fun checkIfValueValid(value: VimDataType, token: String) { + if (value !is VimString) { + throw exExceptionMessage("E474", token) + } + + if (value.value.isEmpty()) { + return + } + + if (boundedValues != null && !boundedValues.contains(value.value)) { + throw exExceptionMessage("E474", token) + } + } + + override fun parseValue(value: String, token: String): VimString = + VimString(value).also { checkIfValueValid(it, token) } + + public fun appendValue(currentValue: VimString, value: VimString): VimString = + VimString(currentValue.value + value.value) + + public fun prependValue(currentValue: VimString, value: VimString): VimString = + VimString(value.value + currentValue.value) + + public fun removeValue(currentValue: VimString, value: VimString): VimString { + // TODO: Not sure this is correct. Should replace just the first occurrence? + return VimString(currentValue.value.replace(value.value, "")) + } +} + +/** + * Represents a string that is a comma-separated list of values + * + * Note that we have tried multiple ways to represent a string list option, from a separate class similar to + * [StringListOption] or a combined string option. While a string list option "is-a" string option, its operations + * (append, prepend and remove) are implemented very differently to the string option. Unless there is a good reason to + * do so, we do not expect this to change again. + */ +public open class StringListOption( + name: String, + abbrev: String, + defaultValue: VimString, + public val boundedValues: Collection? = null, +) : Option(name, abbrev, defaultValue) { + + public constructor(name: String, abbrev: String, defaultValue: String, boundedValues: Collection? = null) + : this(name, abbrev, VimString(defaultValue), boundedValues) override fun checkIfValueValid(value: VimDataType, token: String) { if (value !is VimString) { @@ -92,44 +139,34 @@ public open class StringOption(name: String, abbrev: String, defaultValue: VimSt VimString(value).also { checkIfValueValid(it, token) } public fun appendValue(currentValue: VimString, value: VimString): VimString { + // TODO: What happens if we're trying to add a sublist that already exists? if (split(currentValue.value).contains(value.value)) return currentValue return VimString(joinValues(currentValue.value, value.value)) } public fun prependValue(currentValue: VimString, value: VimString): VimString { + // TODO: What happens if we're trying to add a sublist that already exists? if (split(currentValue.value).contains(value.value)) return currentValue return VimString(joinValues(value.value, currentValue.value)) } public fun removeValue(currentValue: VimString, value: VimString): VimString { - val newValue = if (isList) { - val valuesToRemove = split(value.value) - val elements = split(currentValue.value).toMutableList() - if (Collections.indexOfSubList(elements, valuesToRemove) != -1) { - // see `:help set` - // When the option is a list of flags, {value} must be - // exactly as they appear in the option. Remove flags - // one by one to avoid problems. - elements.removeAll(valuesToRemove) - } - elements.joinToString(separator = ",") - } else { - // TODO: Not sure this is correct. Should replace just the first occurrence? - currentValue.value.replace(value.value, "") + val valuesToRemove = split(value.value) + val elements = split(currentValue.value).toMutableList() + if (Collections.indexOfSubList(elements, valuesToRemove) != -1) { + // see `:help set` + // When the option is a list of flags, {value} must be + // exactly as they appear in the option. Remove flags + // one by one to avoid problems. + elements.removeAll(valuesToRemove) } - return VimString(newValue) + return VimString(elements.joinToString(separator = ",")) } - public open fun split(value: String): List { - return if (isList) { - value.split(",") - } else { - listOf(value) - } - } + public open fun split(value: String): List = value.split(",") private fun joinValues(first: String, second: String): String { - val separator = if (isList && first.isNotEmpty()) "," else "" + val separator = if (first.isNotEmpty()) "," else "" return first + separator + second } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/OptionValueAccessor.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/OptionValueAccessor.kt deleted file mode 100644 index cf97179861..0000000000 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/OptionValueAccessor.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2003-2023 The IdeaVim authors - * - * Use of this source code is governed by an MIT-style - * license that can be found in the LICENSE.txt file or at - * https://opensource.org/licenses/MIT. - */ - -package com.maddyhome.idea.vim.options - -import com.maddyhome.idea.vim.api.VimOptionGroup -import com.maddyhome.idea.vim.api.getStringListValues -import com.maddyhome.idea.vim.api.hasValue -import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType -import com.maddyhome.idea.vim.vimscript.services.OptionService - -/** - * API for accessing option values in the given scope - * - * This class is intended to be used by code that needs to check option values to modify behaviour. Code that needs to - * administer options should use [OptionService] (e.g. `:set`, `:setlocal`, `:setglobal`). - * - * All functions assume that the option exists, and that the calling code knows what type to expect. Trying to retrieve - * a non-existent option, or calling the wrong accessor will lead to exceptions or incorrect behaviour. - */ -public class OptionValueAccessor(private val optionGroup: VimOptionGroup, public val scope: OptionScope) { - /** Gets the loosely typed option value */ - public fun getValue(option: Option): T = optionGroup.getOptionValue(option, scope) - - /** Gets the option value as an integer */ - public fun getIntValue(option: NumberOption): Int = getValue(option).value - - /** Gets the option value as a string */ - public fun getStringValue(option: StringOption): String = getValue(option).value - - /** - * Gets the option value as a string list - * - * @see hasValue - */ - public fun getStringListValues(option: StringOption): List = optionGroup.getStringListValues(option, scope) - - /** Checks if a string list option contains a value, or if a simple string value matches the given value - * - * If the option is a string option, the given value must match the entire string - */ - public fun hasValue(option: StringOption, value: String): Boolean = optionGroup.hasValue(option, scope, value) - - /** - * Checks the option value is set/true - * - * The option is most likely a toggle option, but this is not required. - */ - public fun isSet(option: ToggleOption): Boolean = getValue(option).asBoolean() -} diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/ClipboardOptionHelper.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/ClipboardOptionHelper.kt index 53c2320196..e4b723f5b7 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/ClipboardOptionHelper.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/ClipboardOptionHelper.kt @@ -8,13 +8,9 @@ package com.maddyhome.idea.vim.options.helpers -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector -import com.maddyhome.idea.vim.api.modifyOptionValue import com.maddyhome.idea.vim.options.OptionConstants -import com.maddyhome.idea.vim.options.OptionScope -import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString public object ClipboardOptionHelper { public var ideaputDisabled: Boolean = false @@ -22,21 +18,16 @@ public object ClipboardOptionHelper { public class IdeaputDisabler : AutoCloseable { private val containedBefore = - injector.globalOptions().hasValue(Options.clipboard, OptionConstants.clipboard_ideaput) + injector.globalOptions().clipboard.contains(OptionConstants.clipboard_ideaput) init { - injector.optionGroup.modifyOptionValue(Options.clipboard, OptionScope.GLOBAL) { - removeValue(it, VimString(OptionConstants.clipboard_ideaput)) - } - + injector.globalOptions().clipboard.removeValue(OptionConstants.clipboard_ideaput) ideaputDisabled = true } override fun close() { if (containedBefore) { - injector.optionGroup.modifyOptionValue(Options.clipboard, OptionScope.GLOBAL) { - appendValue(it, VimString(OptionConstants.clipboard_ideaput)) - } + injector.globalOptions().clipboard.prependValue(OptionConstants.clipboard_ideaput) } ideaputDisabled = false } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/GuiCursorOptionHelper.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/GuiCursorOptionHelper.kt index 90b318b4f5..cbbfd777f0 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/GuiCursorOptionHelper.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/GuiCursorOptionHelper.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.options.helpers -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.command.VimStateMachine @@ -83,7 +82,7 @@ public object GuiCursorOptionHelper { var highlightGroup = "" var lmapHighlightGroup = "" var blinkModes = emptyList() - injector.globalOptions().getStringListValues(Options.guicursor) + injector.globalOptions().guicursor .map { convertToken(it) } .forEach { data -> if (data.modes.contains(mode) || data.modes.contains(GuiCursorMode.ALL)) { diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/KeywordOptionHelper.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/KeywordOptionHelper.kt index 716b6ce92f..7af24a00d2 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/KeywordOptionHelper.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/options/helpers/KeywordOptionHelper.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.options.helpers -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.options.OptionChangeListener @@ -28,9 +27,7 @@ public object KeywordOptionHelper { } public fun updateSpecs() { - keywordSpecs = valuesToValidatedAndReversedSpecs( - parseValues(injector.globalOptions().getStringValue(Options.iskeyword)), - )!!.toMutableList() + keywordSpecs = valuesToValidatedAndReversedSpecs(injector.globalOptions().iskeyword)!!.toMutableList() } public fun isValueInvalid(value: String): Boolean { diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/put/VimPutBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/put/VimPutBase.kt index 0a31a034c5..2c30b37552 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/put/VimPutBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/put/VimPutBase.kt @@ -12,7 +12,6 @@ import com.maddyhome.idea.vim.api.BufferPosition import com.maddyhome.idea.vim.api.ExecutionContext import com.maddyhome.idea.vim.api.ImmutableVimCaret import com.maddyhome.idea.vim.api.MutableVimEditor -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.VimCaret import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.getLineEndForOffset @@ -538,7 +537,7 @@ public abstract class VimPutBase : VimPut { ) { val visualSelection = data.visualSelection val subMode = visualSelection?.typeInEditor?.toSubMode() ?: VimStateMachine.SubMode.NONE - if (injector.globalOptions().hasValue(Options.clipboard, OptionConstants.clipboard_ideaput)) { + if (injector.globalOptions().clipboard.contains(OptionConstants.clipboard_ideaput)) { val idePasteProvider = getProviderForPasteViaIde(editor, text.typeInRegister, data) if (idePasteProvider != null) { logger.debug("Perform put via idea paste") diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/register/VimRegisterGroupBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/register/VimRegisterGroupBase.kt index 0deb44f802..94b0a46d87 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/register/VimRegisterGroupBase.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/register/VimRegisterGroupBase.kt @@ -73,7 +73,7 @@ public abstract class VimRegisterGroupBase : VimRegisterGroup { injector.optionGroup.addListener( Options.clipboard, { - val clipboardOptionValue = injector.globalOptions().getStringListValues(Options.clipboard) + val clipboardOptionValue = injector.globalOptions().clipboard defaultRegisterChar = when { "unnamed" in clipboardOptionValue -> '*' "unnamedplus" in clipboardOptionValue -> '+' diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/SetCommand.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/SetCommand.kt index 48861e43e8..c76a2751a3 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/SetCommand.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/SetCommand.kt @@ -24,6 +24,7 @@ import com.maddyhome.idea.vim.helper.Msg import com.maddyhome.idea.vim.options.NumberOption import com.maddyhome.idea.vim.options.Option import com.maddyhome.idea.vim.options.OptionScope +import com.maddyhome.idea.vim.options.StringListOption import com.maddyhome.idea.vim.options.StringOption import com.maddyhome.idea.vim.options.ToggleOption import com.maddyhome.idea.vim.vimscript.model.ExecutionResult @@ -275,6 +276,7 @@ private fun formatKnownOptionValue(option: Option, scope: Optio private fun appendValue(option: Option, currentValue: VimDataType, value: VimDataType): VimDataType? { return when (option) { is StringOption -> option.appendValue(currentValue as VimString, value as VimString) + is StringListOption -> option.appendValue(currentValue as VimString, value as VimString) is NumberOption -> option.addValues(currentValue as VimInt, value as VimInt) else -> null } @@ -283,6 +285,7 @@ private fun appendValue(option: Option, currentValue: VimDataType, private fun prependValue(option: Option, currentValue: VimDataType, value: VimDataType): VimDataType? { return when (option) { is StringOption -> option.prependValue(currentValue as VimString, value as VimString) + is StringListOption -> option.prependValue(currentValue as VimString, value as VimString) is NumberOption -> option.multiplyValues(currentValue as VimInt, value as VimInt) else -> null } @@ -291,6 +294,7 @@ private fun prependValue(option: Option, currentValue: VimDataType, private fun removeValue(option: Option, currentValue: VimDataType, value: VimDataType): VimDataType? { return when (option) { is StringOption -> option.removeValue(currentValue as VimString, value as VimString) + is StringListOption -> option.removeValue(currentValue as VimString, value as VimString) is NumberOption -> option.subtractValues(currentValue as VimInt, value as VimInt) else -> null } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/expressions/operators/handlers/binary/BinaryOperatorWithIgnoreCaseOption.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/expressions/operators/handlers/binary/BinaryOperatorWithIgnoreCaseOption.kt index 576c3166d5..0649e917fa 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/expressions/operators/handlers/binary/BinaryOperatorWithIgnoreCaseOption.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/expressions/operators/handlers/binary/BinaryOperatorWithIgnoreCaseOption.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.vimscript.model.expressions.operators.handlers.binary -import com.maddyhome.idea.vim.api.Options import com.maddyhome.idea.vim.api.globalOptions import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType @@ -18,9 +17,7 @@ public abstract class BinaryOperatorWithIgnoreCaseOption( private val caseSensitiveImpl: BinaryOperatorHandler, ) : BinaryOperatorHandler() { - private fun shouldIgnoreCase(): Boolean { - return injector.globalOptions().isSet(Options.ignorecase) - } + private fun shouldIgnoreCase(): Boolean = injector.globalOptions().ignorecase override fun performOperation(left: VimDataType, right: VimDataType): VimDataType { return if (shouldIgnoreCase()) {