rasulomaroff / reactive.nvim

Reactivity. Right in your neovim.
Apache License 2.0
183 stars 1 forks source link

Help with highlighting statuscol/status column icon background #16

Open Ajaymamtora opened 2 months ago

Ajaymamtora commented 2 months ago

When I use statuscol.nvim to define extra columns, the extra ones are highlighted:

image

https://github.com/luukvbaal/statuscol.nvim

I've just used the default setup and am unsure how I'd go about setting these highlights?

This is my statuscol config:

function config.statuscol()
  local builtin = require("statuscol.builtin")

  local opts = {
    -- setopt = true,
    thousands = false,
    relculright = true,
    foldfunc = "builtin",
    ft_ignore = { "Outline", "terminal", "toggleterm", "qf", "Trouble", "help", "neo-tree", "oil" },
    bt_ignore = { "terminal", "help", "nofile", "prompt", "toggleterm", "qf", "Trouble" },
    segments = { -- {
      --  sign = { name = { "LightBulb" }, fillchar=" ", maxwidth = 1, auto = false, wrap=false },
      {
        text = { " ", builtin.foldfunc, " " },
        condition = { builtin.not_empty, true, builtin.not_empty },
        click = "v:lua.ScFa",
      },
      {
        sign = {
          name = { "Dap" },
          maxwidth = 1,
          colwidth = 1,
          auto = false,
          fillchar = " ",      -- character used to fill a segment with less signs than maxwidth
          fillcharhl = "NONE",
        },
        condition = { builtin.not_empty },
        click = "v:lua.ScSa",
      },
      {
        sign = {
          namespace = { "diagnostic" },
          maxwidth = 1,
          colwidth = 1,
          auto = true,
          fillchar = " ",      -- character used to fill a segment with less signs than maxwidth
          fillcharhl = "NONE",
        },
        condition = { builtin.not_empty },
        click = "v:lua.ScSa",
      }, --
      {
        text = { " " },
      }, -- Spacing before gitsigns
      {
        sign = {
          name = { ".*" },
          namespace = { ".*" },
          maxwidth = 1,
          colwidth = 2,
          fillchar = " ",      -- character used to fill a segment with less signs than maxwidth
          fillcharhl = "NONE",
        },
        click = "v:lua.ScSa",
      }, -- lightbulb or bookmark or other?
      {
        text = { builtin.lnumfunc },
      }, -- line number col
      {
        text = { " " },
      }, -- Spacing before gitsigns
      {
        sign = {
          namespace = { "gitsigns" },
          maxwidth = 1,
          colwidth = 2,
          wrap = true,
          fillchar = " ",      -- character used to fill a segment with less signs than maxwidth
          fillcharhl = "NONE",
        },
      },
    },
    clickmod = "c",
    clickhandlers = {
      Lnum = builtin.lnum_click,
      FoldClose = builtin.foldclose_click,
      FoldOpen = builtin.foldopen_click,
      FoldOther = builtin.foldother_click,
      DapBreakpointRejected = builtin.toggle_breakpoint,
      DapBreakpoint = builtin.toggle_breakpoint,
      DapBreakpointCondition = builtin.toggle_breakpoint,
      DiagnosticSignError = builtin.diagnostic_click,
      DiagnosticSignHint = builtin.diagnostic_click,
      DiagnosticSignInfo = builtin.diagnostic_click,
      DiagnosticSignWarn = builtin.diagnostic_click,
      GitSignsTopdelete = builtin.gitsigns_click,
      GitSignsUntracked = builtin.gitsigns_click,
      GitSignsAdd = builtin.gitsigns_click,
      GitSignsChange = builtin.gitsigns_click,
      GitSignsChangedelete = builtin.gitsigns_click,
      GitSignsDelete = builtin.gitsigns_click,
      gitsigns_extmark_signs_ = builtin.gitsigns_click,
      LightBulbSign = function(args)
        vim.lsp.buf.code_action()
      end,
    },
  }

  require("statuscol").setup(opts)
end

Its the components defines with sign = {.. that don't get highlighted

Any help would be much appreciated

Ajaymamtora commented 2 months ago

I've tried playing with fillcharhl = "NONE", but I think the issue is that reactive.nvim isn't setting the highlight for that object whatever it is? Is there a way it could do this?

rasulomaroff commented 2 months ago

Hi there! You can also check this issue for more info: https://github.com/rasulomaroff/reactive.nvim/issues/13

But basically you're right, reactive by default doesn't apply highlights for CursorLineSign and CursorLineFold, but you can just link those highlights to CursorLine to achieve the desired effect.

Try that first, but this may not work if those sign columns have another highlight names

Ajaymamtora commented 2 months ago

Thanks for the reply, I’ve tried linking the highlight groups like you suggested:

vim.api.nvim_set_hl(0, "CursorLineFold", { link = "CursorLine" })                                                       
vim.api.nvim_set_hl(0, "CursorLineSign", { link = "CursorLine" })

image

but it doesn’t change anything unfortunately, it looks like they have a different highlight group like you said. Is there a way I could debug what hi light group they’re using? I tried reading the source code for both plugins but i couldn’t figure it out lol

Ajaymamtora commented 2 months ago

Think I’ve figured it out, i need to set the custom segments and the custom sign defined things to the same hl group as well

Ajaymamtora commented 2 months ago

@rasulomaroff I can't get only the current line to be highlighted, the custom columns are permanently set in 1 colour and I don't understand it:

image

I've tried setting all the hl groups to "CursorLine", "CursorLineNr" , tried creating a custom hl group and tried to adjust that in my own preset but nothing works. This is the custom preset:

local mypreset = {
  name = "mypreset",
  skip = function()
    return vim.api.nvim_buf_get_option(0, "buftype") == ""
  end,
  modes = {
    n = {
      -- normal mode configuration
      hl = {
        CursorLineExtraSign = { fg = "#ca0000", bg = "#00c3ff" },
        CursorLine = { fg = "#ca0000", bg = "#00c3ff" },
      },
      winhl = {
        CursorLineExtraSign = { fg = "#ca0000", bg = "#00c3ff" },
        CursorLine = { fg = "#ca0000", bg = "#00c3ff" },
      },
    },
    i = {
      hl = {
        CursorLineExtraSign = { fg = "#ca0000", bg = "#00c3ff" },
        CursorLine = { fg = "#ca0000", bg = "#00c3ff" },
      },
      winhl = {
        CursorLineExtraSign = { fg = "#ca0000", bg = "#00c3ff" },
        CursorLine = { fg = "#ca0000", bg = "#00c3ff" },
      },
    },
  },
}
return mypreset
Ajaymamtora commented 2 months ago

Hl also doesnt work with the builtin fold function:

  {
    text = {
      builtin.foldfunc,
    },
    condition = { builtin.not_empty, true, },
    click = "v:lua.ScFa",
    hl = line_hl, -- <- has no effect
  },

Ive also tried just not highlighting the sign column bit but the fold column is giving me problems that way too:

Screenshot 2024-05-28 at 23 33 15

I can't get rid of this background no matter what I do. Is it because foldfunc is returning some sort of formatted string thats incompatible with the hl = param?

https://github.com/luukvbaal/statuscol.nvim/blob/483b9a596dfd63d541db1aa51ee6ee9a1441c4cc/lua/statuscol/builtin.lua#L37

rasulomaroff commented 2 months ago

@Ajaymamtora Is it highlighted for you even when the only highlight group that is applied by reactive is CursorLine? Looks like it's CursorLineSign or CursorLineFold

reactive won't highlight anything you didn't specify, so if that empty rectangle is going up/down together with the cursor line, then it may use the same highlight group

Could you also please share your config for reactive and statuscol plugins, if not able to track the issue? I'll take a look at it when I have times

Ajaymamtora commented 2 months ago

It did but I had linked those highlight groups (no matter what I did it didn't work while linked), when I unlink them I can control them properly, thanks

After a lot more playing about it looks like to get this to work properly you have to ensure you don't declare a hl group in the custom segments. Also this bit in the readme causes the preset to basically not work:

  skip = function()
    return vim.api.nvim_buf_get_option(0, 'buftype') == ''
  end,

Here's a working config for statuscol:

function config.statuscol()
  local builtin = require("statuscol.builtin")

  local opts = {
    setopt = true,
    thousands = false,
    relculright = true,
    foldfunc = "builtin",
    ft_ignore = { "Outline", "terminal", "toggleterm", "qf", "Trouble", "help", "neo-tree", "oil" },
    bt_ignore = { "terminal", "help", "nofile", "prompt", "toggleterm", "qf", "Trouble" },
    segments = {
      {
        text = {
          function(args)
            return builtin.foldfunc(args)
          end,
        },
        condition = { builtin.not_empty, true, },
        click = "v:lua.ScFa",
      },
      {
        sign = {
          name = { "Dap" },
          maxwidth = 1,
          colwidth = 1,
          auto = true,
          fillchar = " ",
        },
        condition = { builtin.not_empty },
        click = "v:lua.ScSa",
      },
      {
        sign = {
          namespace = { "diagnostic" },
          maxwidth = 1,
          colwidth = 1,
          auto = true,
          fillchar = " ",
        },
        condition = { builtin.not_empty },
        click = "v:lua.ScSa",
      },
      {
        text = { " " },
      },
      {
        sign = {
          name = { ".*" },
          namespace = { ".*" },
          maxwidth = 2,
          colwidth = 2,
          auto = true,
          fillchar = " ",
        },
        click = "v:lua.ScSa",
      },
      {
        text = { builtin.lnumfunc },
      },
      {
        text = { " " },
      },
      {
        sign = {
          namespace = { "gitsigns" },
          maxwidth = 1,
          colwidth = 1,
          auto = false,
          wrap = true,
          fillchar = " ",
        },
      },
    },
    clickmod = "c",
    clickhandlers = {
      Lnum = builtin.lnum_click,
      FoldClose = builtin.foldclose_click,
      FoldOpen = builtin.foldopen_click,
      FoldOther = builtin.foldother_click,
      DapBreakpointRejected = builtin.toggle_breakpoint,
      DapBreakpoint = builtin.toggle_breakpoint,
      DapBreakpointCondition = builtin.toggle_breakpoint,
      DiagnosticSignError = builtin.diagnostic_click,
      DiagnosticSignHint = builtin.diagnostic_click,
      DiagnosticSignInfo = builtin.diagnostic_click,
      DiagnosticSignWarn = builtin.diagnostic_click,
      GitSignsTopdelete = builtin.gitsigns_click,
      GitSignsUntracked = builtin.gitsigns_click,
      GitSignsAdd = builtin.gitsigns_click,
      GitSignsChange = builtin.gitsigns_click,
      GitSignsChangedelete = builtin.gitsigns_click,
      GitSignsDelete = builtin.gitsigns_click,
      gitsigns_extmark_signs_ = builtin.gitsigns_click,
      LightBulbSign = function(args)
        vim.lsp.buf.code_action()
      end,
    },
  }

  require("statuscol").setup(opts)
end

reactive config:

function config.reactive()
  local opts = {
    builtin = {
      cursorline = false,
      cursor = false,
      modemsg = false
    },
    load = { 'mypreset' }, -- you can also use a string
  }
  require('reactive').setup(opts)
end

reactive preset at /lua/reactive/presets/mypreset.lua (based on the builtin cursor line preset)

local function set_highlight(groups, color)
  local result = {}
  for _, group in ipairs(groups) do
    result[group] = { bg = color }
  end
  return result
end

local common_highlight_groups = {
  "CursorLine",
  "CursorLineSign",
  "CursorLineFold",
  "CursorLineNr",
  "DapBreakpoint",
  "DapRejected",
  "DapLogPoint",
  "DapStopped",
  "DiagnosticSignError",
  "DiagnosticSignWarn",
  "DiagnosticSignInfo",
  "DiagnosticSignHint",
}

local common_highlight = set_highlight(common_highlight_groups, "#fff000")

return {
  name = "mypreset",
  init = function()
    vim.opt.cursorline = true
  end,
  static = {
    winhl = {
      inactive = {
        CursorLine = { bg = '#202020' },
        CursorLineNr = { fg = '#b0b0b0', bg = '#202020' },
      },
    },
  },
  modes = {
    no = {
      operators = {
        [{ "gu", "gU", "g~", "~" }] = {
          winhl = {
            CursorLine = { bg = "#334155" },
            CursorLineNr = { fg = "#cbd5e1", bg = "#334155" },
          },
        },
        c = {
          winhl = {
            CursorLine = { bg = "#162044" },
            CursorLineNr = { fg = "#93c5fd", bg = "#162044" },
          },
        },
        d = {
          winhl = {
            CursorLine = { bg = "#350808" },
            CursorLineNr = { fg = "#fca5a5", bg = "#350808" },
          },
        },
        y = {
          winhl = {
            CursorLine = { bg = "#422006" },
            CursorLineNr = { fg = "#fdba74", bg = "#422006" },
          },
        },
      },
    },
    i = {
      winhl = {
        CursorLine = { bg = "#012828" },
        CursorLineNr = { fg = "#5eead4", bg = "#012828" },
      },
    },
    c = {
      winhl = {
        CursorLine = { bg = "#202020" },
        CursorLineNr = { fg = "#ffffff", bg = "#303030" },
      },
    },
    n = {
      winhl = common_highlight,
    },
    [{ "v", "V", "\x16" }] = {
      winhl = {
        CursorLineNr = { fg = "#d8b4fe" },
        Visual = { bg = "#3b0764" },
      },
    },
    [{ "s", "S", "\x13" }] = {
      winhl = {
        CursorLineNr = { fg = "#c4b5fd" },
        Visual = { bg = "#2e1065" },
      },
    },
    R = {
      winhl = {
        CursorLine = { bg = "#083344" },
        CursorLineNr = { fg = "#67e8f9", bg = "#083344" },
      },
    },
  },
}
rasulomaroff commented 2 months ago

Hi @Ajaymamtora, I had some time to check the issue and again it seems like there's nothing wrong with neither of plugins. Those highlights were linked to CursorLineSign, so when you used it in reactive, it also affected the sign column.

Regarding the skip function. I also checked that and it works properly. Whenever 'buftype' is an empty string (which should be the case in your case), then the whole preset gets skipped. You may intended to use 'filetype' instead?