Repository: nvim-lualine/lualine.nvim
Pull request #828 (2022-09-04 23:57:04)

Add overseer extension.
This PR adds a simple [overseer.nvim](https://github.com/stevearc/overseer.nvim) extension.

dcordb: cc @stevearc @dzfrias
stevearc: While you're adding overseer configuration to the lualine repo, this would be a good place to ask if it makes more sense for [this overseer component](https://github.com/stevearc/overseer.nvim/blob/master/lua/lualine/components/overseer.lua) to live in the overseer repo or in the lualine repo. Thoughts?
dcordb: @stevearc Yes I think it makes the more sense to have that component on lualine repo. For example, if someone wants to have overseer integrated with another status line plugin, it does not make sense to add it to the overseer repo, you would eventually end up with many integrations in there. For this, I think the implementation of each component for each status line should be in the status line repo.

Patch:
diff --git a/lua/lualine/components/diagnostics/sources.lua b/lua/lualine/components/diagnostics/sources.lua
index 96611ea..3432b9e 100644
--- a/lua/lualine/components/diagnostics/sources.lua
+++ b/lua/lualine/components/diagnostics/sources.lua
@@ -40,8 +40,8 @@ M.sources = {
 
     return workspace_diag(diag_severity.ERROR),
       workspace_diag(diag_severity.WARN),
-      workspace_diag(diag_severity.HINT),
-      workspace_diag(diag_severity.INFO)
+      workspace_diag(diag_severity.INFO),
+      workspace_diag(diag_severity.HINT)
   end,
   nvim_diagnostic = function()
     local diagnostics = vim.diagnostic.get(0)
diff --git a/lua/lualine/components/filename.lua b/lua/lualine/components/filename.lua
index b7f74f4..1d9232f 100644
--- a/lua/lualine/components/filename.lua
+++ b/lua/lualine/components/filename.lua
@@ -19,14 +19,6 @@ local default_options = {
   shorting_target = 40,
 }
 
----counts how many times pattern occur in base ( used for counting path-sep )
----@param base string
----@param pattern string
----@return number
-local function count(base, pattern)
-  return select(2, string.gsub(base, pattern, ''))
-end
-
 local function is_new_file()
   local filename = vim.fn.expand('%')
   return filename ~= '' and vim.bo.buftype == '' and vim.fn.filereadable(filename) == 0
@@ -35,10 +27,27 @@ end
 ---shortens path by turning apple/orange -> a/orange
 ---@param path string
 ---@param sep string path separator
+---@param max_len integer maximum length of the full filename string
 ---@return string
-local function shorten_path(path, sep)
-  -- ('([^/])[^/]+%/', '%1/', 1)
-  return path:gsub(string.format('([^%s])[^%s]+%%%s', sep, sep, sep), '%1' .. sep, 1)
+local function shorten_path(path, sep, max_len)
+  local len = #path
+  if len <= max_len then
+    return path
+  end
+
+  local segments = vim.split(path, sep)
+  for idx = 1, #segments - 1 do
+    if len <= max_len then
+      break
+    end
+
+    local segment = segments[idx]
+    local shortened = segment:sub(1, vim.startswith(segment, '.') and 2 or 1)
+    segments[idx] = shortened
+    len = len - (#segment - #shortened)
+  end
+
+  return table.concat(segments, sep)
 end
 
 M.init = function(self, options)
@@ -73,11 +82,7 @@ M.update_status = function(self)
     local estimated_space_available = windwidth - self.options.shorting_target
 
     local path_separator = package.config:sub(1, 1)
-    for _ = 0, count(data, path_separator) do
-      if windwidth <= 84 or #data > estimated_space_available then
-        data = shorten_path(data, path_separator)
-      end
-    end
+    data = shorten_path(data, path_separator, estimated_space_available)
   end
 
   if self.options.file_status then
diff --git a/lua/lualine/extensions/overseer.lua b/lua/lualine/extensions/overseer.lua
new file mode 100644
index 0000000..e49a4c4
--- /dev/null
+++ b/lua/lualine/extensions/overseer.lua
@@ -0,0 +1,16 @@
+-- Copyright (c) 2020-2021 hoob3rt
+-- MIT license, see LICENSE for more details.
+
+local M = {}
+
+M.sections = {
+  lualine_a = {
+    function()
+      return 'OverseerList'
+    end,
+  },
+}
+
+M.filetypes = { 'OverseerList' }
+
+return M


Test patch:
diff --git a/tests/spec/component_spec.lua b/tests/spec/component_spec.lua
index 4b7d1e9..f4f6634 100644
--- a/tests/spec/component_spec.lua
+++ b/tests/spec/component_spec.lua
@@ -455,19 +455,6 @@ describe('FileSize component', function()
 end)
 
 describe('Filename component', function()
-  local function shorten_path(path, target)
-    target = target and target or 40
-    local sep = package.config:sub(1, 1)
-    local winwidth = vim.fn.winwidth(0)
-    local segments = select(2, string.gsub(path, sep, ''))
-    for _ = 0, segments do
-      if winwidth <= 84 or #path > winwidth - target then
-        path = path:gsub(string.format('([^%s])[^%s]+%%%s', sep, sep, sep), '%1' .. sep, 1)
-      end
-    end
-    return path
-  end
-
   it('works', function()
     local opts = build_component_opts {
       component_separators = { left = '', right = '' },
@@ -506,7 +493,7 @@ describe('Filename component', function()
       path = 1,
     }
     vim.cmd(':e test-file.txt')
-    assert_component('filename', opts, shorten_path(vim.fn.expand('%:~:.')))
+    assert_component('filename', opts, vim.fn.expand('%:~:.'))
     vim.cmd(':bdelete!')
   end)
 
@@ -516,10 +503,74 @@ describe('Filename component', function()
       padding = 0,
       file_status = false,
       path = 2,
+      shorting_target = 0,
+    }
+    vim.cmd(':e test-file.txt')
+    assert_component('filename', opts, vim.fn.expand('%:p'))
+    vim.cmd(':bdelete!')
+  end)
+
+  it('shortens path', function()
+    stub(vim.fn, 'expand')
+    vim.fn.expand.on_call_with('%:p').returns('/home/foobar/test/test.lua')
+    stub(vim.fn, 'winwidth')
+    vim.fn.winwidth.on_call_with(0).returns(100)
+
+    local opts = build_component_opts {
+      component_separators = { left = '', right = '' },
+      padding = 0,
+      file_status = false,
+      path = 2,
+      shorting_target = 90,
     }
     vim.cmd(':e test-file.txt')
-    assert_component('filename', opts, shorten_path(vim.fn.expand('%:p')))
+    assert_component('filename', opts, '/h/f/t/test.lua')
+
+    vim.cmd(':bdelete!')
+    vim.fn.winwidth:revert()
+    vim.fn.expand:revert()
+  end)
+
+  it('shortens path with tilde', function()
+    stub(vim.fn, 'expand')
+    vim.fn.expand.on_call_with('%:p:~').returns('~/test/test.lua')
+    stub(vim.fn, 'winwidth')
+    vim.fn.winwidth.on_call_with(0).returns(100)
+
+    local opts = build_component_opts {
+      component_separators = { left = '', right = '' },
+      padding = 0,
+      file_status = false,
+      path = 3,
+      shorting_target = 90,
+    }
+    vim.cmd(':e test-file.txt')
+    assert_component('filename', opts, '~/t/test.lua')
+
+    vim.cmd(':bdelete!')
+    vim.fn.winwidth:revert()
+    vim.fn.expand:revert()
+  end)
+
+  it('shortens path with hidden directory', function()
+    stub(vim.fn, 'expand')
+    vim.fn.expand.on_call_with('%:p').returns('/home/foobar/.test/test.lua')
+    stub(vim.fn, 'winwidth')
+    vim.fn.winwidth.on_call_with(0).returns(100)
+
+    local opts = build_component_opts {
+      component_separators = { left = '', right = '' },
+      padding = 0,
+      file_status = false,
+      path = 2,
+      shorting_target = 90,
+    }
+    vim.cmd(':e test-file.txt')
+    assert_component('filename', opts, '/h/f/.t/test.lua')
+
     vim.cmd(':bdelete!')
+    vim.fn.winwidth:revert()
+    vim.fn.expand:revert()
   end)
 end)