From fb755082585a9715c84ee0816544e4c2ea7d14be Mon Sep 17 00:00:00 2001 From: Filipp Vakhitov Date: Tue, 23 Jan 2024 23:59:57 +0200 Subject: [PATCH] Support widget themes --- .../vim/ui/widgets/mode/ModeWidgetPopup.kt | 271 +++++++++++------- .../idea/vim/ui/widgets/mode/Util.kt | 129 +++++++++ .../idea/vim/ui/widgets/mode/VimModeWidget.kt | 83 ------ .../vimscript/services/IjVariableService.kt | 67 +---- .../messages/IdeaVimBundle.properties | 4 +- 5 files changed, 314 insertions(+), 240 deletions(-) create mode 100644 src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/Util.kt diff --git a/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/ModeWidgetPopup.kt b/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/ModeWidgetPopup.kt index d18a06c6fa..4475038c4b 100644 --- a/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/ModeWidgetPopup.kt +++ b/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/ModeWidgetPopup.kt @@ -14,16 +14,25 @@ import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.ui.DialogPanel import com.intellij.openapi.ui.popup.JBPopup import com.intellij.openapi.ui.popup.JBPopupFactory +import com.intellij.ui.components.JBCheckBox import com.intellij.ui.components.JBScrollPane import com.intellij.ui.components.JBTabbedPane import com.intellij.ui.content.ContentFactory +import com.intellij.ui.dsl.builder.Cell import com.intellij.ui.dsl.builder.RowLayout +import com.intellij.ui.dsl.builder.TopGap +import com.intellij.ui.dsl.builder.bindItem +import com.intellij.ui.dsl.builder.bindSelected import com.intellij.ui.dsl.builder.bindText import com.intellij.ui.dsl.builder.panel +import com.intellij.ui.dsl.builder.selected +import com.intellij.ui.dsl.builder.toNullableProperty +import com.intellij.ui.layout.not import com.intellij.util.Alarm import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.helper.MessageHelper import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString +import com.maddyhome.idea.vim.vimscript.model.datatypes.asVimInt import java.awt.BorderLayout import java.awt.Dimension import java.awt.FlowLayout @@ -35,7 +44,6 @@ import javax.swing.JPanel import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty - public class ModeWidgetPopup : AnAction() { public override fun actionPerformed(e: AnActionEvent) { val project = e.project ?: return @@ -64,7 +72,7 @@ public class ModeWidgetPopup : AnAction() { val darkThemeSettings = createPanel(getWidgetThemeColors(false)) tabbedPane.addTab(MessageHelper.getMessage("widget.mode.popup.tab.light"), lightThemeSettings.addScrollPane()) tabbedPane.addTab(MessageHelper.getMessage("widget.mode.popup.tab.dark"), darkThemeSettings.addScrollPane()) - tabbedPane.preferredSize = Dimension(300, 600) + tabbedPane.preferredSize = Dimension(300, 300) for (i in 0 until tabbedPane.tabCount) { val label = JLabel(tabbedPane.getTitleAt(i), JLabel.CENTER) label.preferredSize = Dimension(126, tabbedPane.getTabComponentAt(i).preferredSize.height) @@ -77,6 +85,7 @@ public class ModeWidgetPopup : AnAction() { val popup = JBPopupFactory.getInstance() .createComponentPopupBuilder(popupContent, popupContent) .setTitle(MessageHelper.getMessage("widget.mode.popup.title")) + .setResizable(true) .setMovable(true) .setRequestFocus(true) .setCancelOnClickOutside(false) @@ -110,6 +119,8 @@ public class ModeWidgetPopup : AnAction() { private fun getWidgetThemeColors(isLight: Boolean): ModeColors { val keyPostfix = if (isLight) "_light" else "_dark" return ModeColors( + "widget_mode_is_full_customization$keyPostfix", + "widget_mode_theme$keyPostfix", "widget_mode_normal_background$keyPostfix", "widget_mode_normal_foreground$keyPostfix", "widget_mode_insert_background$keyPostfix", @@ -135,121 +146,134 @@ public class ModeWidgetPopup : AnAction() { private fun createPanel(modeColors: ModeColors): DialogPanel { val panel = panel { - row { text(MessageHelper.getMessage("widget.mode.popup.color.instruction")) } - - group(MessageHelper.getMessage("widget.mode.popup.group.normal.title")) { - row { - label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::normalBg) - }.layout(RowLayout.PARENT_GRID) - row { - label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::normalFg) - }.layout(RowLayout.PARENT_GRID) + lateinit var advancedSettings: Cell + row { + advancedSettings = checkBox(MessageHelper.getMessage("widget.mode.popup.field.advanced.settings")).bindSelected(modeColors::isFullCustomization) } - - group(MessageHelper.getMessage("widget.mode.popup.group.insert.title")) { - row { - label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::insertBg) - }.layout(RowLayout.PARENT_GRID) + group { row { - label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::insertFg) - }.layout(RowLayout.PARENT_GRID) - } - - group(MessageHelper.getMessage("widget.mode.popup.group.replace.title")) { - row { - label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::replaceBg) - }.layout(RowLayout.PARENT_GRID) - row { - label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::replaceFg) - }.layout(RowLayout.PARENT_GRID) - } - - group(MessageHelper.getMessage("widget.mode.popup.group.command.title")) { - row { - label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::commandBg) - }.layout(RowLayout.PARENT_GRID) - row { - label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::commandFg) - }.layout(RowLayout.PARENT_GRID) - } + label(MessageHelper.getMessage("widget.mode.popup.field.theme")) + comboBox(ModeWidgetTheme.values().toList()).bindItem(modeColors::theme.toNullableProperty()) + } + row { browserLink("Suggest your theme", "https://youtrack.jetbrains.com/issue/VIM-1377/Normal-mode-needs-to-be-more-obvious") } + }.topGap(TopGap.NONE).visibleIf(!advancedSettings.selected) + group(MessageHelper.getMessage("widget.mode.popup.group.title.full.customization")) { + row { text(MessageHelper.getMessage("widget.mode.popup.color.instruction")) } - group(MessageHelper.getMessage("widget.mode.popup.group.visual.title")) { - row { - label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::visualBg) - }.layout(RowLayout.PARENT_GRID) - row { - label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::visualFg) - }.layout(RowLayout.PARENT_GRID) + group(MessageHelper.getMessage("widget.mode.popup.group.normal.title")) { + row { + label(MessageHelper.getMessage("widget.mode.popup.field.background")) + textField().bindText(modeColors::normalBg) + }.layout(RowLayout.PARENT_GRID) + row { + label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) + textField().bindText(modeColors::normalFg) + }.layout(RowLayout.PARENT_GRID) + } - collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.line.title")) { - row { text(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.instruction")) } + group(MessageHelper.getMessage("widget.mode.popup.group.insert.title")) { row { label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::visualLineBg) + textField().bindText(modeColors::insertBg) }.layout(RowLayout.PARENT_GRID) row { label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::visualLineFg) + textField().bindText(modeColors::insertFg) }.layout(RowLayout.PARENT_GRID) } - collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.block.title")) { - row { text(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.instruction")) } + group(MessageHelper.getMessage("widget.mode.popup.group.replace.title")) { row { label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::visualBlockBg) + textField().bindText(modeColors::replaceBg) }.layout(RowLayout.PARENT_GRID) row { label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::visualBlockFg) + textField().bindText(modeColors::replaceFg) }.layout(RowLayout.PARENT_GRID) } - } - group(MessageHelper.getMessage("widget.mode.popup.group.select.title")) { - row { - label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::selectBg) - }.layout(RowLayout.PARENT_GRID) - row { - label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::selectFg) - }.layout(RowLayout.PARENT_GRID) + group(MessageHelper.getMessage("widget.mode.popup.group.command.title")) { + row { + label(MessageHelper.getMessage("widget.mode.popup.field.background")) + textField().bindText(modeColors::commandBg) + }.layout(RowLayout.PARENT_GRID) + row { + label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) + textField().bindText(modeColors::commandFg) + }.layout(RowLayout.PARENT_GRID) + } - collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.line.title")) { - row { text(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.instruction")) } + group(MessageHelper.getMessage("widget.mode.popup.group.visual.title")) { row { label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::selectLineBg) + textField().bindText(modeColors::visualBg) }.layout(RowLayout.PARENT_GRID) row { label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::selectLineFg) + textField().bindText(modeColors::visualFg) }.layout(RowLayout.PARENT_GRID) + + collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.line.title")) { + row { text(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.instruction")) } + row { + label(MessageHelper.getMessage("widget.mode.popup.field.background")) + textField().bindText(modeColors::visualLineBg) + }.layout(RowLayout.PARENT_GRID) + row { + label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) + textField().bindText(modeColors::visualLineFg) + }.layout(RowLayout.PARENT_GRID) + } + + collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.block.title")) { + row { text(MessageHelper.getMessage("widget.mode.popup.group.visual.subgroup.instruction")) } + row { + label(MessageHelper.getMessage("widget.mode.popup.field.background")) + textField().bindText(modeColors::visualBlockBg) + }.layout(RowLayout.PARENT_GRID) + row { + label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) + textField().bindText(modeColors::visualBlockFg) + }.layout(RowLayout.PARENT_GRID) + } } - collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.block.title")) { - row { text(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.instruction")) } + group(MessageHelper.getMessage("widget.mode.popup.group.select.title")) { row { label(MessageHelper.getMessage("widget.mode.popup.field.background")) - textField().bindText(modeColors::selectBlockBg) + textField().bindText(modeColors::selectBg) }.layout(RowLayout.PARENT_GRID) row { label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) - textField().bindText(modeColors::selectBlockFg) + textField().bindText(modeColors::selectFg) }.layout(RowLayout.PARENT_GRID) + + collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.line.title")) { + row { text(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.instruction")) } + row { + label(MessageHelper.getMessage("widget.mode.popup.field.background")) + textField().bindText(modeColors::selectLineBg) + }.layout(RowLayout.PARENT_GRID) + row { + label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) + textField().bindText(modeColors::selectLineFg) + }.layout(RowLayout.PARENT_GRID) + } + + collapsibleGroup(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.block.title")) { + row { text(MessageHelper.getMessage("widget.mode.popup.group.select.subgroup.instruction")) } + row { + label(MessageHelper.getMessage("widget.mode.popup.field.background")) + textField().bindText(modeColors::selectBlockBg) + }.layout(RowLayout.PARENT_GRID) + row { + label(MessageHelper.getMessage("widget.mode.popup.field.foreground")) + textField().bindText(modeColors::selectBlockFg) + }.layout(RowLayout.PARENT_GRID) + } } - } + }.topGap(TopGap.NONE).visibleIf(advancedSettings.selected) } return panel } @@ -262,6 +286,7 @@ public class ModeWidgetPopup : AnAction() { } private class ModeColors( + isFullCustomizationKey: String, themeKey: String, normalBgKey: String, normalFgKey: String, insertBgKey: String, insertFgKey: String, replaceBgKey: String, replaceFgKey: String, @@ -269,28 +294,40 @@ public class ModeWidgetPopup : AnAction() { visualBgKey: String, visualFgKey: String, visualLineBgKey: String, visualLineFgKey: String, visualBlockBgKey: String, visualBlockFgKey: String, selectBgKey: String, selectFgKey: String, selectLineBgKey: String, selectLineFgKey: String, selectBlockBgKey: String, selectBlockFgKey: String ) { - var normalBg: String by VimScopeVariable(normalBgKey) - var normalFg: String by VimScopeVariable(normalFgKey) - var insertBg: String by VimScopeVariable(insertBgKey) - var insertFg: String by VimScopeVariable(insertFgKey) - var replaceBg: String by VimScopeVariable(replaceBgKey) - var replaceFg: String by VimScopeVariable(replaceFgKey) - var commandBg: String by VimScopeVariable(commandBgKey) - var commandFg: String by VimScopeVariable(commandFgKey) - var visualBg: String by VimScopeVariable(visualBgKey) - var visualFg: String by VimScopeVariable(visualFgKey) - var visualLineBg: String by VimScopeVariable(visualLineBgKey) - var visualLineFg: String by VimScopeVariable(visualLineFgKey) - var visualBlockBg: String by VimScopeVariable(visualBlockBgKey) - var visualBlockFg: String by VimScopeVariable(visualBlockFgKey) - var selectBg: String by VimScopeVariable(selectBgKey) - var selectFg: String by VimScopeVariable(selectFgKey) - var selectLineBg: String by VimScopeVariable(selectLineBgKey) - var selectLineFg: String by VimScopeVariable(selectLineFgKey) - var selectBlockBg: String by VimScopeVariable(selectBlockBgKey) - var selectBlockFg: String by VimScopeVariable(selectBlockFgKey) - - private class VimScopeVariable(private var key: String): ReadWriteProperty { + var isFullCustomization: Boolean by VimScopeBooleanVariable(isFullCustomizationKey) + var theme: ModeWidgetTheme by VimScopeThemeVariable(themeKey) + var normalBg: String by VimScopeStringVariable(normalBgKey) + var normalFg: String by VimScopeStringVariable(normalFgKey) + var insertBg: String by VimScopeStringVariable(insertBgKey) + var insertFg: String by VimScopeStringVariable(insertFgKey) + var replaceBg: String by VimScopeStringVariable(replaceBgKey) + var replaceFg: String by VimScopeStringVariable(replaceFgKey) + var commandBg: String by VimScopeStringVariable(commandBgKey) + var commandFg: String by VimScopeStringVariable(commandFgKey) + var visualBg: String by VimScopeStringVariable(visualBgKey) + var visualFg: String by VimScopeStringVariable(visualFgKey) + var visualLineBg: String by VimScopeStringVariable(visualLineBgKey) + var visualLineFg: String by VimScopeStringVariable(visualLineFgKey) + var visualBlockBg: String by VimScopeStringVariable(visualBlockBgKey) + var visualBlockFg: String by VimScopeStringVariable(visualBlockFgKey) + var selectBg: String by VimScopeStringVariable(selectBgKey) + var selectFg: String by VimScopeStringVariable(selectFgKey) + var selectLineBg: String by VimScopeStringVariable(selectLineBgKey) + var selectLineFg: String by VimScopeStringVariable(selectLineFgKey) + var selectBlockBg: String by VimScopeStringVariable(selectBlockBgKey) + var selectBlockFg: String by VimScopeStringVariable(selectBlockFgKey) + + private class VimScopeBooleanVariable(private var key: String): ReadWriteProperty { + override fun getValue(thisRef: ModeColors, property: KProperty<*>): Boolean { + return injector.variableService.getVimVariable(key)?.asBoolean() ?: false + } + + override fun setValue(thisRef: ModeColors, property: KProperty<*>, value: Boolean) { + injector.variableService.storeVimVariable(key, value.asVimInt()) + } + } + + private class VimScopeStringVariable(private var key: String): ReadWriteProperty { override fun getValue(thisRef: ModeColors, property: KProperty<*>): String { return injector.variableService.getVimVariable(key)?.asString() ?: "" } @@ -299,5 +336,33 @@ public class ModeWidgetPopup : AnAction() { injector.variableService.storeVimVariable(key, VimString(value)) } } + + private class VimScopeThemeVariable(private var key: String): ReadWriteProperty { + override fun getValue(thisRef: ModeColors, property: KProperty<*>): ModeWidgetTheme { + val themeString = injector.variableService.getVimVariable(key)?.asString() ?: return ModeWidgetTheme.getDefaultTheme() + return ModeWidgetTheme.parseString(themeString) ?: ModeWidgetTheme.getDefaultTheme() + } + + override fun setValue(thisRef: ModeColors, property: KProperty<*>, value: ModeWidgetTheme) { + injector.variableService.storeVimVariable(key, VimString(value.toString())) + } + } + } +} + +public enum class ModeWidgetTheme(private var value: String) { + TEST("Nord-Aurora (testing, will be removed)"), + COLORLESS("Colorless"); + + override fun toString(): String { + return value + } + + public companion object { + public fun parseString(string: String): ModeWidgetTheme? { + return ModeWidgetTheme.values().firstOrNull { it.value == string } + } + + public fun getDefaultTheme(): ModeWidgetTheme = TEST } } diff --git a/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/Util.kt b/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/Util.kt new file mode 100644 index 0000000000..495b4d70f9 --- /dev/null +++ b/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/Util.kt @@ -0,0 +1,129 @@ +/* + * Copyright 2003-2024 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.ui.widgets.mode + +import com.intellij.ide.ui.LafManager +import com.intellij.util.ui.UIUtil +import com.maddyhome.idea.vim.api.injector +import com.maddyhome.idea.vim.state.mode.Mode +import com.maddyhome.idea.vim.state.mode.SelectionType +import java.awt.Color + +public fun getModeBackground(mode: Mode?): Color { + val isLight = !LafManager.getInstance().currentUIThemeLookAndFeel.isDark + val keyPostfix = if (isLight) "_light" else "_dark" + if (injector.variableService.getVimVariable("widget_mode_is_full_customization$keyPostfix")?.asBoolean() != true) { + val themeString = injector.variableService.getVimVariable("widget_mode_theme$keyPostfix")?.asString() ?: "" + val theme = ModeWidgetTheme.parseString(themeString) ?: ModeWidgetTheme.getDefaultTheme() + when (theme) { + ModeWidgetTheme.TEST -> { + return when (mode) { + Mode.INSERT -> Color.decode("#D08770") + Mode.REPLACE -> Color.decode("#EBCB8B") + is Mode.NORMAL -> Color.decode("#BF616A") + is Mode.CMD_LINE -> Color.decode("#A3BE8C") + is Mode.VISUAL -> Color.decode("#B48EAD") + is Mode.SELECT -> Color.decode("#B48EAD") + is Mode.OP_PENDING, null -> UIUtil.getPanelBackground() + } + } + ModeWidgetTheme.COLORLESS -> { + return UIUtil.getPanelBackground() + } + } + } else { + val colorString = when (mode) { + Mode.INSERT -> injector.variableService.getVimVariable("widget_mode_insert_background$keyPostfix") + Mode.REPLACE -> injector.variableService.getVimVariable("widget_mode_replace_background$keyPostfix") + is Mode.NORMAL -> injector.variableService.getVimVariable("widget_mode_normal_background$keyPostfix") + is Mode.CMD_LINE -> injector.variableService.getVimVariable("widget_mode_command_background$keyPostfix") + is Mode.VISUAL -> { + val visualModeBackground = injector.variableService.getVimVariable("widget_mode_visual_background$keyPostfix") + when (mode.selectionType) { + SelectionType.CHARACTER_WISE -> visualModeBackground + SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_visual_line_background$keyPostfix") ?: visualModeBackground + SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_visual_block_background$keyPostfix") ?: visualModeBackground + } + } + is Mode.SELECT -> { + val selectModeBackground = injector.variableService.getVimVariable("widget_mode_select_background$keyPostfix") + when (mode.selectionType) { + SelectionType.CHARACTER_WISE -> selectModeBackground + SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_select_line_background$keyPostfix") ?: selectModeBackground + SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_select_block_background$keyPostfix") ?: selectModeBackground + } + } + is Mode.OP_PENDING, null -> null + }?.asString() + val defaultColor = UIUtil.getPanelBackground() + val color = when (colorString) { + "v:status_bar_bg" -> UIUtil.getPanelBackground() + "v:status_bar_fg" -> UIUtil.getLabelForeground() + else -> { + if (colorString == null) { + defaultColor + } else { + try { Color.decode(colorString) } catch (e: Exception) { defaultColor } + } + } + } + return color + } +} + +public fun getModeForeground(mode: Mode?): Color { + val isLight = !LafManager.getInstance().currentUIThemeLookAndFeel.isDark + val keyPostfix = if (isLight) "_light" else "_dark" + if (injector.variableService.getVimVariable("widget_mode_is_full_customization$keyPostfix")?.asBoolean() != true) { + val themeString = injector.variableService.getVimVariable("widget_mode_theme$keyPostfix")?.asString() ?: "" + val theme = ModeWidgetTheme.parseString(themeString) ?: ModeWidgetTheme.getDefaultTheme() + return when (theme) { + ModeWidgetTheme.TEST -> Color.decode("#2E3440") + ModeWidgetTheme.COLORLESS -> UIUtil.getLabelForeground() + } + } else { + val colorString = when (mode) { + Mode.INSERT -> injector.variableService.getVimVariable("widget_mode_insert_foreground$keyPostfix") + Mode.REPLACE -> injector.variableService.getVimVariable("widget_mode_replace_foreground$keyPostfix") + is Mode.NORMAL -> injector.variableService.getVimVariable("widget_mode_normal_foreground$keyPostfix") + is Mode.CMD_LINE -> injector.variableService.getVimVariable("widget_mode_command_foreground$keyPostfix") + is Mode.VISUAL -> { + val visualModeBackground = injector.variableService.getVimVariable("widget_mode_visual_foreground$keyPostfix") + when (mode.selectionType) { + SelectionType.CHARACTER_WISE -> visualModeBackground + SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_visual_line_foreground$keyPostfix") ?: visualModeBackground + SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_visual_block_foreground$keyPostfix") ?: visualModeBackground + } + } + is Mode.SELECT -> { + val selectModeBackground = injector.variableService.getVimVariable("widget_mode_select_foreground$keyPostfix") + when (mode.selectionType) { + SelectionType.CHARACTER_WISE -> selectModeBackground + SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_select_line_foreground$keyPostfix") ?: selectModeBackground + SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_select_block_foreground$keyPostfix") ?: selectModeBackground + } + } + is Mode.OP_PENDING, null -> null + }?.asString() + val defaultColor = UIUtil.getLabelForeground() + val color = when (colorString) { + "v:status_bar_bg" -> UIUtil.getPanelBackground() + "v:status_bar_fg" -> UIUtil.getLabelForeground() + else -> { + if (colorString == null) { + defaultColor + } else { + try { Color.decode(colorString) } catch (e: Exception) { defaultColor } + } + } + } + return color + } + +} diff --git a/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/VimModeWidget.kt b/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/VimModeWidget.kt index 44b6320022..362231ac32 100644 --- a/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/VimModeWidget.kt +++ b/src/main/java/com/maddyhome/idea/vim/ui/widgets/mode/VimModeWidget.kt @@ -8,7 +8,6 @@ package com.maddyhome.idea.vim.ui.widgets.mode -import com.intellij.ide.ui.LafManager import com.intellij.openapi.components.service import com.intellij.openapi.editor.Editor import com.intellij.openapi.fileEditor.FileEditorManager @@ -21,7 +20,6 @@ import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsManager import com.intellij.ui.awt.RelativePoint import com.intellij.ui.components.JBLabel import com.intellij.ui.util.width -import com.intellij.util.ui.UIUtil import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.newapi.globalIjOptions import com.maddyhome.idea.vim.newapi.vim @@ -30,7 +28,6 @@ import com.maddyhome.idea.vim.state.mode.SelectionType import com.maddyhome.idea.vim.state.mode.mode import com.maddyhome.idea.vim.ui.widgets.mode.listeners.ModeWidgetFocusListener import com.maddyhome.idea.vim.ui.widgets.mode.listeners.ModeWidgetModeListener -import java.awt.Color import java.awt.Dimension import java.awt.Point import java.awt.event.MouseAdapter @@ -134,86 +131,6 @@ public class VimModeWidget(public val project: Project) : CustomStatusBarWidget, SelectionType.BLOCK_WISE -> SELECT_BLOCK } - private fun getModeForeground(mode: Mode?): Color { - val keyPostfix = if (LafManager.getInstance().currentUIThemeLookAndFeel.isDark) "_dark" else "_light" - val colorString = when (mode) { - Mode.INSERT -> injector.variableService.getVimVariable("widget_mode_insert_foreground$keyPostfix") - Mode.REPLACE -> injector.variableService.getVimVariable("widget_mode_replace_foreground$keyPostfix") - is Mode.NORMAL -> injector.variableService.getVimVariable("widget_mode_normal_foreground$keyPostfix") - is Mode.CMD_LINE -> injector.variableService.getVimVariable("widget_mode_command_foreground$keyPostfix") - is Mode.VISUAL -> { - val visualModeBackground = injector.variableService.getVimVariable("widget_mode_visual_foreground$keyPostfix") - when (mode.selectionType) { - SelectionType.CHARACTER_WISE -> visualModeBackground - SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_visual_line_foreground$keyPostfix") ?: visualModeBackground - SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_visual_block_foreground$keyPostfix") ?: visualModeBackground - } - } - is Mode.SELECT -> { - val selectModeBackground = injector.variableService.getVimVariable("widget_mode_select_foreground$keyPostfix") - when (mode.selectionType) { - SelectionType.CHARACTER_WISE -> selectModeBackground - SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_select_line_foreground$keyPostfix") ?: selectModeBackground - SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_select_block_foreground$keyPostfix") ?: selectModeBackground - } - } - is Mode.OP_PENDING, null -> null - }?.asString() - val defaultColor = UIUtil.getLabelForeground() - val color = when (colorString) { - "v:status_bar_bg" -> UIUtil.getPanelBackground() - "v:status_bar_fg" -> UIUtil.getLabelForeground() - else -> { - if (colorString == null) { - defaultColor - } else { - try { Color.decode(colorString) } catch (e: Exception) { defaultColor } - } - } - } - return color - } - - private fun getModeBackground(mode: Mode?): Color { - val keyPostfix = if (LafManager.getInstance().currentUIThemeLookAndFeel.isDark) "_dark" else "_light" - val colorString = when (mode) { - Mode.INSERT -> injector.variableService.getVimVariable("widget_mode_insert_background$keyPostfix") - Mode.REPLACE -> injector.variableService.getVimVariable("widget_mode_replace_background$keyPostfix") - is Mode.NORMAL -> injector.variableService.getVimVariable("widget_mode_normal_background$keyPostfix") - is Mode.CMD_LINE -> injector.variableService.getVimVariable("widget_mode_command_background$keyPostfix") - is Mode.VISUAL -> { - val visualModeBackground = injector.variableService.getVimVariable("widget_mode_visual_background$keyPostfix") - when (mode.selectionType) { - SelectionType.CHARACTER_WISE -> visualModeBackground - SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_visual_line_background$keyPostfix") ?: visualModeBackground - SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_visual_block_background$keyPostfix") ?: visualModeBackground - } - } - is Mode.SELECT -> { - val selectModeBackground = injector.variableService.getVimVariable("widget_mode_select_background$keyPostfix") - when (mode.selectionType) { - SelectionType.CHARACTER_WISE -> selectModeBackground - SelectionType.LINE_WISE -> injector.variableService.getVimVariable("widget_mode_select_line_background$keyPostfix") ?: selectModeBackground - SelectionType.BLOCK_WISE -> injector.variableService.getVimVariable("widget_mode_select_block_background$keyPostfix") ?: selectModeBackground - } - } - is Mode.OP_PENDING, null -> null - }?.asString() - val defaultColor = UIUtil.getPanelBackground() - val color = when (colorString) { - "v:status_bar_bg" -> UIUtil.getPanelBackground() - "v:status_bar_fg" -> UIUtil.getLabelForeground() - else -> { - if (colorString == null) { - defaultColor - } else { - try { Color.decode(colorString) } catch (e: Exception) { defaultColor } - } - } - } - return color - } - private class JBLabelWiderThan(private val words: Collection): JBLabel("", CENTER) { private val wordWidth: Int get() { diff --git a/src/main/java/com/maddyhome/idea/vim/vimscript/services/IjVariableService.kt b/src/main/java/com/maddyhome/idea/vim/vimscript/services/IjVariableService.kt index ccd4bea792..1f5369b8f4 100644 --- a/src/main/java/com/maddyhome/idea/vim/vimscript/services/IjVariableService.kt +++ b/src/main/java/com/maddyhome/idea/vim/vimscript/services/IjVariableService.kt @@ -54,57 +54,6 @@ internal class IjVariableService : VimVariableServiceBase(), PersistentStateComp } } - override fun getVimVariable(name: String): VimDataType? { - val userSetValue = super.getVimVariable(name) - if (userSetValue != null) return userSetValue - - return when (name) { - "widget_mode_normal_background_light" -> VimString("#aed586") - "widget_mode_normal_foreground_light" -> VimString("v:status_bar_fg") - "widget_mode_insert_background_light" -> VimString("#86aed5") - "widget_mode_insert_foreground_light" -> VimString("v:status_bar_fg") - "widget_mode_replace_background_light" -> VimString("#d58686") - "widget_mode_replace_foreground_light" -> VimString("v:status_bar_fg") - "widget_mode_command_background_light" -> VimString("#aed586") - "widget_mode_command_foreground_light" -> VimString("v:status_bar_fg") - "widget_mode_visual_background_light" -> VimString("#d5aed5") - "widget_mode_visual_foreground_light" -> VimString("v:status_bar_fg") -// "widget_mode_visual_line_background_light" -> VimString("") -// "widget_mode_visual_line_foreground_light" -> VimString("v:status_bar_fg") -// "widget_mode_visual_block_background_light" -> VimString("") -// "widget_mode_visual_block_foreground_light" -> VimString("v:status_bar_fg") - "widget_mode_select_background_light" -> VimString("#d5aed5") - "widget_mode_select_foreground_light" -> VimString("v:status_bar_fg") -// "widget_mode_select_line_background_light" -> VimString("") -// "widget_mode_select_line_foreground_light" -> VimString("v:status_bar_fg") -// "widget_mode_select_block_background_light" -> VimString("") -// "widget_mode_select_block_foreground_light" -> VimString("v:status_bar_fg") - - "widget_mode_normal_background_dark" -> VimString("#aed586") - "widget_mode_normal_foreground_dark" -> VimString("v:status_bar_fg") - "widget_mode_insert_background_dark" -> VimString("#86aed5") - "widget_mode_insert_foreground_dark" -> VimString("v:status_bar_fg") - "widget_mode_replace_background_dark" -> VimString("#d58686") - "widget_mode_replace_foreground_dark" -> VimString("v:status_bar_fg") - "widget_mode_command_background_dark" -> VimString("#aed586") - "widget_mode_command_foreground_dark" -> VimString("v:status_bar_fg") - "widget_mode_visual_background_dark" -> VimString("#d5aed5") - "widget_mode_visual_foreground_dark" -> VimString("v:status_bar_fg") -// "widget_mode_visual_line_background_dark" -> VimString("") -// "widget_mode_visual_line_foreground_dark" -> VimString("v:status_bar_fg") -// "widget_mode_visual_block_background_dark" -> VimString("") -// "widget_mode_visual_block_foreground_dark" -> VimString("v:status_bar_fg") - "widget_mode_select_background_dark" -> VimString("#d5aed5") - "widget_mode_select_foreground_dark" -> VimString("v:status_bar_fg") -// "widget_mode_select_line_background_dark" -> VimString("") -// "widget_mode_select_line_foreground_dark" -> VimString("v:status_bar_fg") -// "widget_mode_select_block_background_dark" -> VimString("") -// "widget_mode_select_block_foreground_dark" -> VimString("v:status_bar_fg") - - else -> null - } - } - override fun getState(): Element { val element = Element("variables") saveData(element) @@ -124,6 +73,12 @@ internal class IjVariableService : VimVariableServiceBase(), PersistentStateComp variableElement.setAttribute("value", value.value) variableElement.setAttribute("type", "string") vimVariablesElement.addContent(variableElement) + } else if (value is VimInt) { + val variableElement = Element("variable") + variableElement.setAttribute("key", key) + variableElement.setAttribute("value", value.value.toString()) + variableElement.setAttribute("type", "int") + vimVariablesElement.addContent(variableElement) } } element.addContent(vimVariablesElement) @@ -133,8 +88,14 @@ internal class IjVariableService : VimVariableServiceBase(), PersistentStateComp val vimVariablesElement = element.getChild("vim-variables") val variableElements = vimVariablesElement.getChildren("variable") for (variableElement in variableElements) { - if (variableElement.getAttributeValue("type") != "string") continue - vimVariables[variableElement.getAttributeValue("key")] = VimString(variableElement.getAttributeValue("value")) + when (variableElement.getAttributeValue("type")) { + "string" -> { + vimVariables[variableElement.getAttributeValue("key")] = VimString(variableElement.getAttributeValue("value")) + } + "int" -> { + vimVariables[variableElement.getAttributeValue("key")] = VimInt(variableElement.getAttributeValue("value")) + } + } } } } diff --git a/src/main/resources/messages/IdeaVimBundle.properties b/src/main/resources/messages/IdeaVimBundle.properties index 4a1e1a28bd..83b9289751 100644 --- a/src/main/resources/messages/IdeaVimBundle.properties +++ b/src/main/resources/messages/IdeaVimBundle.properties @@ -135,6 +135,9 @@ widget.mode.popup.title=Mode Widget Colors widget.mode.popup.tab.light=Light Theme widget.mode.popup.tab.dark=Dark Theme widget.mode.popup.color.instruction=Use HEX color values for exact colors; use v:status_bar_bg to use your IDE's status bar background color and v:status_bar_fg for the foreground +widget.mode.popup.field.theme=Widget theme: +widget.mode.popup.field.advanced.settings=Full color customization (advanced) +widget.mode.popup.group.title.full.customization=Full customization widget.mode.popup.group.normal.title=Normal Mode widget.mode.popup.group.insert.title=Insert Mode widget.mode.popup.group.replace.title=Replace Mode @@ -150,7 +153,6 @@ widget.mode.popup.group.select.subgroup.block.title=Select Block widget.mode.popup.field.background=Background: widget.mode.popup.field.foreground=Text: - configurable.name.vim.emulation=Vim configurable.keyhandler.link=Use sethandler command to configure handlers from the .ideavimrc file configurable.noneditablehandler.helper.text.with.example=Non-editable handlers are defined in .ideavimrc file. E.g. ''{0}'' for {1}.