romgrk / barbar.nvim

The neovim tabline plugin.
2.16k stars 81 forks source link

Powerline rendering looks off #516

Closed alyzmal closed 1 year ago

alyzmal commented 1 year ago

Description

Upon setting my preset to "powerline", a weird underline appeared under the text of the active buffer and the triangular edge took on a weird color unlike the rest of the section. It does not appear under any other buffers, and all other inactive buffers look normal.

To Reproduce

init.lua: require("barbar").setup { icons = { preset = "powerline" } }

Information Neovim version: 0.9.1

Iron-E commented 1 year ago

Picture? Terminal? Current font?

alyzmal commented 1 year ago

Screenshot from 2023-06-30 22 12 59@2x

This is what I mean when I say only the active buffer is affected. I am currently using WezTerm with the Fira Code font.

Iron-E commented 1 year ago

Does this help? https://wezfurlong.org/wezterm/faq.html#how-do-i-enable-undercurl-curly-underlines

alyzmal commented 1 year ago

Upon completion of the suggested steps, I was rewarded with a barbar that looked exactly the same as the one before it, only with a blue underline rather than a white one. I was hoping to figure out how to potentially disable the underline altogether and/or make the triangular shape at the edge match the current buffer's color, a la something like Lualine.

Iron-E commented 1 year ago

I was hoping to figure out how to potentially disable the underline altogether 

