mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-06-02 04:34:06 +02:00
VIM-1377 Normal mode needs to be more obvious
Add color customization to mode widget
This commit is contained in:
parent
722cffbd48
commit
a9ededc997
src/main
java/com/maddyhome/idea/vim
resources
vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/services
@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
* 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.openapi.actionSystem.AnAction
|
||||||
|
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.JBScrollPane
|
||||||
|
import com.intellij.ui.components.JBTabbedPane
|
||||||
|
import com.intellij.ui.content.ContentFactory
|
||||||
|
import com.intellij.ui.dsl.builder.RowLayout
|
||||||
|
import com.intellij.ui.dsl.builder.bindText
|
||||||
|
import com.intellij.ui.dsl.builder.panel
|
||||||
|
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 java.awt.BorderLayout
|
||||||
|
import java.awt.Dimension
|
||||||
|
import java.awt.FlowLayout
|
||||||
|
import javax.swing.BorderFactory
|
||||||
|
import javax.swing.JButton
|
||||||
|
import javax.swing.JComponent
|
||||||
|
import javax.swing.JLabel
|
||||||
|
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
|
||||||
|
createPopup().showCenteredInCurrentWindow(project)
|
||||||
|
}
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
public fun createPopup(): JBPopup {
|
||||||
|
val mainPanel = JPanel(BorderLayout())
|
||||||
|
val buttonPanel = JPanel(FlowLayout(FlowLayout.RIGHT))
|
||||||
|
|
||||||
|
val applyButton = JButton("Apply")
|
||||||
|
val cancelButton = JButton("Close")
|
||||||
|
buttonPanel.add(applyButton)
|
||||||
|
buttonPanel.add(cancelButton)
|
||||||
|
mainPanel.add(buttonPanel, BorderLayout.SOUTH)
|
||||||
|
|
||||||
|
val tabbedPane = JBTabbedPane()
|
||||||
|
val lightThemeSettings = createPanel(getWidgetThemeColors(true))
|
||||||
|
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)
|
||||||
|
for (i in 0 until tabbedPane.tabCount) {
|
||||||
|
val label = JLabel(tabbedPane.getTitleAt(i), JLabel.CENTER)
|
||||||
|
label.preferredSize = Dimension(126, tabbedPane.getTabComponentAt(i).preferredSize.height)
|
||||||
|
tabbedPane.setTabComponentAt(i, label)
|
||||||
|
}
|
||||||
|
tabbedPane.selectedIndex = if (LafManager.getInstance().currentUIThemeLookAndFeel.isDark) 1 else 0
|
||||||
|
mainPanel.add(tabbedPane, BorderLayout.CENTER)
|
||||||
|
|
||||||
|
val popupContent = ContentFactory.getInstance().createContent(mainPanel, "", false).component
|
||||||
|
val popup = JBPopupFactory.getInstance()
|
||||||
|
.createComponentPopupBuilder(popupContent, popupContent)
|
||||||
|
.setTitle(MessageHelper.getMessage("widget.mode.popup.title"))
|
||||||
|
.setMovable(true)
|
||||||
|
.setRequestFocus(true)
|
||||||
|
.setCancelOnClickOutside(false)
|
||||||
|
.setCancelKeyEnabled(false)
|
||||||
|
.createPopup()
|
||||||
|
|
||||||
|
applyButton.addActionListener {
|
||||||
|
lightThemeSettings.apply()
|
||||||
|
darkThemeSettings.apply()
|
||||||
|
// todo update widget
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelButton.addActionListener {
|
||||||
|
popup.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
val alarm = Alarm(popup)
|
||||||
|
fun updateApplyButtonVisibility() {
|
||||||
|
alarm.addRequest({
|
||||||
|
applyButton.isEnabled = lightThemeSettings.isModified() || darkThemeSettings.isModified()
|
||||||
|
updateApplyButtonVisibility()
|
||||||
|
}, 500L)
|
||||||
|
}
|
||||||
|
updateApplyButtonVisibility()
|
||||||
|
|
||||||
|
return popup
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getWidgetThemeColors(isLight: Boolean): ModeColors {
|
||||||
|
val keyPostfix = if (isLight) "_light" else "_dark"
|
||||||
|
return ModeColors(
|
||||||
|
"widget_mode_normal_background$keyPostfix",
|
||||||
|
"widget_mode_normal_foreground$keyPostfix",
|
||||||
|
"widget_mode_insert_background$keyPostfix",
|
||||||
|
"widget_mode_insert_foreground$keyPostfix",
|
||||||
|
"widget_mode_replace_background$keyPostfix",
|
||||||
|
"widget_mode_replace_foreground$keyPostfix",
|
||||||
|
"widget_mode_command_background$keyPostfix",
|
||||||
|
"widget_mode_command_foreground$keyPostfix",
|
||||||
|
"widget_mode_visual_background$keyPostfix",
|
||||||
|
"widget_mode_visual_foreground$keyPostfix",
|
||||||
|
"widget_mode_visual_line_background$keyPostfix",
|
||||||
|
"widget_mode_visual_line_foreground$keyPostfix",
|
||||||
|
"widget_mode_visual_block_background$keyPostfix",
|
||||||
|
"widget_mode_visual_block_foreground$keyPostfix",
|
||||||
|
"widget_mode_select_background$keyPostfix",
|
||||||
|
"widget_mode_select_foreground$keyPostfix",
|
||||||
|
"widget_mode_select_line_background$keyPostfix",
|
||||||
|
"widget_mode_select_line_foreground$keyPostfix",
|
||||||
|
"widget_mode_select_block_background$keyPostfix",
|
||||||
|
"widget_mode_select_block_foreground$keyPostfix",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return panel
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JComponent.addScrollPane(): JComponent {
|
||||||
|
val scrollPane = JBScrollPane(this, JBScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JBScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
|
||||||
|
scrollPane.border = BorderFactory.createEmptyBorder()
|
||||||
|
return scrollPane
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ModeColors(
|
||||||
|
normalBgKey: String, normalFgKey: String,
|
||||||
|
insertBgKey: String, insertFgKey: String,
|
||||||
|
replaceBgKey: String, replaceFgKey: String,
|
||||||
|
commandBgKey: String, commandFgKey: String,
|
||||||
|
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<ModeColors, String> {
|
||||||
|
override fun getValue(thisRef: ModeColors, property: KProperty<*>): String {
|
||||||
|
return injector.variableService.getVimVariable(key)?.asString() ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: ModeColors, property: KProperty<*>, value: String) {
|
||||||
|
injector.variableService.storeVimVariable(key, VimString(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,10 +8,12 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.ui.widgets.mode
|
package com.maddyhome.idea.vim.ui.widgets.mode
|
||||||
|
|
||||||
|
import com.intellij.ide.ui.LafManager
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.wm.CustomStatusBarWidget
|
import com.intellij.openapi.wm.CustomStatusBarWidget
|
||||||
|
import com.intellij.ui.awt.RelativePoint
|
||||||
import com.intellij.ui.components.JBLabel
|
import com.intellij.ui.components.JBLabel
|
||||||
import com.intellij.ui.util.width
|
import com.intellij.ui.util.width
|
||||||
import com.intellij.util.ui.UIUtil
|
import com.intellij.util.ui.UIUtil
|
||||||
@ -25,6 +27,9 @@ import com.maddyhome.idea.vim.ui.widgets.mode.listeners.ModeWidgetFocusListener
|
|||||||
import com.maddyhome.idea.vim.ui.widgets.mode.listeners.ModeWidgetModeListener
|
import com.maddyhome.idea.vim.ui.widgets.mode.listeners.ModeWidgetModeListener
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
|
import java.awt.Point
|
||||||
|
import java.awt.event.MouseAdapter
|
||||||
|
import java.awt.event.MouseEvent
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
@ -54,6 +59,19 @@ public class VimModeWidget(public val project: Project) : CustomStatusBarWidget,
|
|||||||
modeChangeListeners.add(ModeWidgetModeListener(this@VimModeWidget))
|
modeChangeListeners.add(ModeWidgetModeListener(this@VimModeWidget))
|
||||||
myEditorListeners.add(ModeWidgetFocusListener(this@VimModeWidget))
|
myEditorListeners.add(ModeWidgetFocusListener(this@VimModeWidget))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label.addMouseListener(object : MouseAdapter() {
|
||||||
|
override fun mouseClicked(e: MouseEvent) {
|
||||||
|
val popup = ModeWidgetPopup.createPopup()
|
||||||
|
val dimension = popup.content.preferredSize
|
||||||
|
|
||||||
|
val widgetLocation = e.component.locationOnScreen
|
||||||
|
popup.show(RelativePoint(Point(
|
||||||
|
widgetLocation.x + e.component.width - dimension.width,
|
||||||
|
widgetLocation.y - dimension.height,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun ID(): String {
|
override fun ID(): String {
|
||||||
@ -112,21 +130,83 @@ public class VimModeWidget(public val project: Project) : CustomStatusBarWidget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getModeForeground(mode: Mode?): Color {
|
private fun getModeForeground(mode: Mode?): Color {
|
||||||
// TODO make it customizable via settings (color picker) or .idevimrc
|
val keyPostfix = if (LafManager.getInstance().currentUIThemeLookAndFeel.isDark) "_dark" else "_light"
|
||||||
return UIUtil.getPanelBackground()
|
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? {
|
private fun getModeBackground(mode: Mode?): Color {
|
||||||
// TODO make it customizable via settings (color picker) or .idevimrc
|
val keyPostfix = if (LafManager.getInstance().currentUIThemeLookAndFeel.isDark) "_dark" else "_light"
|
||||||
return when (mode) {
|
val colorString = when (mode) {
|
||||||
Mode.INSERT -> Color(134, 174, 213)
|
Mode.INSERT -> injector.variableService.getVimVariable("widget_mode_insert_background$keyPostfix")
|
||||||
Mode.REPLACE -> Color(213, 134, 134)
|
Mode.REPLACE -> injector.variableService.getVimVariable("widget_mode_replace_background$keyPostfix")
|
||||||
is Mode.NORMAL -> Color(174, 213, 134)
|
is Mode.NORMAL -> injector.variableService.getVimVariable("widget_mode_normal_background$keyPostfix")
|
||||||
is Mode.CMD_LINE -> Color(174, 213, 134)
|
is Mode.CMD_LINE -> injector.variableService.getVimVariable("widget_mode_command_background$keyPostfix")
|
||||||
is Mode.VISUAL -> Color(213, 174, 213)
|
is Mode.VISUAL -> {
|
||||||
is Mode.SELECT -> Color(213, 174, 213)
|
val visualModeBackground = injector.variableService.getVimVariable("widget_mode_visual_background$keyPostfix")
|
||||||
is Mode.OP_PENDING, null -> label.parent?.background
|
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<String>): JBLabel("", CENTER) {
|
private class JBLabelWiderThan(private val words: Collection<String>): JBLabel("", CENTER) {
|
||||||
|
@ -47,4 +47,55 @@ internal class IjVariableService : VimVariableServiceBase() {
|
|||||||
else -> error("Unexpected")
|
else -> error("Unexpected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,7 @@
|
|||||||
|
|
||||||
<action id="VimShortcutKeyAction" class="com.maddyhome.idea.vim.action.VimShortcutKeyAction"/>
|
<action id="VimShortcutKeyAction" class="com.maddyhome.idea.vim.action.VimShortcutKeyAction"/>
|
||||||
<action id="VimActions" class="com.maddyhome.idea.vim.ui.VimActions"/>
|
<action id="VimActions" class="com.maddyhome.idea.vim.ui.VimActions"/>
|
||||||
|
<action id="CustomizeModeWidget" class="com.maddyhome.idea.vim.ui.widgets.mode.ModeWidgetPopup"/>
|
||||||
|
|
||||||
<group id="IdeaVim.ReloadVimRc.group" class="com.maddyhome.idea.vim.ui.ReloadFloatingToolbarActionGroup">
|
<group id="IdeaVim.ReloadVimRc.group" class="com.maddyhome.idea.vim.ui.ReloadFloatingToolbarActionGroup">
|
||||||
<action id="IdeaVim.ReloadVimRc.reload" class="com.maddyhome.idea.vim.ui.ReloadVimRc"
|
<action id="IdeaVim.ReloadVimRc.reload" class="com.maddyhome.idea.vim.ui.ReloadVimRc"
|
||||||
|
@ -84,6 +84,8 @@ action.VimShortcutKeyAction.text=Shortcuts
|
|||||||
action.VimActions.text=Vim Actions
|
action.VimActions.text=Vim Actions
|
||||||
action.not.found.0=Action not found: {0}
|
action.not.found.0=Action not found: {0}
|
||||||
|
|
||||||
|
action.CustomizeModeWidget.text=Mode Widget Settings
|
||||||
|
|
||||||
action.VimFindActionIdAction.text=IdeaVim: Track Action Ids
|
action.VimFindActionIdAction.text=IdeaVim: Track Action Ids
|
||||||
action.VimFindActionIdAction.description=Starts tracking ids of executed actions
|
action.VimFindActionIdAction.description=Starts tracking ids of executed actions
|
||||||
|
|
||||||
@ -129,6 +131,26 @@ action.finish.eap.text=Finish EAP
|
|||||||
# Don't forget to update README if you modify this entry
|
# Don't forget to update README if you modify this entry
|
||||||
action.subscribe.to.eap.text=Subscribe to EAP
|
action.subscribe.to.eap.text=Subscribe to EAP
|
||||||
|
|
||||||
|
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.group.normal.title=Normal Mode
|
||||||
|
widget.mode.popup.group.insert.title=Insert Mode
|
||||||
|
widget.mode.popup.group.replace.title=Replace Mode
|
||||||
|
widget.mode.popup.group.command.title=Command Mode
|
||||||
|
widget.mode.popup.group.visual.title=Visual Mode
|
||||||
|
widget.mode.popup.group.visual.subgroup.instruction=Leave fields empty to inherit colors from Visual Mode
|
||||||
|
widget.mode.popup.group.visual.subgroup.line.title=Visual Line
|
||||||
|
widget.mode.popup.group.visual.subgroup.block.title=Visual Block
|
||||||
|
widget.mode.popup.group.select.title=Select Mode
|
||||||
|
widget.mode.popup.group.select.subgroup.instruction=Leave fields empty to inherit colors from Select Mode
|
||||||
|
widget.mode.popup.group.select.subgroup.line.title=Select Line
|
||||||
|
widget.mode.popup.group.select.subgroup.block.title=Select Block
|
||||||
|
widget.mode.popup.field.background=Background:
|
||||||
|
widget.mode.popup.field.foreground=Foreground:
|
||||||
|
|
||||||
|
|
||||||
configurable.name.vim.emulation=Vim
|
configurable.name.vim.emulation=Vim
|
||||||
configurable.keyhandler.link=<html>Use <a>sethandler</a> command to configure handlers from the .ideavimrc file</html>
|
configurable.keyhandler.link=<html>Use <a>sethandler</a> command to configure handlers from the .ideavimrc file</html>
|
||||||
configurable.noneditablehandler.helper.text.with.example=Non-editable handlers are defined in .ideavimrc file. E.g. ''{0}'' for {1}.
|
configurable.noneditablehandler.helper.text.with.example=Non-editable handlers are defined in .ideavimrc file. E.g. ''{0}'' for {1}.
|
||||||
|
@ -14,6 +14,7 @@ import com.maddyhome.idea.vim.ex.ExException
|
|||||||
import com.maddyhome.idea.vim.vimscript.model.VimLContext
|
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.VimDataType
|
||||||
import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
|
import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
|
||||||
|
import org.jetbrains.annotations.ApiStatus.Internal
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,4 +110,9 @@ public interface VariableService {
|
|||||||
*/
|
*/
|
||||||
@TestOnly
|
@TestOnly
|
||||||
public fun clear()
|
public fun clear()
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
public fun getVimVariable(name: String): VimDataType?
|
||||||
|
@Internal
|
||||||
|
public fun storeVimVariable(name: String, value: VimDataType)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ public abstract class VimVariableServiceBase : VariableService {
|
|||||||
private val windowVariablesKey = Key<MutableMap<String, VimDataType>>("TabVariables")
|
private val windowVariablesKey = Key<MutableMap<String, VimDataType>>("TabVariables")
|
||||||
private val bufferVariablesKey = Key<MutableMap<String, VimDataType>>("BufferVariables")
|
private val bufferVariablesKey = Key<MutableMap<String, VimDataType>>("BufferVariables")
|
||||||
private val tabVariablesKey = Key<MutableMap<String, VimDataType>>("WindowVariables")
|
private val tabVariablesKey = Key<MutableMap<String, VimDataType>>("WindowVariables")
|
||||||
|
private var vimVariables: MutableMap<String, VimDataType> = mutableMapOf()
|
||||||
|
|
||||||
private fun getWindowVariables(editor: VimEditor) =
|
private fun getWindowVariables(editor: VimEditor) =
|
||||||
injector.vimStorageService.getOrPutWindowData(editor, windowVariablesKey) { mutableMapOf() }
|
injector.vimStorageService.getOrPutWindowData(editor, windowVariablesKey) { mutableMapOf() }
|
||||||
@ -241,4 +242,12 @@ public abstract class VimVariableServiceBase : VariableService {
|
|||||||
override fun clear() {
|
override fun clear() {
|
||||||
globalVariables.clear()
|
globalVariables.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getVimVariable(name: String): VimDataType? {
|
||||||
|
return vimVariables[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun storeVimVariable(name: String, value: VimDataType) {
|
||||||
|
vimVariables[name] = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user