Repository: nvim-lualine/lualine.nvim
Pull request #669 (2022-04-26 21:03:52)

Add option to show buffer number + alternate file icon
This is a rough draft to address #668.
Still needs documentation (and maybe a test spec), which I will add if the feature request is approved.

shadmansaleh: I like the idea of identifying alternate buffer .

I think we should just make mode 4 & 5 that are same as 2 & 3 but shows bufnr instead if buffer index .
shadmansaleh: I like the idea of identifying alternate buffer .

I think we should just make mode 4 & 5 that are same as 2 & 3 but shows bufnr instead if buffer index .
MrcJkb: > I like the idea of identifying alternate buffer .
> 
> I think we should just make mode 4 & 5 that are same as 2 & 3 but shows bufnr instead if buffer index .

Sure. What about the default behaviour?
Would you like to preserve the current default `mode = 2`?
I would suggest changing the default `mode` to 0, as that is what is set in the readme example. But it may surprise users who don't have `mode` set in their configs after an update...

Regarding the alternate buffer identifier: Would you prefer an option to enable/disable it?




shadmansaleh: > What about the default behaviour?
Would you like to preserve the current default mode = 2?

Current default mode is 0 no reason to change that. It's set [here](https://github.com/nvim-lualine/lualine.nvim/blob/45d07fc026400c211337a7ce1cb90e7b7a397e31/lua/lualine/components/buffers/init.lua#L12) by the way . I think you thought it's 2 because of that functions  structure.

> Regarding the alternate buffer identifier: Would you prefer an option to enable/disable it?

You can expose it as an option under symbols table .
```lua
options.symbols = {
  modified = ....,
  alternate_file = ....,
}
```
Similar to how diff & diagnostics component exposes their icons . That way if someone doesn't want it they can just set it to empty string. 
shadmansaleh: You need to have plenary.nvim . Then run `make test` . See [here](https://github.com/nvim-lualine/lualine.nvim/blob/master/CONTRIBUTING.md#devloper-tools)
MrcJkb: I am getting inconsistent buffer numbers in my tests between NeoVim 0.5 and 0.6.
Are some tests excluded depending on the NeoVim version? It won't be possible to reset buffer indexing without quitting the session.
shadmansaleh: > I am getting inconsistent buffer numbers in my tests between NeoVim 0.5 and 0.6.

This is something I've noticed too . You can try matching a pattern instead of exact number . Or you could get the bufnr for the bufname and test against that . That way you'll be varifying the bufnr too in the test though pattern match is easier to write as it's built into statusline test module :)

> Are some tests excluded depending on the NeoVim version?

Not currently . Though you could run different test code in the test based on which nvim version you're on , probably not a good idea in this case as it might break the test on nightly or a new version anytime.
MrcJkb: I implemented the bufnr detection. It turns out that the inconsistency is because NeoVim 0.5 does not create an unnamed buffer. By silently deleting the alternate buffer after creating the first buffer `a.txt`, we can achieve consistent results.
shadmansaleh: lgtm , thanks.

Patch:
diff --git a/README.md b/README.md
index ead8f1e..d7f3516 100644
--- a/README.md
+++ b/README.md
@@ -442,7 +442,9 @@ sections = {
 
       mode = 0, -- 0: Shows buffer name
                 -- 1: Shows buffer index
-                -- 2: Shows buffer name + buffer index
+                -- 2: Shows buffer name + buffer index 
+                -- 3: Shows buffer number
+                -- 4: Shows buffer name + buffer number
 
       max_length = vim.o.columns * 2 / 3, -- Maximum width of buffers component,
                                           -- it can also be a function that returns
@@ -460,6 +462,12 @@ sections = {
         active = 'lualine_{section}_normal',     -- Color for active buffer.
         inactive = 'lualine_{section}_inactive', -- Color for inactive buffer.
       },
+
+      symbols = {
+        modified = ' ●'       -- Text to show when the buffer is modified
+        alternate_file = '#', -- Text to show to indify the alternate file
+        directory =  '',     -- Text to show when the buffer is a directory
+      },
     }
   }
 }
