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

[Feature]: Add support for underline #2

Closed
Racle opened this issue May 30, 2023 · 5 comments
Closed

[Feature]: Add support for underline #2

Racle opened this issue May 30, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@Racle
Copy link

Racle commented May 30, 2023

Problem

Why?
Underline separates code and top bar nicely. This also prevents to mistaking top bar as part of your code.

Kitty terminal has built-in support for this as well neovim.

Expected behavior

Result should look something like this.
image

This is archived with lspsaga.nvim and with my custom config to set underline and correct background color to match my "tab" bar (and keep icon colors correct).

@Racle Racle added the enhancement New feature or request label May 30, 2023
@Bekaboo
Copy link
Owner

Bekaboo commented May 30, 2023

In dropbar.nvim the dropbar_menu_t looks at the symbols it gets from sources to determine what to show , so I think what you can do is to create your custom sources with modified highlights and feed them to the winbar, like what you did in your config for lspsaga:

local sources = require('dropbar.sources')

require('dropbar').setup({
  bar = {
    sources = {
      -- Hijack the default path source
      {
        get_symbols = function(buf, cursor)
          local symbols = sources.path.get_symbols(buf, cursor)
          for _, symbol in ipairs(symbols) do
            symbol.name_hl = ...
            symbol.icon_hl = ...
          end
          return symbols
        end,
      }
      -- Hijack other sources ...
    }
  }
})

@Racle
Copy link
Author

Racle commented May 30, 2023

Quick note, for some reason this config breaks dropbar. services > db is missing after applying this (very simplified) config.
image

require("dropbar").setup(
  {
    bar = {
      sources = {
        -- Hijack the default path source
        {
          get_symbols = function(buf, cursor)
            local symbols = sources.path.get_symbols(buf, cursor) 
            return symbols
        end,
      }
      -- Hijack other sources ...
    }
  }
})

And when I tried dropbar, I noticed that lspsaga winbar is more colorful (which I personally like)
Example here:
image

And here is full config with underline (with broken dropbar as mentioned above)

local sources = require("dropbar.sources")

local function get_hl_color(group, attr)
  return vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID(group)), attr)
end

