nvim-lualine / lualine.nvim

A blazing fast and easy to configure neovim statusline plugin written in pure lua.
MIT License
5.89k stars 459 forks source link

Bug: tabs `fmt` function is ignored #937

Closed ehaynes99 closed 1 year ago

ehaynes99 commented 1 year ago

Self Checks

How to reproduce the problem

Load with config as below

Expected behaviour

The tabs would be displayed with hello!

Actual behaviour

The tabs are displayed as their number

Minimal config to reproduce the issue

call plug#begin("/home/erich/tmp/lualine-issue/.local/share/nvim/plugged")
Plug 'nvim-lualine/lualine.nvim'

call plug#end()

lua << END
require'lualine'.setup {
  sections = {
    lualine_a = {
      {
        'tabs',
        fmt = function(name, context)
          return 'hello!'
        end,
      },
    },
  },
}
END

Additional information

In lua/lualine/components/tabs/tab.lua, the render function looks like:

function Tab:render()
  local name = self:label()
  if self.options.fmt then
    name = self.options.fmt(name or '', self)
  end
  if self.ellipse then -- show ellipsis
    name = '...'
  else
    -- different formats for different modes
    if self.options.mode == 0 then
      name = tostring(self.tabnr)
    elseif self.options.mode == 1 then
      name = name
    else
      name = string.format('%s %s', tostring(self.tabnr), name)
    end
  end

The name is set to the result of the fmt function. However, the following conditional overwrites it in all cases, either with the ellipsis or the mode value. I started to make a PR, but I'm not entirely clear on how ellipse is supposed to behave. If it should take precedence over the fmt function's result, it could be changed to:

function Tab:render()
  local name = self:label()
  if self.ellipse then -- show ellipsis
    name = '...'
  else
    if self.options.fmt then
      name = self.options.fmt(name or '', self)
    elseif self.options.mode == 0 then
      name = tostring(self.tabnr)
    elseif self.options.mode == 1 then
      name = name
    else
      name = string.format('%s %s', tostring(self.tabnr), name)
    end
  end

If fmt should take precedence over ellipse, it would be:

function Tab:render()
  local name = self:label()
  if self.options.fmt then
    name = self.options.fmt(name or '', self)
  elseif self.ellipse then -- show ellipsis
    name = '...'
  else
    -- different formats for different modes
    if self.options.mode == 0 then
      name = tostring(self.tabnr)
    elseif self.options.mode == 1 then
      name = name
    else
      name = string.format('%s %s', tostring(self.tabnr), name)
    end
  end
shadmansaleh commented 1 year ago

I think it's fine. This way it's easier for users to modify the tab name. If you don't want the numbers use mode = 1.

lualine_a = {
      {
        'tabs',
        mode = 1,
        fmt = function(name, context)
          return 'hello!'
        end,
      },
ehaynes99 commented 1 year ago

I see what you mean. It's a bit surprising. I would think if fmt is specified, it would apply without having to explicitly set mode. Since the default settings set mode = 0, it's just discarded.