diff --git a/lua/lualine/components/buffers/buffer.lua b/lua/lualine/components/buffers/buffer.lua
index 3f7268c..613a140 100644
--- a/lua/lualine/components/buffers/buffer.lua
+++ b/lua/lualine/components/buffers/buffer.lua
@@ -20,14 +20,18 @@ function Buffer:is_current()
   return vim.api.nvim_get_current_buf() == self.bufnr
 end
 
+function Buffer:is_alternate()
+  return vim.fn.bufnr('#') == self.bufnr and not self:is_current()
+end
+
 ---setup icons, modified status for buffer
 function Buffer:get_props()
   self.file = modules.utils.stl_escape(vim.api.nvim_buf_get_name(self.bufnr))
   self.buftype = vim.api.nvim_buf_get_option(self.bufnr, 'buftype')
   self.filetype = vim.api.nvim_buf_get_option(self.bufnr, 'filetype')
   local modified = self.options.show_modified_status and vim.api.nvim_buf_get_option(self.bufnr, 'modified')
-  local modified_icon = self.options.icons_enabled and ' ●' or ' +'
-  self.modified_icon = modified and modified_icon or ''
+  self.modified_icon = modified and self.options.symbols.modified or ''
+  self.alternate_file_icon = self:is_alternate() and self.options.symbols.alternate_file or ''
   self.icon = ''
   if self.options.icons_enabled then
     local dev
@@ -43,7 +47,7 @@ function Buffer:get_props()
     elseif self.buftype == 'terminal' then
       dev, _ = require('nvim-web-devicons').get_icon('zsh')
     elseif vim.fn.isdirectory(self.file) == 1 then
-      dev, _ = '', nil
+      dev, _ = self.options.symbols.directory, nil
     else
       dev, _ = require('nvim-web-devicons').get_icon(self.file, vim.fn.expand('#' .. self.bufnr .. ':e'))
     end
@@ -159,14 +163,24 @@ end
 
 function Buffer:apply_mode(name)
   if self.options.mode == 0 then
-    return string.format('%s%s%s', self.icon, name, self.modified_icon)
+    return string.format('%s%s%s%s', self.alternate_file_icon, self.icon, name, self.modified_icon)
   end
 
   if self.options.mode == 1 then
-    return string.format('%s %s%s', self.buf_index or '', self.icon, self.modified_icon)
+    return string.format('%s%s %s%s', self.alternate_file_icon, self.buf_index or '', self.icon, self.modified_icon)
+  end
+
+  if self.options.mode == 2 then
+    return string.format('%s%s %s%s%s', self.alternate_file_icon, self.buf_index or '', self.icon, name, self.modified_icon)
   end
 
-  return string.format('%s %s%s%s', self.buf_index or '', self.icon, name, self.modified_icon)
+  if self.options.mode == 3 then
+    return string.format('%s%s %s%s', self.alternate_file_icon, self.bufnr or '', self.icon, self.modified_icon)
+  end
+
+  -- if self.options.mode == 4 then
+  return string.format('%s%s %s%s%s', self.alternate_file_icon, self.bufnr or '', self.icon, name, self.modified_icon)
+
 end
 
 return Buffer
diff --git a/lua/lualine/components/buffers/init.lua b/lua/lualine/components/buffers/init.lua
index 0276123..f427c9e 100644
--- a/lua/lualine/components/buffers/init.lua
+++ b/lua/lualine/components/buffers/init.lua
@@ -22,6 +22,11 @@ local default_options = {
     active = nil,
     inactive = nil,
   },
+  symbols = {
+    modified = ' ●',
+    alternate_file = '#',
+    directory =  '',
+  }
 }
 
 -- This function is duplicated in tabs


Test patch:
diff --git a/tests/spec/lualine_spec.lua b/tests/spec/lualine_spec.lua
index dc0d8df..430fb88 100644
--- a/tests/spec/lualine_spec.lua
+++ b/tests/spec/lualine_spec.lua
@@ -558,12 +558,12 @@ describe('Lualine', function()
             4: lualine_transitional_lualine_a_buffers_active_to_lualine_a_buffers_inactive = { bg = "#3c3836", fg = "#a89984" }
             5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
         }
