1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-05-07 13:34:02 +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

@ -321,7 +321,10 @@ 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.
`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
</details>

View File

@ -47,6 +47,10 @@ private val HIGHLIGHT_DURATION_VARIABLE_NAME = "highlightedyank_highlight_durati
@NonNls
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 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.
* 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.
*/
internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeListener {
@ -186,13 +193,15 @@ internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeLis
highlighters.clear()
}
private fun getHighlightTextAttributes(editor: Editor) = TextAttributes(
null,
extractUsersHighlightColor(),
editor.colorsScheme.getColor(EditorColors.CARET_COLOR),
EffectType.SEARCH_MATCH,
Font.PLAIN,
)
private fun getHighlightTextAttributes(editor: Editor): TextAttributes {
return TextAttributes(
extractUserHighlightForegroundColor(),
extractUsersHighlightColor(),
editor.colorsScheme.getColor(EditorColors.CARET_COLOR),
EffectType.SEARCH_MATCH,
Font.PLAIN,
)
}
private fun extractUsersHighlightDuration(): Int {
return extractVariable(HIGHLIGHT_DURATION_VARIABLE_NAME, DEFAULT_HIGHLIGHT_DURATION) {
@ -205,15 +214,52 @@ internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeLis
}
private fun extractUsersHighlightColor(): Color {
return extractVariable(HIGHLIGHT_COLOR_VARIABLE_NAME, getDefaultHighlightTextColor()) { value ->
val rgba = value.asString()
.substring(4)
.filter { it != '(' && it != ')' && !it.isWhitespace() }
.split(',')
.map { it.toInt() }
Color(rgba[0], rgba[1], rgba[2], rgba[3])
val value = VimPlugin.getVariableService().getGlobalVariableValue(HIGHLIGHT_COLOR_VARIABLE_NAME)
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)
.filter { it != '(' && it != ')' && !it.isWhitespace() }
.split(',')
.map { it.toInt() }
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 {
@ -236,4 +282,4 @@ internal class VimHighlightedYank : VimExtension, VimYankListener, ModeChangeLis
return default
}
}
}
}

View File

@ -8,6 +8,7 @@
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.util.TextRange
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 = """
fun ${c}sum(x: Int, y: Int, z: Int): Int {
return x + y + z