Ah, gotcha. (Though it's probably good to run nvim with that wezterm env anyway).

We have documentation on the highlight groups used here; the relevant "status" is Current and you'll have to update all of the groups for that status using e.g. :h nvim_set_hl or :h :hi.

For nvim_set_hl, there is :h nvim_get_hl, which you can use in your config to get the definition of one of those highlight groups, and then remove the underline and sp attributes, then reapply it.

You can probably fix BufferCurrentSignRight by swapping the bg and fg values as well as stripping the attributes suggested above.


Edit: this snippet demonstrates usage of the neovim API to change highlights. Beware copy-pasting it won't help in this case, but it should be a good stepping point either way.

I can write a snippet for this particular case if the current documentation is not enough, just let me know!

alyzmal commented 1 year ago

I honestly don't think I understand Neovim's API enough to write the necessary functions on my own. I may need to ask you for a snippet to solve the underlining and SignRight problems, although if it is at all possible, I have one further request: the ability to make the background color of the active buffer's section reflect the current mode, like what Lualine does.

Iron-E commented 1 year ago

What colorscheme are you using?

alyzmal commented 1 year ago

I am currently using cpea2506's one_monokai.nvim colorscheme.

Edit: if integration with that is not simple, don't worry about it. I'm far more concerned with solving the underlining and SignRight problems.

Iron-E commented 1 year ago

Alright, I've got a config that seems to work. You'll have to tweak the colors to your liking but it is at least a working template.

{'cpea2506/one_monokai.nvim', init = function()
  local BLUE         = '#7766ff'
  local CYAN         = '#33dbc3'
  local GREEN        = '#22ff22'
  local GREEN_DARK   = '#70d533'
  local GREEN_LIGHT  = '#99ff99'
  local ORANGE       = '#ff8900'
  local ORANGE_LIGHT = '#f0af00'
  local PINK         = '#ffa6ff'
  local PINK_LIGHT   = '#ffb7b7'
  local PURPLE       = '#cf55f0'
  local PURPLE_LIGHT = '#af60af'
  local RED          = '#ee4a59'
  local RED_DARK     = '#a80000'
  local RED_LIGHT    = '#ff4090'
  local TAN          = '#f4c069'
  local TEAL         = '#60afff'
  local TURQOISE     = '#2bff99'
  local YELLOW       = '#f0df33'

  local MODES =
  {
    ['c']  = RED,
    ['ce'] = RED_DARK,
    ['cv'] = RED_LIGHT,

    ['i'] = GREEN,

    ['ic']  = GREEN_LIGHT,
    ['ix']  = GREEN_LIGHT,
    ['Rc']  = GREEN_LIGHT,
    ['Rvc'] = GREEN_LIGHT,
    ['Rvx'] = GREEN_LIGHT,
    ['Rx']  = GREEN_LIGHT,

    ['n']   = PURPLE_LIGHT,
    ['niI'] = PURPLE_LIGHT,
    ['niR'] = PURPLE_LIGHT,
    ['niV'] = PURPLE_LIGHT,
    ['nt']  = PURPLE_LIGHT,
    ['ntT'] = PURPLE_LIGHT,

    ['no']   = PURPLE,
    ['nov']  = PURPLE,
    ['noV']  = PURPLE,
    ['no'] = PURPLE,

    ['R']  = PINK,
    ['Rv'] = PINK_LIGHT,

    ['r']   = CYAN,
    ['rm']  = CYAN,
    ['r?']  = CYAN,

    ['s']   = TURQOISE,
    ['S']   = TURQOISE,
    ['']  = TURQOISE,

    ['v']   = BLUE,
    ['vs']  = BLUE,
    ['V']   = BLUE,
    ['Vs']  = BLUE,
    ['no']  = BLUE,
    ['s'] = BLUE,

    ['t']   = ORANGE,
    ['!']   = YELLOW,
  }

  local id
  vim.api.nvim_create_autocmd('ColorSchemePre', {
    callback = function(ev)
      if ev.match ~= 'one_monokai' or not id then return end
      vim.api.nvim_del_autocmd(id)
      id = nil
    end,
  })

  vim.api.nvim_create_autocmd('ColorScheme', {
    callback = function()
      local bg = '#353535'
      local fg = '#c0c0c0'

      vim.api.nvim_set_hl(0, 'TabLineSel', {bg = bg, fg = fg})
      vim.schedule(function()
        for _, status in ipairs {'Alternate', 'Current', 'Visible'} do
          local prefix = 'BufferDefault' .. status
          for _, group in ipairs(vim.fn.getcompletion(prefix, 'highlight')) do
            local definition = vim.api.nvim_get_hl(0, {link = false, name = group})
            definition.underline = false
            vim.api.nvim_set_hl(0, 'Buffer' .. status .. group:sub(#prefix + 1), definition)
          end
        end
      end)

      vim.api.nvim_create_autocmd('ModeChanged', {
        callback = function()
          local current_mode = MODES[vim.api.nvim_get_mode().mode]
          for _, pat in ipairs {'BufferCurrent', 'DevIcon*Current'} do
            for _, group in ipairs(vim.fn.getcompletion(pat, 'highlight')) do
              local definition = vim.api.nvim_get_hl(0, {link = false, name = group})
              if group == 'BufferCurrentSignRight' then
                definition.fg = current_mode
              else
                definition.bg = current_mode
              end

              vim.api.nvim_set_hl(0, group, definition)
            end
          end
        end,
        group = 'config',
        pattern = '*:*',
      })
    end,
    group = 'config',
    pattern = 'one_monokai',
  })
end},

Warning

Some of the control codes (e.g. <C-v>) which are necessary to establish valid mode indicators are stripped by GitHub. Look for the "" and cross reference with :h mode() to manually input them on your side.

Alternately, this file also has the list of modes, but downloading it can preserve the characters.

alyzmal commented 1 year ago

Everything is working as expected (albeit after much fiddling). Thanks so much for your helpful snippet and above all, your patience with me. I couldn't appreciate it more!

alyzmal commented 1 year ago

Thanks again for all your help with this. I hate to have to ask you for something else but there seems to be a slight problem. The colors of the section don't automatically update when moving into a file from my Alpha start screen, instead only updating upon entering a different mode. Is there an extra directive I can give the autocommand to make it update on opening and closing windows, including terminal windows?

alyzmal commented 1 year ago

I have been trying to understand the API and which part may be causing this issue since reopening this issue to ask this question. I am as yet unsuccessful; any help would be appreciated.

Iron-E commented 1 year ago

Sorry for not responding earlier, I was on holiday for the fourth.

Does this updated snippet help?

{'cpea2506/one_monokai.nvim', init = function()
  local BLUE         = '#7766ff'
  local CYAN         = '#33dbc3'
  local GREEN        = '#22ff22'
  local GREEN_LIGHT  = '#99ff99'
  local ORANGE       = '#ff8900'
  local PINK         = '#ffa6ff'
  local PINK_LIGHT   = '#ffb7b7'
  local PURPLE       = '#cf55f0'
  local PURPLE_LIGHT = '#af60af'
  local RED          = '#ee4a59'
  local RED_DARK     = '#a80000'
  local RED_LIGHT    = '#ff4090'
  local TURQOISE     = '#2bff99'
  local YELLOW       = '#f0df33'

  local MODES =
  {
    ['c']  = RED,
    ['ce'] = RED_DARK,
    ['cv'] = RED_LIGHT,

    ['i'] = GREEN,

    ['ic']  = GREEN_LIGHT,
    ['ix']  = GREEN_LIGHT,
    ['Rc']  = GREEN_LIGHT,
    ['Rvc'] = GREEN_LIGHT,
    ['Rvx'] = GREEN_LIGHT,
    ['Rx']  = GREEN_LIGHT,

    ['n']   = PURPLE_LIGHT,
    ['niI'] = PURPLE_LIGHT,
    ['niR'] = PURPLE_LIGHT,
    ['niV'] = PURPLE_LIGHT,
    ['nt']  = PURPLE_LIGHT,
    ['ntT'] = PURPLE_LIGHT,

    ['no']   = PURPLE,
    ['nov']  = PURPLE,
    ['noV']  = PURPLE,
    ['no'] = PURPLE,

    ['R']  = PINK,
    ['Rv'] = PINK_LIGHT,

    ['r']  = CYAN,
    ['rm'] = CYAN,
    ['r?'] = CYAN,

    ['s']  = TURQOISE,
    ['S']  = TURQOISE,
    [''] = TURQOISE,

    ['v']   = BLUE,
    ['vs']  = BLUE,
    ['V']   = BLUE,
    ['Vs']  = BLUE,
    ['']  = BLUE,
    ['s'] = BLUE,

    ['t'] = ORANGE,
    ['!'] = YELLOW,
  }

  local id
  vim.api.nvim_create_autocmd('ColorSchemePre', {
    callback = function()
      if not id then return end
      vim.api.nvim_del_autocmd(id)
      id = nil
    end,
  })

  vim.api.nvim_create_autocmd('ColorScheme', {
    callback = function()
      local bg = '#353535'
      local fg = '#c0c0c0'

      vim.api.nvim_set_hl(0, 'TabLineSel', {bg = bg, fg = fg})
      vim.schedule(function()
        for _, status in ipairs {'Alternate', 'Current', 'Visible'} do
          local prefix = 'BufferDefault' .. status
          for _, group in ipairs(vim.fn.getcompletion(prefix, 'highlight')) do
            local definition = vim.api.nvim_get_hl(0, {link = false, name = group})
            definition.underline = false
            vim.api.nvim_set_hl(0, 'Buffer' .. status .. group:sub(#prefix + 1), definition)
          end
        end
      end)

      local function hl_current_mode()
        local current_mode = MODES[vim.api.nvim_get_mode().mode]
        for _, pat in ipairs {'BufferCurrent', 'DevIcon*Current'} do
          for _, group in ipairs(vim.fn.getcompletion(pat, 'highlight')) do
            local definition = vim.api.nvim_get_hl(0, {link = false, name = group})
            if group == 'BufferCurrentSignRight' then
              definition.fg = current_mode
            else
              definition.bg = current_mode
            end

            vim.api.nvim_set_hl(0, group, definition)
          end
        end
      end

      id = vim.api.nvim_create_autocmd('ModeChanged', {
        callback = hl_current_mode,
        group = 'config',
        pattern = '*:*',
      })

      vim.defer_fn(hl_current_mode, 1)
    end,
    group = 'config',
    pattern = 'one_monokai',
  })
end},
alyzmal commented 1 year ago

Works perfectly! Thanks much -- it's handled everything I've thrown at it.