-        |{1: a.txt }
+        |{1: #a.txt }
         {2:}
         {3: b.txt }
         {4:}
         {1: [No Name] }
-        {5:                                                                                             }|
+        {MATCH:{5:%s+}|}
         ]===])
 
         vim.cmd('tabprev')
@@ -577,8 +577,8 @@ describe('Lualine', function()
         |{1: a.txt }
         {2:}
         {3: b.txt }
-        {3: [No Name] }
-        {4:                                                                                             }|
+        {3: #[No Name] }
+        {MATCH:{4:%s+}|}
         ]===])
 
         vim.cmd('tabprev')
@@ -591,11 +591,11 @@ describe('Lualine', function()
             5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
         }
         |{1: a.txt }
-        {1: b.txt }
+        {1: #b.txt }
         {2:}
         {3: [No Name] }
         {4:}
-        {5:                                                                                            }|
+        {MATCH:{5:%s+}|}
         ]===])
       end)
 
@@ -633,7 +633,7 @@ describe('Lualine', function()
             4: lualine_transitional_lualine_a_buffers_active_to_lualine_a_buffers_inactive = { bg = "#3c3836", fg = "#a89984" }
             5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
         }
-        {MATCH:|{1: %d+  }}
+        {MATCH:|{1: #%d+  }}
         {2:}
         {MATCH:{3: %d+  }}
         {4:}
@@ -652,7 +652,7 @@ describe('Lualine', function()
             4: lualine_transitional_lualine_a_buffers_active_to_lualine_a_buffers_inactive = { bg = "#3c3836", fg = "#a89984" }
             5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
         }
-        {MATCH:|{1: %d+ a.txt }}
+        {MATCH:|{1: #%d+ a.txt }}
         {2:}
         {MATCH:{3: %d+ b.txt }}
         {4:}
@@ -684,7 +684,7 @@ describe('Lualine', function()
             2: lualine_transitional_lualine_a_buffers_active_to_lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
             3: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
         }
-        |{1: [No Name] + }
+        |{1: [No Name] ● }
         {2:}
         {3:                                                                                                          }|
         ]===])
@@ -751,6 +751,112 @@ describe('Lualine', function()
         {3:                                                                                                              }|
         ]===])
       end)
+
+      it('can show buffer numbers instead of indices (without file names)', function()
+        local conf = vim.deepcopy(tab_conf)
+        conf.tabline.lualine_a = { { 'buffers', mode = 3, max_length = 1e3, icons_enabled = false } }
+        require('lualine').setup(conf)
+        require('lualine').statusline()
+        vim.cmd('e a.txt')
+        vim.cmd('silent! bd #') -- NeoVim 0.5 does not create an unnamed buffer. This ensures consistent results between NeoVim versions.
+        vim.cmd('e b.txt')
+        local bufnr_a = vim.fn.bufnr('a.txt')
+        local bufnr_b = vim.fn.bufnr('b.txt')
+        tabline:expect([===[
+        highlights = {
+            1: lualine_a_buffers_inactive = { bg = "#3c3836", bold = true, fg = "#a89984" }
+            2: lualine_transitional_lualine_a_buffers_inactive_to_lualine_a_buffers_active = { bg = "#a89984", fg = "#3c3836" }
+            3: lualine_a_buffers_active = { bg = "#a89984", bold = true, fg = "#282828" }
+            4: lualine_transitional_lualine_a_buffers_active_to_lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+            5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+        }
+        |{1: #]===] .. bufnr_a .. [===[  }
+        {2:}
+        {3: ]===] .. bufnr_b .. [===[  }
+        {4:}
+        {MATCH:{5:%s+}|}
+        ]===])
+      end)
+
+      it('can show buffer numbers instead of indices (with file names)', function()
+        local conf = vim.deepcopy(tab_conf)
+        conf.tabline.lualine_a = { { 'buffers', mode = 4, max_length = 1e3, icons_enabled = false } }
+        vim.cmd('e a.txt')
+        vim.cmd('silent! bd #') -- NeoVim 0.5 does not create an unnamed buffer. This ensures consistent results between NeoVim versions.
+        vim.cmd('e b.txt')
+        local bufnr_a = vim.fn.bufnr('a.txt')
+        local bufnr_b = vim.fn.bufnr('b.txt')
+        require('lualine').setup(conf)
+        require('lualine').statusline()
+        tabline:expect([===[
+        highlights = {
+            1: lualine_a_buffers_inactive = { bg = "#3c3836", bold = true, fg = "#a89984" }
+            2: lualine_transitional_lualine_a_buffers_inactive_to_lualine_a_buffers_active = { bg = "#a89984", fg = "#3c3836" }
+            3: lualine_a_buffers_active = { bg = "#a89984", bold = true, fg = "#282828" }
+            4: lualine_transitional_lualine_a_buffers_active_to_lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+            5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+        }
+        |{1: #]===] .. bufnr_a .. [===[ a.txt }
+        {2:}
+        {3: ]===] .. bufnr_b .. [===[ b.txt }
+        {4:}
+        {MATCH:{5:%s+}|}
+        ]===])
+      end)
+
+      it('displays alternate buffer correctly when switching buffers', function()
+        local conf = vim.deepcopy(tab_conf)
+        conf.tabline.lualine_a = { { 'buffers', mode = 3, max_length = 1e3, icons_enabled = false } }
+        require('lualine').setup(conf)
+        require('lualine').statusline()
+        vim.cmd('e a.txt')
+        vim.cmd('silent! bd #') -- NeoVim 0.5 does not create an unnamed buffer. This ensures consistent results between NeoVim versions.
+        vim.cmd('e b.txt')
+        local bufnr_a = vim.fn.bufnr('a.txt')
+        local bufnr_b = vim.fn.bufnr('b.txt')
+        tabline:expect([===[
+        highlights = {
+            1: lualine_a_buffers_inactive = { bg = "#3c3836", bold = true, fg = "#a89984" }
+            2: lualine_transitional_lualine_a_buffers_inactive_to_lualine_a_buffers_active = { bg = "#a89984", fg = "#3c3836" }
+            3: lualine_a_buffers_active = { bg = "#a89984", bold = true, fg = "#282828" }
+            4: lualine_transitional_lualine_a_buffers_active_to_lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+            5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+        }
+        |{1: #]===] .. bufnr_a .. [===[  }
+        {2:}
+        {3: ]===] .. bufnr_b .. [===[  }
+        {4:}
+        {MATCH:{5:%s+}|}
+        ]===])
+        vim.cmd('e a.txt')
+        tabline:expect([===[
+        highlights = {
+            1: lualine_a_buffers_active = { bg = "#a89984", bold = true, fg = "#282828" }
+            2: lualine_transitional_lualine_a_buffers_active_to_lualine_a_buffers_inactive = { bg = "#3c3836", fg = "#a89984" }
+            3: lualine_a_buffers_inactive = { bg = "#3c3836", bold = true, fg = "#a89984" }
+            4: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+        }
+        |{1: ]===] .. bufnr_a .. [===[  }
+        {2:}
+        {3: #]===] .. bufnr_b .. [===[  }
+        {MATCH:{4:%s+}|}
+        ]===])
+        vim.cmd('bprev')
+        tabline:expect([===[
+        highlights = {
+            1: lualine_a_buffers_inactive = { bg = "#3c3836", bold = true, fg = "#a89984" }
+            2: lualine_transitional_lualine_a_buffers_inactive_to_lualine_a_buffers_active = { bg = "#a89984", fg = "#3c3836" }
+            3: lualine_a_buffers_active = { bg = "#a89984", bold = true, fg = "#282828" }
+            4: lualine_transitional_lualine_a_buffers_active_to_lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+            5: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
+        }
+        |{1: #]===] .. bufnr_a .. [===[  }
+        {2:}
+        {3: ]===] .. bufnr_b .. [===[  }
+        {4:}
+        {MATCH:{5:%s+}|}
+        ]===])
+      end)
     end)
 
     describe('windows component', function()