From 2e1049b8ab4f83e5294fbc70724369af1e26c6e9 Mon Sep 17 00:00:00 2001 From: makeworld Date: Fri, 3 Dec 2021 14:58:02 -0500 Subject: [PATCH] Default to using the user's terminal theme colors Issue #181 --- CHANGELOG.md | 2 + config/default.go | 2 + config/theme.go | 226 ++++++++++++++++++++++++++++++++----- contrib/themes/README.md | 8 ++ contrib/themes/amfora.toml | 50 ++++++++ default-config.toml | 2 + go.mod | 2 +- go.sum | 4 +- 8 files changed, 262 insertions(+), 34 deletions(-) create mode 100644 contrib/themes/amfora.toml diff --git a/CHANGELOG.md b/CHANGELOG.md index 7261bd6..10253a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,9 +21,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bookmarks are stored using XML in the XBEL format, old bookmarks are transferred (#68) - Text no longer disappears under the left margin when scrolling (regression in v1.8.0) (#197) - Default search engine changed to geminispace.info from gus.guru +- The user's terminal theme colors are used by default (#181) ## Removed - Favicon support removed (#199) +- The default Amfora theme, get it back [here](https://github.com/makeworld-the-better-one/amfora/blob/master/contrib/themes/amfora.toml) ### Fixed - Help text is now the same color as `regular_text` in the theme config diff --git a/config/default.go b/config/default.go index 9f98f2a..a0b90a6 100644 --- a/config/default.go +++ b/config/default.go @@ -322,6 +322,8 @@ entries_per_page = 20 # Colors can be set using a W3C color name, or a hex value such as "#ffffff". # Setting a background to "default" keeps the terminal default # If your terminal has transparency, set any background to "default" to keep it transparent +# The key "bg" is already set to "default", but this can be used on other backgrounds, +# like for modals. # Note that not all colors will work on terminals that do not have truecolor support. # If you want to stick to the standard 16 or 256 colors, you can get diff --git a/config/theme.go b/config/theme.go index 03e94bc..2a218ea 100644 --- a/config/theme.go +++ b/config/theme.go @@ -8,97 +8,118 @@ import ( ) // Functions to allow themeing configuration. -// UI element colors are mapped to a string key, such as "error" or "tab_bg" +// UI element tcell.Colors are mapped to a string key, such as "error" or "tab_bg" // These are the same keys used in the config file. var themeMu = sync.RWMutex{} var theme = map[string]tcell.Color{ // Default values below + // Only the 16 Xterm system tcell.Colors are used, because those are the tcell.Colors overrided + // by the user's default terminal theme - "bg": tcell.ColorBlack, // Used for cview.Styles.PrimitiveBackgroundColor - "tab_num": tcell.Color30, // xterm:Turquoise4, #008787 + // Used for cview.Styles.PrimitiveBackgroundColor + // Set to tcell.ColorDefault because that allows transparent terminals to work + // The rest of this theme assumes that the background is equivalent to tcell.Color zero, or black. + "bg": tcell.ColorDefault, + + "tab_num": tcell.ColorTeal, "tab_divider": tcell.ColorWhite, - "bottombar_label": tcell.Color30, + "bottombar_label": tcell.ColorTeal, "bottombar_text": tcell.ColorBlack, "bottombar_bg": tcell.ColorWhite, "scrollbar": tcell.ColorWhite, // Modals - "btn_bg": tcell.ColorNavy, // All modal buttons + "btn_bg": tcell.ColorTeal, // All modal buttons "btn_text": tcell.ColorWhite, - "dl_choice_modal_bg": tcell.ColorPurple, + "dl_choice_modal_bg": tcell.ColorOlive, "dl_choice_modal_text": tcell.ColorWhite, - "dl_modal_bg": tcell.Color130, // xterm:DarkOrange3, #af5f00 + "dl_modal_bg": tcell.ColorOlive, "dl_modal_text": tcell.ColorWhite, "info_modal_bg": tcell.ColorGray, "info_modal_text": tcell.ColorWhite, "error_modal_bg": tcell.ColorMaroon, "error_modal_text": tcell.ColorWhite, - "yesno_modal_bg": tcell.ColorPurple, + "yesno_modal_bg": tcell.ColorTeal, "yesno_modal_text": tcell.ColorWhite, "tofu_modal_bg": tcell.ColorMaroon, "tofu_modal_text": tcell.ColorWhite, - "subscription_modal_bg": tcell.Color61, // xterm:SlateBlue3, #5f5faf + "subscription_modal_bg": tcell.ColorTeal, "subscription_modal_text": tcell.ColorWhite, "input_modal_bg": tcell.ColorGreen, "input_modal_text": tcell.ColorWhite, - "input_modal_field_bg": tcell.ColorBlue, + "input_modal_field_bg": tcell.ColorNavy, "input_modal_field_text": tcell.ColorWhite, "bkmk_modal_bg": tcell.ColorTeal, "bkmk_modal_text": tcell.ColorWhite, "bkmk_modal_label": tcell.ColorYellow, - "bkmk_modal_field_bg": tcell.ColorBlue, + "bkmk_modal_field_bg": tcell.ColorNavy, "bkmk_modal_field_text": tcell.ColorWhite, "hdg_1": tcell.ColorRed, "hdg_2": tcell.ColorLime, "hdg_3": tcell.ColorFuchsia, - "amfora_link": tcell.Color33, // xterm:DodgerBlue1, #0087ff - "foreign_link": tcell.Color92, // xterm:DarkViolet, #8700d7 + "amfora_link": tcell.ColorBlue, + "foreign_link": tcell.ColorPurple, "link_number": tcell.ColorSilver, "regular_text": tcell.ColorWhite, "quote_text": tcell.ColorWhite, - "preformatted_text": tcell.Color229, // xterm:Wheat1, #ffffaf + "preformatted_text": tcell.ColorWhite, "list_text": tcell.ColorWhite, } func SetColor(key string, color tcell.Color) { themeMu.Lock() - theme[key] = color + // Use truecolor because this is only called with user-set tcell.Colors + // Which should be represented exactly + theme[key] = color.TrueColor() themeMu.Unlock() } -// GetColor will return tcell.ColorBlack if there is no color for the provided key. +// GetColor will return tcell.ColorBlack if there is no tcell.Color for the provided key. func GetColor(key string) tcell.Color { themeMu.RLock() defer themeMu.RUnlock() - return theme[key].TrueColor() + return theme[key] } -// GetColorString returns a string that can be used in a cview color tag, -// for the given theme key. -// It will return "#000000" if there is no color for the provided key. -func GetColorString(key string) string { - themeMu.RLock() - defer themeMu.RUnlock() - color := theme[key].TrueColor() +// colorToString converts a color to a string for use in a cview tag +func colorToString(color tcell.Color) string { if color == tcell.ColorDefault { return "-" } + + if color&tcell.ColorIsRGB == 0 { + // tcell.Color is not RGB/TrueColor, it's a tcell.Color from the default terminal + // theme as set above + // Return a tcell.Color name instead of a hex code, so that cview doesn't use TrueColor + return ColorToColorName[color] + } + return fmt.Sprintf("#%06x", color.Hex()) } -// GetContrastingColor returns ColorBlack if color is brighter than gray -// otherwise returns ColorWhite if color is dimmer than gray -// if color is ColorDefault (undefined luminance) this returns ColorDefault +// GetColorString returns a string that can be used in a cview tcell.Color tag, +// for the given theme key. +// It will return "#000000" if there is no tcell.Color for the provided key. +func GetColorString(key string) string { + themeMu.RLock() + defer themeMu.RUnlock() + + return colorToString(theme[key]) +} + +// GetContrastingColor returns tcell.ColorBlack if tcell.Color is brighter than gray +// otherwise returns tcell.ColorWhite if tcell.Color is dimmer than gray +// if tcell.Color is tcell.ColorDefault (undefined luminance) this returns tcell.ColorDefault func GetContrastingColor(color tcell.Color) tcell.Color { if color == tcell.ColorDefault { - // color should never be tcell.ColorDefault + // tcell.Color should never be tcell.ColorDefault // only config keys which end in bg are allowed to be set to default - // and the only way the argument of this function is set to ColorDefault + // and the only way the argument of this function is set to tcell.ColorDefault // is if both the text and bg of an element in the UI are set to default return tcell.ColorDefault } @@ -128,6 +149,149 @@ func GetTextColor(key, bg string) tcell.Color { // This happens on focus of a UI element which has a bg of default, in which case // It return tcell.ColorBlack or tcell.ColorWhite, depending on which is more readable func GetTextColorString(key, bg string) string { - color := GetTextColor(key, bg) - return fmt.Sprintf("#%06x", color.Hex()) + return colorToString(GetTextColor(key, bg)) +} + +// Inverted version of a tcell map +// https://github.com/gdamore/tcell/blob/v2.3.3/color.go#L845 +var ColorToColorName = map[tcell.Color]string{ + tcell.ColorBlack: "black", + tcell.ColorMaroon: "maroon", + tcell.ColorGreen: "green", + tcell.ColorOlive: "olive", + tcell.ColorNavy: "navy", + tcell.ColorPurple: "purple", + tcell.ColorTeal: "teal", + tcell.ColorSilver: "silver", + tcell.ColorGray: "gray", + tcell.ColorRed: "red", + tcell.ColorLime: "lime", + tcell.ColorYellow: "yellow", + tcell.ColorBlue: "blue", + tcell.ColorFuchsia: "fuchsia", + tcell.ColorAqua: "aqua", + tcell.ColorWhite: "white", + tcell.ColorAliceBlue: "aliceblue", + tcell.ColorAntiqueWhite: "antiquewhite", + tcell.ColorAquaMarine: "aquamarine", + tcell.ColorAzure: "azure", + tcell.ColorBeige: "beige", + tcell.ColorBisque: "bisque", + tcell.ColorBlanchedAlmond: "blanchedalmond", + tcell.ColorBlueViolet: "blueviolet", + tcell.ColorBrown: "brown", + tcell.ColorBurlyWood: "burlywood", + tcell.ColorCadetBlue: "cadetblue", + tcell.ColorChartreuse: "chartreuse", + tcell.ColorChocolate: "chocolate", + tcell.ColorCoral: "coral", + tcell.ColorCornflowerBlue: "cornflowerblue", + tcell.ColorCornsilk: "cornsilk", + tcell.ColorCrimson: "crimson", + tcell.ColorDarkBlue: "darkblue", + tcell.ColorDarkCyan: "darkcyan", + tcell.ColorDarkGoldenrod: "darkgoldenrod", + tcell.ColorDarkGray: "darkgray", + tcell.ColorDarkGreen: "darkgreen", + tcell.ColorDarkKhaki: "darkkhaki", + tcell.ColorDarkMagenta: "darkmagenta", + tcell.ColorDarkOliveGreen: "darkolivegreen", + tcell.ColorDarkOrange: "darkorange", + tcell.ColorDarkOrchid: "darkorchid", + tcell.ColorDarkRed: "darkred", + tcell.ColorDarkSalmon: "darksalmon", + tcell.ColorDarkSeaGreen: "darkseagreen", + tcell.ColorDarkSlateBlue: "darkslateblue", + tcell.ColorDarkSlateGray: "darkslategray", + tcell.ColorDarkTurquoise: "darkturquoise", + tcell.ColorDarkViolet: "darkviolet", + tcell.ColorDeepPink: "deeppink", + tcell.ColorDeepSkyBlue: "deepskyblue", + tcell.ColorDimGray: "dimgray", + tcell.ColorDodgerBlue: "dodgerblue", + tcell.ColorFireBrick: "firebrick", + tcell.ColorFloralWhite: "floralwhite", + tcell.ColorForestGreen: "forestgreen", + tcell.ColorGainsboro: "gainsboro", + tcell.ColorGhostWhite: "ghostwhite", + tcell.ColorGold: "gold", + tcell.ColorGoldenrod: "goldenrod", + tcell.ColorGreenYellow: "greenyellow", + tcell.ColorHoneydew: "honeydew", + tcell.ColorHotPink: "hotpink", + tcell.ColorIndianRed: "indianred", + tcell.ColorIndigo: "indigo", + tcell.ColorIvory: "ivory", + tcell.ColorKhaki: "khaki", + tcell.ColorLavender: "lavender", + tcell.ColorLavenderBlush: "lavenderblush", + tcell.ColorLawnGreen: "lawngreen", + tcell.ColorLemonChiffon: "lemonchiffon", + tcell.ColorLightBlue: "lightblue", + tcell.ColorLightCoral: "lightcoral", + tcell.ColorLightCyan: "lightcyan", + tcell.ColorLightGoldenrodYellow: "lightgoldenrodyellow", + tcell.ColorLightGray: "lightgray", + tcell.ColorLightGreen: "lightgreen", + tcell.ColorLightPink: "lightpink", + tcell.ColorLightSalmon: "lightsalmon", + tcell.ColorLightSeaGreen: "lightseagreen", + tcell.ColorLightSkyBlue: "lightskyblue", + tcell.ColorLightSlateGray: "lightslategray", + tcell.ColorLightSteelBlue: "lightsteelblue", + tcell.ColorLightYellow: "lightyellow", + tcell.ColorLimeGreen: "limegreen", + tcell.ColorLinen: "linen", + tcell.ColorMediumAquamarine: "mediumaquamarine", + tcell.ColorMediumBlue: "mediumblue", + tcell.ColorMediumOrchid: "mediumorchid", + tcell.ColorMediumPurple: "mediumpurple", + tcell.ColorMediumSeaGreen: "mediumseagreen", + tcell.ColorMediumSlateBlue: "mediumslateblue", + tcell.ColorMediumSpringGreen: "mediumspringgreen", + tcell.ColorMediumTurquoise: "mediumturquoise", + tcell.ColorMediumVioletRed: "mediumvioletred", + tcell.ColorMidnightBlue: "midnightblue", + tcell.ColorMintCream: "mintcream", + tcell.ColorMistyRose: "mistyrose", + tcell.ColorMoccasin: "moccasin", + tcell.ColorNavajoWhite: "navajowhite", + tcell.ColorOldLace: "oldlace", + tcell.ColorOliveDrab: "olivedrab", + tcell.ColorOrange: "orange", + tcell.ColorOrangeRed: "orangered", + tcell.ColorOrchid: "orchid", + tcell.ColorPaleGoldenrod: "palegoldenrod", + tcell.ColorPaleGreen: "palegreen", + tcell.ColorPaleTurquoise: "paleturquoise", + tcell.ColorPaleVioletRed: "palevioletred", + tcell.ColorPapayaWhip: "papayawhip", + tcell.ColorPeachPuff: "peachpuff", + tcell.ColorPeru: "peru", + tcell.ColorPink: "pink", + tcell.ColorPlum: "plum", + tcell.ColorPowderBlue: "powderblue", + tcell.ColorRebeccaPurple: "rebeccapurple", + tcell.ColorRosyBrown: "rosybrown", + tcell.ColorRoyalBlue: "royalblue", + tcell.ColorSaddleBrown: "saddlebrown", + tcell.ColorSalmon: "salmon", + tcell.ColorSandyBrown: "sandybrown", + tcell.ColorSeaGreen: "seagreen", + tcell.ColorSeashell: "seashell", + tcell.ColorSienna: "sienna", + tcell.ColorSkyblue: "skyblue", + tcell.ColorSlateBlue: "slateblue", + tcell.ColorSlateGray: "slategray", + tcell.ColorSnow: "snow", + tcell.ColorSpringGreen: "springgreen", + tcell.ColorSteelBlue: "steelblue", + tcell.ColorTan: "tan", + tcell.ColorThistle: "thistle", + tcell.ColorTomato: "tomato", + tcell.ColorTurquoise: "turquoise", + tcell.ColorViolet: "violet", + tcell.ColorWheat: "wheat", + tcell.ColorWhiteSmoke: "whitesmoke", + tcell.ColorYellowGreen: "yellowgreen", } diff --git a/contrib/themes/README.md b/contrib/themes/README.md index 8754fb8..c3fa6da 100644 --- a/contrib/themes/README.md +++ b/contrib/themes/README.md @@ -2,6 +2,14 @@ You can use these themes by replacing the `[theme]` section of your [config](https://github.com/makeworld-the-better-one/amfora/wiki/Configuration) with their contents. Some themes won't display properly on terminals that do not have truecolor support. +## Amfora + +This is the original Amfora theme we all know and love. From v1.9.0 and onwards, the user's terminal theme is used by default. Use this theme to restore the original Amfora look. + + +Demo GIF + + ## Nord Contributed by **[@lokesh-krishna](https://github.com/lokesh-krishna)**. diff --git a/contrib/themes/amfora.toml b/contrib/themes/amfora.toml new file mode 100644 index 0000000..0cff44a --- /dev/null +++ b/contrib/themes/amfora.toml @@ -0,0 +1,50 @@ +[theme] + +# Only the 256 xterm colors are used, so truecolor support is not needed + +bg = "black" +tab_num = "#008787" +tab_divider = "white" +bottombar_label = "#008787" +bottombar_text = "black" +bottombar_bg = "white" +scrollbar = "white" + +btn_bg = "#000080" +btn_text = "white" + +dl_choice_modal_bg = "#800080" +dl_choice_modal_text = "white" +dl_modal_bg = "#af5f00" +dl_modal_text = "white" +info_modal_bg = "#808080" +info_modal_text = "white" +error_modal_bg = "#800000" +error_modal_text = "white" +yesno_modal_bg = "#800080" +yesno_modal_text = "white" +tofu_modal_bg = "#800000" +tofu_modal_text = "white" +subscription_modal_bg = "#5f5faf" +subscription_modal_text = "white" +input_modal_bg = "#008000" +input_modal_text = "white" +input_modal_field_bg = "#0000ff" +input_modal_field_text = "white" + +bkmk_modal_bg = "#008080" +bkmk_modal_text = "white" +bkmk_modal_label = "#ffff00" +bkmk_modal_field_bg = "#0000ff" +bkmk_modal_field_text = "white" + +hdg_1 = "#ff0000" +hdg_2 = "#00ff00" +hdg_3 = "#ff00ff" +amfora_link = "#0087ff" +foreign_link = "#8700d7" +link_number = "#c0c0c0" +regular_text = "white" +quote_text = "white" +preformatted_text = "#ffffaf" +list_text = "white" diff --git a/default-config.toml b/default-config.toml index 09ceb3f..e282219 100644 --- a/default-config.toml +++ b/default-config.toml @@ -319,6 +319,8 @@ entries_per_page = 20 # Colors can be set using a W3C color name, or a hex value such as "#ffffff". # Setting a background to "default" keeps the terminal default # If your terminal has transparency, set any background to "default" to keep it transparent +# The key "bg" is already set to "default", but this can be used on other backgrounds, +# like for modals. # Note that not all colors will work on terminals that do not have truecolor support. # If you want to stick to the standard 16 or 256 colors, you can get diff --git a/go.mod b/go.mod index 0a71e48..d24ce2d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/makeworld-the-better-one/amfora go 1.15 require ( - code.rocketnine.space/tslocum/cview v1.5.6-0.20210525194531-92dca67ac283 + code.rocketnine.space/tslocum/cview v1.5.6-0.20210530175404-7e8817f20bdc github.com/atotto/clipboard v0.1.4 github.com/dustin/go-humanize v1.0.0 github.com/fsnotify/fsnotify v1.4.9 // indirect diff --git a/go.sum b/go.sum index 8655c1f..491117a 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,8 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= code.rocketnine.space/tslocum/cbind v0.1.5 h1:i6NkeLLNPNMS4NWNi3302Ay3zSU6MrqOT+yJskiodxE= code.rocketnine.space/tslocum/cbind v0.1.5/go.mod h1:LtfqJTzM7qhg88nAvNhx+VnTjZ0SXBJtxBObbfBWo/M= -code.rocketnine.space/tslocum/cview v1.5.6-0.20210525194531-92dca67ac283 h1:5KBGXdQdfV09eYXOZuFTxqDujndqtRraXj+lyFcxlPk= -code.rocketnine.space/tslocum/cview v1.5.6-0.20210525194531-92dca67ac283/go.mod h1:KBRxzIsj8bfgFpnMpkGVoxsrPUvnQsRnX29XJ2yzB6M= +code.rocketnine.space/tslocum/cview v1.5.6-0.20210530175404-7e8817f20bdc h1:nAcBp7ZCWHpa8fHpynCbULDTAZgPQv28+Z+QnhnFG7E= +code.rocketnine.space/tslocum/cview v1.5.6-0.20210530175404-7e8817f20bdc/go.mod h1:KBRxzIsj8bfgFpnMpkGVoxsrPUvnQsRnX29XJ2yzB6M= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=