nvim-ts-rainbow icon indicating copy to clipboard operation
nvim-ts-rainbow copied to clipboard

Adapt highlight colours in alignment to used colourscheme

Open lockejan opened this issue 2 years ago • 6 comments

Hey, I noticed that when using colours different from gruvbox (in my case oneDark) with nvim-ts-rainbow, that some bracket highlights result in a really difficult contrast.

Therefore I changed some of the highlight colours to better suit the used color palette. As other plugins are supporting specifying a theme or adapting to the color palette by default, I thought it would be a nice feature addition to have the same for nvim-ts-rainbow.

At the moment it's just an idea and I don't know how much effort is need to achieve it, but I thought dropping it here to see if it's interesting enough for @p00f and others would be a good starting point.✌️

lockejan avatar Feb 04 '22 11:02 lockejan

https://github.com/p00f/nvim-ts-rainbow#colours

p00f avatar Feb 04 '22 11:02 p00f

I have read the readme and you probably misunderstood my explanation.

The goal would be to specify a colour theme without the need to specify the whole colour palette (or not specify a theme at all and it adapts automatically). Lualine for example exposes a theme field in it's config table. (I assume the colour palette is mapped against the string and the colours are part of the plugin resources.🤔)

So instead of colours ={ #abcdef, ...} I'm thinking just theme = "onedark"

lockejan avatar Feb 04 '22 15:02 lockejan

I see, in that case colorschemes can use the rainbowcol1, rainbowcol2, ....rainbowcol7 highlight groups. Quite a few colorschemes do.

Although I'm open to a contrib/themes folder. Implementing this is a good chance to refactor internal.lua

p00f avatar Feb 04 '22 15:02 p00f

I have currently linked the rainbowcolN groups to the rainbow colours of my theme:

vim.cmd 'hi link rainbowcol1 RainbowRed'
vim.cmd 'hi link rainbowcol2 RainbowYellow'
vim.cmd 'hi link rainbowcol3 RainbowBlue'
vim.cmd 'hi link rainbowcol4 RainbowGreen'
vim.cmd 'hi link rainbowcol5 RainbowOrange'
vim.cmd 'hi link rainbowcol6 RainbowCyan'
vim.cmd 'hi link rainbowcol7 RainbowViolet'

I think it's quite awkward and a "theme" table would be a nice solution. I would propose a DSL like this:

  • The theme is a list-like table
  • Each table entry is a colour
  • Each colour is either a string or a table
    • If string, then it is the name of an existing highlight group
    • If table, it is the specification of a highlight group

A highlight group specification is a table whose 1 entry is the name of the group and remainder are the same arguments as vim.api.nvim_set_hl() accepts. Example:

setup {
  -- other stuff...
  rainbow = {
    theme = {
      'RainbowRed',  -- Use existing group
      {'RainbowBlue', guifg='#0000FF' ctermfg='blue' },  -- Create new group
      -- And so on
    }
  }
}

Having the theme as a table allows users to store all values in one variable. The list-like tables allows users to specify however many colours they want, the number of highlight groups is the length of the table. Allowing both strings and tables as table items allows users to reuse their existing highlight groups if they already have some other rainbow-like plugin. Themes can supply their own value or this plugin can include a number of popular themes.

setup {
  -- other stuff...
  rainbow = {
    -- Load an included theme from file
    theme = require 'rainbow.themes.solarized_dark'
  }
}

HiPhish avatar Apr 18 '22 14:04 HiPhish

Hopefully helpful to some onlookers—it isn't the automatic solution the OP was requesting, but it gives me the fine-grained control I would want anyway.

Lua-based themes tend to store their colour palettes in tables. Take tokyo night as an example.

I have a config for each of my colour schems. Here, for the present case.

I have

local colors = require('tokyonight.colors').setup { style = 'night' }

Then later,

  local rainbow_colors = {
    colors.fg,     -- 1
    colors.green,  -- 2
    colors.orange, -- ⋮
    colors.blue1,
    colors.yellow,
    colors.purple,
    colors.blue,
  }

Then set the colours

  require('colors.util').set_rainbow(rainbow_colors)

where my colors.util returns M with

M.set_rainbow = function(colors)
  for i = 1, #colors do
    vim.cmd('highlight rainbowcol' .. i .. ' guifg=' .. colors[i])
  end
end

(I think there's a neovim lua API for setting highlights now, but I haven't gotten around to refactoring.)

timtro avatar Nov 22 '22 23:11 timtro

Here is a thoughtful vimscript snippet to extract highlight colors automagically from the current color scheme: junegunn/rainbow_parentheses.vim

It took many factors into account -- light/dark background, color uniqueness, ansi-16color/xterm-256color/RGB compatibility, optional user-defined blacklist -- which could be a helpful reference when reimplementing similar functions in Lua.

Edit: I forked and patched the vimscript to share its color selections with nvim-ts-rainbow at rainbowcol# highlight groups. This is a dirty hack, but just works.

Arnie97 avatar Dec 17 '22 06:12 Arnie97