Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling to work with a 256 color terminal #363

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 94 additions & 57 deletions lua/gruvbox.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,60 +71,59 @@ Gruvbox.config = {
-- main gruvbox color palette
---@class GruvboxPalette
Gruvbox.palette = {
dark0_hard = "#1d2021",
dark0 = "#282828",
dark0_soft = "#32302f",
dark1 = "#3c3836",
dark2 = "#504945",
dark3 = "#665c54",
dark4 = "#7c6f64",
light0_hard = "#f9f5d7",
light0 = "#fbf1c7",
light0_soft = "#f2e5bc",
light1 = "#ebdbb2",
light2 = "#d5c4a1",
light3 = "#bdae93",
light4 = "#a89984",
bright_red = "#fb4934",
bright_green = "#b8bb26",
bright_yellow = "#fabd2f",
bright_blue = "#83a598",
bright_purple = "#d3869b",
bright_aqua = "#8ec07c",
bright_orange = "#fe8019",
neutral_red = "#cc241d",
neutral_green = "#98971a",
neutral_yellow = "#d79921",
neutral_blue = "#458588",
neutral_purple = "#b16286",
neutral_aqua = "#689d6a",
neutral_orange = "#d65d0e",
faded_red = "#9d0006",
faded_green = "#79740e",
faded_yellow = "#b57614",
faded_blue = "#076678",
faded_purple = "#8f3f71",
faded_aqua = "#427b58",
faded_orange = "#af3a03",
dark_red_hard = "#792329",
dark_red = "#722529",
dark_red_soft = "#7b2c2f",
light_red_hard = "#fc9690",
light_red = "#fc9487",
light_red_soft = "#f78b7f",
dark_green_hard = "#5a633a",
dark_green = "#62693e",
dark_green_soft = "#686d43",
light_green_hard = "#d3d6a5",
light_green = "#d5d39b",
light_green_soft = "#cecb94",
dark_aqua_hard = "#3e4934",
dark_aqua = "#49503b",
dark_aqua_soft = "#525742",
light_aqua_hard = "#e6e9c1",
light_aqua = "#e8e5b5",
light_aqua_soft = "#e1dbac",
gray = "#928374",
dark0 = { ["gui"] = "#282828", ["cterm"] = 235 },
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it easier to read this way? --

Suggested change
dark0 = { ["gui"] = "#282828", ["cterm"] = 235 },
dark0 = { gui = "#282828", cterm = 235 },

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This patch removes dark0_hard for whatever reason.

  2. why not structure this as:

Gruvbox.palette = {
  gui = {
    dark0_hard = "#1d2021",
    dark0 = "#282828",
    ...
  },
  cterm = {
    dark0_hard = 235,
    dark0 = 235,
    ...
  }
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing.

  1. Readibility without brackets: I fully agree. Sorry, it is the first time I'm coding lua and I thought for some reason that the brackets ought to be there. Anyhow, corrected now in the most recent commit.
  2. removal of dark0_hard was unintentional, thanks for spotting that. Corrected in the most recent commit.
  3. There were three reasons for it in my mind. First, it's supposed to be the same color, so it feels natural to have one key that then is used to access the same color for two different ways to configure the color. Second, the names are used eg. in the color groups. I felt it would require many more changes in the code and would result in a lot of overhead code. Now it the main logic is the same and at the end, for all highlights, a conversion expands into gui or cterm. The third reason is maintainability. It is much better to have the two values close to each other in the code. If you change the gui value, you see you need to adapt the cterm value as well. What would be your argument for changing it that way?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The advantage of the proposed structure is a vast simplification of the patch: the entire expand_colors_in_highlights() becomes unnecessarily as the correct palette can be returned from get_colors() depending on the value of vim.o.termguicolors, everything else (excluding your patch in L1242) can remain the same as before.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jomade Here's what I could come up with -- lxv@eae39ed -- I'm not entirely sure if it's that much better than your version. It's disappointing that unlike vim_get_hl_by_name() which allows users to specify GUI/TUI flag in the 2nd arg, nvim_set_hl() doesn't support that (ref: https://github.com/neovim/neovim/blob/master/test/functional/api/highlight_spec.lua)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NVM, my version breaks runtime changes termguicolors <-> notermguicolors because it only has access to either cterm or gui color value at a time. I'm sorry about the noise.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries.
Btw, I know see that I probably can make the expansion function more compact. Let's see if I can get that done on one of the next evenings. Sth along the lines (not tested):

local function expand_highlight_prop(hl, prop)
   if hl.[prop] == nil then return end
   if hl.[prob] == "NONE" then
     if prop != "sp" then 
          hl.["cterm"..prop] = "NONE"
     end
     hl.[prop] = "NONE"
   else 
     hl.["cterm"..prop] = hl.[prop].cterm
     hl.[prop] = hl.[prop].gui
   end
end

And then call the function for "fg", "bg" and "sp".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my recent upgrade. I have compacted the code as outlined here (minus the bugs in the displayed code...)

dark0_soft = { ["gui"] = "#32302f", ["cterm"] = 236 },
dark1 = { ["gui"] = "#3c3836", ["cterm"] = 237 },
dark2 = { ["gui"] = "#504945", ["cterm"] = 239 },
dark3 = { ["gui"] = "#665c54", ["cterm"] = 59 },
dark4 = { ["gui"] = "#7c6f64", ["cterm"] = 242 },
light0_hard = { ["gui"] = "#f9f5d7", ["cterm"] = 230 },
light0 = { ["gui"] = "#fbf1c7", ["cterm"] = 230 },
light0_soft = { ["gui"] = "#f2e5bc", ["cterm"] = 223 },
light1 = { ["gui"] = "#ebdbb2", ["cterm"] = 187 },
light2 = { ["gui"] = "#d5c4a1", ["cterm"] = 187 },
light3 = { ["gui"] = "#bdae93", ["cterm"] = 144 },
light4 = { ["gui"] = "#a89984", ["cterm"] = 138 },
bright_red = { ["gui"] = "#fb4934", ["cterm"] = 203 },
bright_green = { ["gui"] = "#b8bb26", ["cterm"] = 142 },
bright_yellow = { ["gui"] = "#fabd2f", ["cterm"] = 214 },
bright_blue = { ["gui"] = "#83a598", ["cterm"] = 108 },
bright_purple = { ["gui"] = "#d3869b", ["cterm"] = 174 },
bright_aqua = { ["gui"] = "#8ec07c", ["cterm"] = 108 },
bright_orange = { ["gui"] = "#fe8019", ["cterm"] = 208 },
neutral_red = { ["gui"] = "#cc241d", ["cterm"] = 160 },
neutral_green = { ["gui"] = "#98971a", ["cterm"] = 100 },
neutral_yellow = { ["gui"] = "#d79921", ["cterm"] = 172 },
neutral_blue = { ["gui"] = "#458588", ["cterm"] = 66 },
neutral_purple = { ["gui"] = "#b16286", ["cterm"] = 132 },
neutral_aqua = { ["gui"] = "#689d6a", ["cterm"] = 71 },
neutral_orange = { ["gui"] = "#d65d0e", ["cterm"] = 166 },
faded_red = { ["gui"] = "#9d0006", ["cterm"] = 124 },
faded_green = { ["gui"] = "#79740e", ["cterm"] = 100 },
faded_yellow = { ["gui"] = "#b57614", ["cterm"] = 136 },
faded_blue = { ["gui"] = "#076678", ["cterm"] = 24 },
faded_purple = { ["gui"] = "#8f3f71", ["cterm"] = 95 },
faded_aqua = { ["gui"] = "#427b58", ["cterm"] = 65 },
faded_orange = { ["gui"] = "#af3a03", ["cterm"] = 130 },
dark_red_hard = { ["gui"] = "#792329", ["cterm"] = 88 },
dark_red = { ["gui"] = "#722529", ["cterm"] = 237 },
dark_red_soft = { ["gui"] = "#7b2c2f", ["cterm"] = 238 },
light_red_hard = { ["gui"] = "#fc9690", ["cterm"] = 210 },
light_red = { ["gui"] = "#fc9487", ["cterm"] = 210 },
light_red_soft = { ["gui"] = "#f78b7f", ["cterm"] = 210 },
dark_green_hard = { ["gui"] = "#5a633a", ["cterm"] = 240 },
dark_green = { ["gui"] = "#62693e", ["cterm"] = 240 },
dark_green_soft = { ["gui"] = "#686d43", ["cterm"] = 59 },
light_green_hard = { ["gui"] = "#d3d6a5", ["cterm"] = 187 },
light_green = { ["gui"] = "#d5d39b", ["cterm"] = 186 },
light_green_soft = { ["gui"] = "#cecb94", ["cterm"] = 186 },
dark_aqua_hard = { ["gui"] = "#3e4934", ["cterm"] = 238 },
dark_aqua = { ["gui"] = "#49503b", ["cterm"] = 238 },
dark_aqua_soft = { ["gui"] = "#525742", ["cterm"] = 239 },
light_aqua_hard = { ["gui"] = "#e6e9c1", ["cterm"] = 187 },
light_aqua = { ["gui"] = "#e8e5b5", ["cterm"] = 187 },
light_aqua_soft = { ["gui"] = "#e1dbac", ["cterm"] = 187 },
gray = { ["gui"] = "#928374", ["cterm"] = 244 }
}

-- get a hex list of gruvbox colors based on current bg and constrast config
Expand Down Expand Up @@ -210,11 +209,48 @@ local function get_colors()
return color_groups[bg]
end

-- apply gui and cterm colors to the highlight groups given as an argument.
-- function works in-place, thus hl_groups will be altered
local function expand_colors_in_highlights(hl_groups)
-- iterate over highlights
for k,hl in pairs(hl_groups) do
-- check if foreground value is set and expand and replace
if hl.fg ~= nil then
if hl.fg == "NONE" then
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to explicitly set it to "NONE" if they are empty?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the entry is empty/nil it will not be set.
If it is not nil, then it is evaluated if a colorname or "NONE" was supplied and expanded or not dependent on the content.

This clause is introduced since there is one entry in the palette "@none" where fg="NONE". That would cause the lookup to fail as "NONE" is not a color name. However that would be a different way to resolve that.

Does that make it more clear? Thanks for looking into this!

hl.ctermfg = "NONE"
hl.fg = "NONE"
else
hl.ctermfg = hl.fg.cterm
hl.fg = hl.fg.gui
end
end
-- check if background value is set and expand and replace
if hl.bg ~= nil then
if hl.bg == "NONE" then
hl.ctermbg = "NONE"
hl.bg = "NONE"
else
hl.ctermbg = hl.bg.cterm
hl.bg = hl.bg.gui
end
end
-- check if background value is set and expand and replace
if hl.sp ~= nil then
if hl.sp == "NONE" then
hl.sp = "NONE"
else
hl.sp = hl.sp.gui
end
end
end
end

local function get_groups()
local colors = get_colors()
local config = Gruvbox.config

if config.terminal_colors then
-- setting terminal colors is only supported for RGB
if config.terminal_colors and vim.o.termguicolors then
local term_colors = {
colors.bg0,
colors.neutral_red,
Expand All @@ -234,7 +270,7 @@ local function get_groups()
colors.fg1,
}
for index, value in ipairs(term_colors) do
vim.g["terminal_color_" .. index - 1] = value
vim.g["terminal_color_" .. index - 1] = value.gui
end
end

Expand Down Expand Up @@ -1219,6 +1255,8 @@ local function get_groups()
groups[group] = vim.tbl_extend("force", groups[group] or {}, hl)
end

expand_colors_in_highlights(groups)

return groups
end

Expand All @@ -1239,7 +1277,6 @@ Gruvbox.load = function()
vim.cmd.hi("clear")
end
vim.g.colors_name = "gruvbox"
vim.o.termguicolors = true
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you removing this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood this line as it will enable termgui-options without possibility for the user to disable it - is this correct?
Nvim will ignore the cterm-colors if the option is set. So for the 256-colors, the option needs to be disabled.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have another proposal how to allow for the user to switch off termguicolors?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood this line as it will enable termgui-options without possibility for the user to disable it - is this correct?

that's correct but I am also worried about the users who already have the plugin in place who doesn't have this enabled yet. I will see if we have a better way to check this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a valid concern. I also think it should be default with termguicolors - that's the future anyway.
Is it possible to get it in as a config variable? I have not fully understood how the configuration system works ... But a config switch to turn on 256 colors and disable the automatic termguicolors could work well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my most recent commit. I added a config option.


local groups = get_groups()

Expand Down