vim.cmd [[hi WinBar guisp=#665c54 gui=underline guibg=#313131]]
vim.cmd [[hi WinBarNC guisp=#665c54 gui=underline guibg=#313131]]

require("dropbar").setup(
  {
    bar = {
      sources = {
        {
          get_symbols = function(buf, cursor)
            local symbols = sources.path.get_symbols(buf, cursor)
            for _, symbol in ipairs(symbols) do
              -- get correct icon color
              local icon_fg = get_hl_color(symbol.icon_hl, "fg#")
              symbol.icon_hl = "DropbarSymbol" .. symbol.icon_hl

              local icon_string = ""
              if icon_fg == "" then
                icon_string = "hi " .. symbol.icon_hl .. " guisp=#665c54 gui=underline guibg=#313131"
              else
                icon_string = "hi " .. symbol.icon_hl .. " guisp=#665c54 gui=underline guibg=#313131 guifg=" .. icon_fg
              end

              vim.cmd(icon_string)
            end
            return symbols
          end
        }
      }
    }
  }
)

@Bekaboo
Copy link
Owner

Bekaboo commented May 30, 2023

services > db is missing after applying this (very simplified) config.

That is expected because you don't include the lsp source... The snippet I gave above is just a minimal example, you might want to check the doc to see what sources you are going to include.

lspsaga winbar is more colorful (which I personally like)

Currently all builtin sources of dropbar.nvim does not set hlgroups for the name (text part) of the symbols, so they are just highlighted with 'WinBar' and 'WinBarNC', personally I prefer this way because in this way I tell symbol names from kinds (icons) more easily. To make the names of symbols highlighted in the same color as that of the icons, set symbol.name_hl to equal to symbol.icon_hl.

@Racle
Copy link
Author

Racle commented May 30, 2023

Quick (working) first version

local sources = require("dropbar.sources")

local function get_hl_color(group, attr)
  return vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID(group)), attr)
end

local get_symbols = function(buf, cursor, symbols)
  local path = false
  if symbols == nil then
    symbols = sources.path.get_symbols(buf, cursor)
    path = true
  end
  for _, symbol in ipairs(symbols) do
    -- get correct icon color
    local icon_fg = get_hl_color(symbol.icon_hl, "fg#")
    symbol.icon_hl = "DropbarSymbol" .. symbol.icon_hl

    -- set name highlight
    if not path then
      symbol.name_hl = symbol.icon_hl
    end

    local icon_string = ""
    if icon_fg == "" then
      icon_string = "hi " .. symbol.icon_hl .. " guisp=#665c54 gui=underline guibg=#313131"
    else
      icon_string = "hi " .. symbol.icon_hl .. " guisp=#665c54 gui=underline guibg=#313131 guifg=" .. icon_fg
    end

    vim.cmd(icon_string)
  end
  return symbols
end

vim.cmd [[hi WinBar guisp=#665c54 gui=underline guibg=#313131]]
vim.cmd [[hi WinBarNC guisp=#665c54 gui=underline guibg=#313131]]

require("dropbar").setup(
  {
    bar = {
      sources = function(_, _)
        return {
          {
            get_symbols = get_symbols
          },
          {
            get_symbols = function(buf, cursor)
              if vim.bo[buf].ft == "markdown" then
                return sources.markdown.get_symbols(buf, cursor)
              end
              for _, source in ipairs(
                {
                  sources.lsp,
                  sources.treesitter
                }
              ) do
                return get_symbols(buf, cursor, source.get_symbols(buf, cursor))
              end
              return {}
            end
          }
        }
      end
    }
  }
)

@Bekaboo Bekaboo closed this as not planned Won't fix, can't repro, duplicate, stale Mar 20, 2024
@IvarWithoutBones
Copy link

I noticed the solution posted above doesn't work anymore, so in case anyone else is looking to change the background color of the bar I thought I'd post my (slightly adapted) version:

-- Modified version of https://github.com/Bekaboo/dropbar.nvim/issues/2#issuecomment-1568244312, thanks!
local function bar_background_color_source()
    local function set_highlight_take_foreground(opts, source_hl, target_hl)
        if target_hl == nil then target_hl = source_hl end
        local fg = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID(source_hl)), "fg#")
        if fg == "" then
            vim.api.nvim_set_hl(0, target_hl, opts)
        else
            vim.api.nvim_set_hl(0, target_hl, vim.tbl_extend("force", opts, { fg = fg }))
        end
    end

    local function color_symbols(symbols, opts)
        for _, symbol in ipairs(symbols) do
            local source_hl = symbol.icon_hl
            symbol.icon_hl = "DropbarSymbol" .. symbol.icon_hl
            symbol.name_hl = symbol.icon_hl
            set_highlight_take_foreground(opts, source_hl, symbol.icon_hl)
        end
        return symbols
    end

    return {
        get_symbols = function(buf, win, cursor)
            -- Use the background of the WinBar highlight group
            local opts = { bg = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID("WinBar")), "bg#") }
            set_highlight_take_foreground(opts, "DropBarIconUISeparator")
            set_highlight_take_foreground(opts, "DropBarIconUIPickPivot")

            local sources = require('dropbar.sources')
            if vim.bo[buf].ft == "markdown" then
                return color_symbols(sources.markdown.get_symbols(buf, win, cursor), opts)
            end
            if vim.bo[buf].ft == "terminal" then
                return color_symbols(sources.terminal.get_symbols(buf, win, cursor), opts)
            end

            for _, source in ipairs({ sources.lsp, sources.treesitter }) do
                local symbols = source.get_symbols(buf, win, cursor)
                if not vim.tbl_isempty(symbols) then
                    return color_symbols(symbols, opts)
                end
            end
            return {}
        end
    }
end

require("dropbar").setup({
    bar = {
        sources = function(_, _)
            return { bar_background_color_source() }
        end
    },
})

It takes the background from the WinBar highlight group, so just configure that to update it. It should be simple to add an underline to this if you're so inclined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants