1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-08-02 09:59:07 +02:00

Add ability to set the highlightedyank foreground color

This commit is contained in:
Julien Phalip 2024-11-08 15:08:43 -08:00 committed by lippfi
parent 365b58eb56
commit 5db2984fdd
3 changed files with 145 additions and 17 deletions
doc
src
main/java/com/maddyhome/idea/vim/extension/highlightedyank
test/java/org/jetbrains/plugins/ideavim/extension/highlightedyank

View File

@ -322,6 +322,9 @@ If you want to optimize highlight duration, assign a time in milliseconds:
If you want to change background color of highlight you can provide the rgba of the color you want e.g. If you want to change background color of highlight you can provide the rgba of the color you want e.g.
`let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"` `let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"`
If you want to change text color of highlight you can provide the rgba of the color you want e.g.
`let g:highlightedyank_highlight_foreground_color = "rgba(0, 0, 0, 255)"`
https://github.com/machakann/vim-highlightedyank/blob/master/doc/highlightedyank.txt https://github.com/machakann/vim-highlightedyank/blob/master/doc/highlightedyank.txt
</details> </details>

View File

@ -47,6 +47,10 @@ private val HIGHLIGHT_DURATION_VARIABLE_NAME = "highlightedyank_highlight_durati
@NonNls @NonNls
private val HIGHLIGHT_COLOR_VARIABLE_NAME = "highlightedyank_highlight_color" private val HIGHLIGHT_COLOR_VARIABLE_NAME = "highlightedyank_highlight_color"
@NonNls
private val HIGHLIGHT_FOREGROUND_COLOR_VARIABLE_NAME = "highlightedyank_highlight_foreground_color"
private var defaultHighlightTextColor: Color? = null private var defaultHighlightTextColor: Color? = null
private fun getDefaultHighlightTextColor(): Color { private fun getDefaultHighlightTextColor(): Color {
@ -77,6 +81,9 @@ internal class HighlightColorResetter : LafManagerListener {
* if you want to change background color of highlight you can provide the rgba of the color you want e.g. * if you want to change background color of highlight you can provide the rgba of the color you want e.g.
* let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)" * let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"
* *
* if you want to change text color of highlight you can provide the rgba of the color you want e.g.
* let g:highlightedyank_highlight_foreground_color = "rgba(0, 0, 0, 255)"
*
* When a new text is yanked or user starts editing, the old highlighting would be deleted. * When a new text is yanked or user starts editing, the old highlighting would be deleted.
*/ */
internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeListener { internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeListener {
@ -186,13 +193,15 @@ internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeLis
highlighters.clear() highlighters.clear()
} }
private fun getHighlightTextAttributes(editor: Editor) = TextAttributes( private fun getHighlightTextAttributes(editor: Editor): TextAttributes {
null, return TextAttributes(
extractUserHighlightForegroundColor(),
extractUsersHighlightColor(), extractUsersHighlightColor(),
editor.colorsScheme.getColor(EditorColors.CARET_COLOR), editor.colorsScheme.getColor(EditorColors.CARET_COLOR),
EffectType.SEARCH_MATCH, EffectType.SEARCH_MATCH,
Font.PLAIN, Font.PLAIN,
) )
}
private fun extractUsersHighlightDuration(): Int { private fun extractUsersHighlightDuration(): Int {
return extractVariable(HIGHLIGHT_DURATION_VARIABLE_NAME, DEFAULT_HIGHLIGHT_DURATION) { return extractVariable(HIGHLIGHT_DURATION_VARIABLE_NAME, DEFAULT_HIGHLIGHT_DURATION) {
@ -205,15 +214,52 @@ internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeLis
} }
private fun extractUsersHighlightColor(): Color { private fun extractUsersHighlightColor(): Color {
return extractVariable(HIGHLIGHT_COLOR_VARIABLE_NAME, getDefaultHighlightTextColor()) { value -> val value = VimPlugin.getVariableService().getGlobalVariableValue(HIGHLIGHT_COLOR_VARIABLE_NAME)
val rgba = value.asString() if (value != null) {
return try {
parseRgbaColor(value.asString())
} catch (e: Exception) {
@VimNlsSafe val message = MessageHelper.message(
"highlightedyank.invalid.value.of.0.1",
"g:$HIGHLIGHT_COLOR_VARIABLE_NAME",
e.message ?: "",
)
VimPlugin.showMessage(message)
getDefaultHighlightTextColor()
}
}
return getDefaultHighlightTextColor()
}
private fun extractUserHighlightForegroundColor(): Color? {
val value = VimPlugin.getVariableService().getGlobalVariableValue(HIGHLIGHT_FOREGROUND_COLOR_VARIABLE_NAME)
?: return null
return try {
parseRgbaColor(value.asString())
} catch (e: Exception) {
@VimNlsSafe val message = MessageHelper.message(
"highlightedyank.invalid.value.of.0.1",
"g:$HIGHLIGHT_FOREGROUND_COLOR_VARIABLE_NAME",
e.message ?: "",
)
VimPlugin.showMessage(message)
null
}
}
private fun parseRgbaColor(colorString: String): Color {
val rgba = colorString
.substring(4) .substring(4)
.filter { it != '(' && it != ')' && !it.isWhitespace() } .filter { it != '(' && it != ')' && !it.isWhitespace() }
.split(',') .split(',')
.map { it.toInt() } .map { it.toInt() }
Color(rgba[0], rgba[1], rgba[2], rgba[3]) if (rgba.size != 4 || rgba.any { it < 0 || it > 255 }) {
throw IllegalArgumentException("Invalid RGBA values. Each component must be between 0 and 255")
} }
return Color(rgba[0], rgba[1], rgba[2], rgba[3])
} }
private fun <T> extractVariable(variable: String, default: T, extractFun: (value: VimDataType) -> T): T { private fun <T> extractVariable(variable: String, default: T, extractFun: (value: VimDataType) -> T): T {

View File

@ -8,6 +8,7 @@
package org.jetbrains.plugins.ideavim.extension.highlightedyank package org.jetbrains.plugins.ideavim.extension.highlightedyank
import com.intellij.openapi.editor.colors.EditorColors
import com.intellij.openapi.editor.markup.RangeHighlighter import com.intellij.openapi.editor.markup.RangeHighlighter
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.maddyhome.idea.vim.VimPlugin import com.maddyhome.idea.vim.VimPlugin
@ -182,6 +183,84 @@ class VimHighlightedYankTest : VimTestCase() {
} }
} }
@Test
fun `test no foreground color used when not explicitly provided`() {
configureByText(code)
typeText("yy")
val attributes = getFirstHighlighter().getTextAttributes(null)
assertEquals(null, attributes?.foregroundColor)
}
@Test
fun `test custom foreground colour used when provided by user`() {
configureByText(code)
enterCommand("let g:highlightedyank_highlight_foreground_color=\"rgba(100,10,20,30)\"")
typeText("yy")
val highlighter = getFirstHighlighter()
assertEquals(Color(100, 10, 20, 30), highlighter.getTextAttributes(null)?.foregroundColor)
}
@Test
fun `test indicating error when incorrect background highlight color was provided by user`() {
configureByText(code)
listOf(
"rgba(1,2,3)",
"rgba(1, 2, 3, 0.1)",
"rgb(1,2,3)",
"rgba(260, 2, 5, 6)",
"rgba(0, 0, 0, 300)"
).forEach { color ->
enterCommand("let g:highlightedyank_highlight_color = \"$color\"")
typeText("yy")
assertTrue(
VimPlugin.getMessage().contains("highlightedyank: Invalid value of g:highlightedyank_highlight_color"),
color,
)
// Should fall back to default background color when there's an error
val defaultColor = EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES.defaultAttributes.backgroundColor
assertEquals(defaultColor, getFirstHighlighter().getTextAttributes(null)?.backgroundColor)
}
}
@Test
fun `test indicating error when incorrect foreground highlight color was provided by user`() {
configureByText(code)
listOf(
"rgba(1,2,3)",
"rgba(1, 2, 3, 0.1)",
"rgb(1,2,3)",
"rgba(260, 2, 5, 6)",
"rgba(0, 0, 0, 300)"
).forEach { color ->
enterCommand("let g:highlightedyank_highlight_foreground_color = \"$color\"")
typeText("yy")
assertTrue(
VimPlugin.getMessage().contains("highlightedyank: Invalid value of g:highlightedyank_highlight_foreground_color"),
color,
)
// Should not set a foreground color when there's an error
assertEquals(null, getFirstHighlighter().getTextAttributes(null)?.foregroundColor)
}
}
@Test
fun `test both foreground and background colors can be set simultaneously`() {
configureByText(code)
enterCommand("let g:highlightedyank_highlight_foreground_color=\"rgba(255,0,0,255)\"")
enterCommand("let g:highlightedyank_highlight_color=\"rgba(0,255,0,128)\"")
typeText("yy")
val attributes = getFirstHighlighter().getTextAttributes(null)
assertEquals(Color(255, 0, 0, 255), attributes?.foregroundColor)
assertEquals(Color(0, 255, 0, 128), attributes?.backgroundColor)
}
private val code = """ private val code = """
fun ${c}sum(x: Int, y: Int, z: Int): Int { fun ${c}sum(x: Int, y: Int, z: Int): Int {
return x + y + z return x + y + z