feat: add windows component (#595)
Co-authored-by: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com>
This commit is contained in:
parent
4480d91e60
commit
e9b935ccd6
38
README.md
38
README.md
|
@ -241,6 +241,7 @@ sections = {lualine_a = {'mode'}}
|
|||
- `mode` (vim mode)
|
||||
- `progress` (%progress in file)
|
||||
- `tabs` (shows currently available tabs)
|
||||
- `windows` (shows currently available windows)
|
||||
|
||||
#### Custom components
|
||||
|
||||
|
@ -597,6 +598,43 @@ sections = {
|
|||
}
|
||||
```
|
||||
|
||||
#### windows component options
|
||||
|
||||
```lua
|
||||
sections = {
|
||||
lualine_a = {
|
||||
{
|
||||
'windows',
|
||||
show_filename_only = true, -- Shows shortened relative path when set to false.
|
||||
show_modified_status = true, -- Shows indicator when the window is modified.
|
||||
|
||||
mode = 0, -- 0: Shows window name
|
||||
-- 1: Shows window index (bufnr)
|
||||
-- 2: Shows window name + window index (bufnr)
|
||||
|
||||
max_length = vim.o.columns * 2 / 3, -- Maximum width of windows component,
|
||||
-- it can also be a function that returns
|
||||
-- the value of `max_length` dynamically.
|
||||
filetype_names = {
|
||||
TelescopePrompt = 'Telescope',
|
||||
dashboard = 'Dashboard',
|
||||
packer = 'Packer',
|
||||
fzf = 'FZF',
|
||||
alpha = 'Alpha'
|
||||
}, -- Shows specific window name for that filetype ( { `filetype` = `window_name`, ... } )
|
||||
|
||||
disabled_buftypes = { 'quickfix', 'prompt' }, -- Hide a window if its buffer's type is disabled
|
||||
|
||||
windows_color = {
|
||||
-- Same values as the general color option can be used here.
|
||||
active = 'lualine_{section}_normal', -- Color for active window.
|
||||
inactive = 'lualine_{section}_inactive', -- Color for inactive window.
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Tabline
|
||||
|
|
|
@ -240,6 +240,7 @@ CHANGING COMPONENTS IN LUALINE SECTIONS ~
|
|||
- `mode` (vim mode)
|
||||
- `progress` (%progress in file)
|
||||
- `tabs` (shows currently available tabs)
|
||||
- `windows` (shows currently available windows)
|
||||
|
||||
|
||||
*lualine-Custom-components*
|
||||
|
@ -621,6 +622,44 @@ Component specific options These are options that are available on
|
|||
<
|
||||
|
||||
|
||||
*lualine-windows-component-options*
|
||||
|
||||
>
|
||||
sections = {
|
||||
lualine_a = {
|
||||
{
|
||||
'windows',
|
||||
show_filename_only = true, -- Shows shortened relative path when set to false.
|
||||
show_modified_status = true, -- Shows indicator when the window is modified.
|
||||
|
||||
mode = 0, -- 0: Shows window name
|
||||
-- 1: Shows window index (bufnr)
|
||||
-- 2: Shows window name + window index (bufnr)
|
||||
|
||||
max_length = vim.o.columns * 2 / 3, -- Maximum width of windows component,
|
||||
-- it can also be a function that returns
|
||||
-- the value of `max_length` dynamically.
|
||||
filetype_names = {
|
||||
TelescopePrompt = 'Telescope',
|
||||
dashboard = 'Dashboard',
|
||||
packer = 'Packer',
|
||||
fzf = 'FZF',
|
||||
alpha = 'Alpha'
|
||||
}, -- Shows specific window name for that filetype ( { `filetype` = `window_name`, ... } )
|
||||
|
||||
disabled_buftypes = { 'quickfix', 'prompt' }, -- Hide a window if its buffer's type is disabled
|
||||
|
||||
windows_color = {
|
||||
-- Same values as the general color option can be used here.
|
||||
active = 'lualine_{section}_normal', -- Color for active window.
|
||||
inactive = 'lualine_{section}_inactive', -- Color for inactive window.
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
<
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
TABLINE ~
|
||||
|
|
|
@ -277,8 +277,8 @@ local function set_statusline()
|
|||
end
|
||||
|
||||
-- lualine.statusline function
|
||||
--- Draw correct statusline for current winwow
|
||||
---@param focused boolean : force the vale of is_focuased . useful for debugginf
|
||||
--- Draw correct statusline for current window
|
||||
---@param focused boolean : force the value of is_focused . useful for debugging
|
||||
---@return string statusline string
|
||||
local function status_dispatch(focused)
|
||||
local retval
|
||||
|
|
|
@ -15,6 +15,10 @@ function Buffer:init(opts)
|
|||
self:get_props()
|
||||
end
|
||||
|
||||
function Buffer:is_current()
|
||||
return vim.api.nvim_get_current_buf() == self.bufnr
|
||||
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))
|
||||
|
@ -48,6 +52,13 @@ function Buffer:get_props()
|
|||
end
|
||||
end
|
||||
|
||||
---returns line configured for handling mouse click
|
||||
---@param name string
|
||||
---@return string
|
||||
function Buffer:configure_mouse_click(name)
|
||||
return string.format('%%%s@LualineSwitchBuffer@%s%%T', self.bufnr, name)
|
||||
end
|
||||
|
||||
---returns rendered buffer
|
||||
---@return string
|
||||
function Buffer:render()
|
||||
|
@ -59,19 +70,13 @@ function Buffer:render()
|
|||
if self.ellipse then -- show elipsis
|
||||
name = '...'
|
||||
else
|
||||
if self.options.mode == 0 then
|
||||
name = string.format('%s%s%s', self.icon, name, self.modified_icon)
|
||||
elseif self.options.mode == 1 then
|
||||
name = string.format('%s %s%s', self.bufnr, self.icon, self.modified_icon)
|
||||
else
|
||||
name = string.format('%s %s%s%s', self.bufnr, self.icon, name, self.modified_icon)
|
||||
end
|
||||
name = self:apply_mode(name)
|
||||
end
|
||||
name = Buffer.apply_padding(name, self.options.padding)
|
||||
self.len = vim.fn.strchars(name)
|
||||
|
||||
-- setup for mouse clicks
|
||||
local line = string.format('%%%s@LualineSwitchBuffer@%s%%T', self.bufnr, name)
|
||||
local line = self:configure_mouse_click(name)
|
||||
-- apply highlight
|
||||
line = modules.highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')])
|
||||
.. line
|
||||
|
@ -119,6 +124,9 @@ function Buffer:name()
|
|||
elseif self.buftype == 'terminal' then
|
||||
local match = string.match(vim.split(self.file, ' ')[1], 'term:.*:(%a+)')
|
||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
||||
elseif self.buftype == 'quickfix' then
|
||||
local is_loclist = 0 ~= vim.fn.getloclist(0, { filewinid = 1 }).filewinid
|
||||
return is_loclist and 'Location list' or 'Quickfix List'
|
||||
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||
return vim.fn.fnamemodify(self.file, ':p:.')
|
||||
elseif self.file == '' then
|
||||
|
@ -139,4 +147,16 @@ function Buffer.apply_padding(str, padding)
|
|||
return string.rep(' ', l_padding) .. str .. string.rep(' ', r_padding)
|
||||
end
|
||||
|
||||
function Buffer:apply_mode(name)
|
||||
if self.options.mode == 0 then
|
||||
return string.format('%s%s%s', self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
if self.options.mode == 1 then
|
||||
return string.format('%s %s%s', self.bufnr, self.icon, self.modified_icon)
|
||||
end
|
||||
|
||||
return string.format('%s %s%s%s', self.bufnr, self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
return Buffer
|
||||
|
|
|
@ -48,31 +48,48 @@ function M:init(options)
|
|||
inactive = get_hl('lualine_' .. options.self.section, false),
|
||||
}
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
self.highlights = {
|
||||
active = highlight.create_component_highlight_group(
|
||||
self.options.buffers_color.active,
|
||||
'buffers_active',
|
||||
self.options,
|
||||
false
|
||||
),
|
||||
inactive = highlight.create_component_highlight_group(
|
||||
self.options.buffers_color.inactive,
|
||||
'buffers_inactive',
|
||||
self.options,
|
||||
false
|
||||
),
|
||||
if self.options.component_name == 'buffers' then
|
||||
self.highlights = {
|
||||
active = highlight.create_component_highlight_group(
|
||||
self.options.buffers_color.active,
|
||||
'buffers_active',
|
||||
self.options,
|
||||
false
|
||||
),
|
||||
inactive = highlight.create_component_highlight_group(
|
||||
self.options.buffers_color.inactive,
|
||||
'buffers_inactive',
|
||||
self.options,
|
||||
false
|
||||
),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M:new_buffer(bufnr)
|
||||
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
||||
|
||||
return Buffer:new {
|
||||
bufnr = bufnr,
|
||||
options = self.options,
|
||||
highlights = self.highlights,
|
||||
}
|
||||
end
|
||||
|
||||
function M:buffers()
|
||||
local buffers = {}
|
||||
for b = 1, vim.fn.bufnr('$') do
|
||||
if vim.fn.buflisted(b) ~= 0 and vim.api.nvim_buf_get_option(b, 'buftype') ~= 'quickfix' then
|
||||
buffers[#buffers + 1] = self:new_buffer(b)
|
||||
end
|
||||
end
|
||||
|
||||
return buffers
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
local data = {}
|
||||
local buffers = {}
|
||||
for b = 1, vim.fn.bufnr('$') do
|
||||
if vim.fn.buflisted(b) ~= 0 and vim.api.nvim_buf_get_option(b, 'buftype') ~= 'quickfix' then
|
||||
buffers[#buffers + 1] = Buffer { bufnr = b, options = self.options, highlights = self.highlights }
|
||||
end
|
||||
end
|
||||
local current_bufnr = vim.api.nvim_get_current_buf()
|
||||
local buffers = self:buffers()
|
||||
local current = -2
|
||||
-- mark the first, last, current, before current, after current buffers
|
||||
-- for rendering
|
||||
|
@ -83,7 +100,7 @@ function M:update_status()
|
|||
buffers[#buffers].last = true
|
||||
end
|
||||
for i, buffer in ipairs(buffers) do
|
||||
if buffer.bufnr == current_bufnr then
|
||||
if buffer:is_current() then
|
||||
buffer.current = true
|
||||
current = i
|
||||
end
|
||||
|
@ -112,7 +129,7 @@ function M:update_status()
|
|||
-- start drawing from current buffer and draw left and right of it until
|
||||
-- all buffers are drawn or max_length has been reached.
|
||||
if current == -2 then
|
||||
local b = Buffer { bufnr = vim.api.nvim_get_current_buf(), options = self.options, highlights = self.highlights }
|
||||
local b = self:new_buffer()
|
||||
b.current = true
|
||||
if self.options.self.section < 'x' then
|
||||
b.last = true
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
local Window = require('lualine.components.windows.window')
|
||||
local M = require('lualine.components.buffers'):extend()
|
||||
local highlight = require('lualine.highlight')
|
||||
|
||||
local default_options = {
|
||||
disabled_filetypes = {},
|
||||
disabled_buftypes = { 'quickfix', 'prompt' },
|
||||
}
|
||||
|
||||
function M:init(options)
|
||||
options.buffers_color = nil -- bufers_color isn't windpws option.
|
||||
M.super.init(self, options)
|
||||
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
self.options.windows_color = vim.tbl_deep_extend('keep', self.options.windows_color or {}, self.options.buffers_color)
|
||||
self.options.buffers_color = nil -- this is the default value of colors generated by parent bufferes component.
|
||||
|
||||
self.highlights = {
|
||||
active = highlight.create_component_highlight_group(
|
||||
self.options.windows_color.active,
|
||||
'windows_active',
|
||||
self.options,
|
||||
false
|
||||
),
|
||||
inactive = highlight.create_component_highlight_group(
|
||||
self.options.windows_color.inactive,
|
||||
'windows_inactive',
|
||||
self.options,
|
||||
false
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
function M:new_buffer(winnr)
|
||||
winnr = winnr or vim.api.nvim_get_current_win()
|
||||
|
||||
return Window:new {
|
||||
winnr = winnr,
|
||||
options = self.options,
|
||||
highlights = self.highlights,
|
||||
}
|
||||
end
|
||||
|
||||
--- Override to only return buffers shown in the windows of the current tab
|
||||
function M:buffers()
|
||||
local tabnr = vim.api.nvim_get_current_tabpage()
|
||||
local buffers = {}
|
||||
|
||||
for _, winnr in ipairs(vim.api.nvim_tabpage_list_wins(tabnr)) do
|
||||
if not self:should_hide(winnr) then
|
||||
buffers[#buffers + 1] = self:new_buffer(winnr)
|
||||
end
|
||||
end
|
||||
|
||||
return buffers
|
||||
end
|
||||
|
||||
function M:should_hide(winnr)
|
||||
local bufnr = vim.api.nvim_win_get_buf(winnr)
|
||||
local filetype = vim.api.nvim_buf_get_option(bufnr, 'filetype')
|
||||
local buftype = vim.api.nvim_buf_get_option(bufnr, 'buftype')
|
||||
local is_filetype_disabled = vim.tbl_contains(self.options.disabled_filetypes, filetype)
|
||||
local is_buftype_disabled = vim.tbl_contains(self.options.disabled_buftypes, buftype)
|
||||
local is_floating = '' ~= vim.api.nvim_win_get_config(winnr).relative
|
||||
|
||||
return is_floating or is_buftype_disabled or is_filetype_disabled
|
||||
end
|
||||
|
||||
vim.cmd([[
|
||||
function! LualineSwitchWindow(win_number, mouseclicks, mousebutton, modifiers)
|
||||
execute a:win_number . 'wincmd w'
|
||||
endfunction
|
||||
]])
|
||||
|
||||
return M
|
|
@ -0,0 +1,35 @@
|
|||
local Window = require('lualine.components.buffers.buffer'):extend()
|
||||
|
||||
---intialize a new buffer from opts
|
||||
---@param opts table
|
||||
function Window:init(opts)
|
||||
assert(opts.winnr, 'Cannot create Window without winnr')
|
||||
opts.bufnr = vim.api.nvim_win_get_buf(opts.winnr)
|
||||
|
||||
Window.super.init(self, opts)
|
||||
|
||||
self.winnr = opts.winnr
|
||||
self.win_number = vim.api.nvim_win_get_number(self.winnr)
|
||||
end
|
||||
|
||||
function Window:is_current()
|
||||
return vim.api.nvim_get_current_win() == self.winnr
|
||||
end
|
||||
|
||||
function Window:apply_mode(name)
|
||||
if self.options.mode == 0 then
|
||||
return string.format('%s%s%s', self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
if self.options.mode == 1 then
|
||||
return string.format('%s %s%s', self.win_number, self.icon, self.modified_icon)
|
||||
end
|
||||
|
||||
return string.format('%s %s%s%s', self.win_number, self.icon, name, self.modified_icon)
|
||||
end
|
||||
|
||||
function Window:configure_mouse_click(name)
|
||||
return string.format('%%%s@LualineSwitchWindow@%s%%T', self.win_number, name)
|
||||
end
|
||||
|
||||
return Window
|
|
@ -752,6 +752,55 @@ describe('Lualine', function()
|
|||
]===])
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('windows component', function()
|
||||
it('works', function()
|
||||
local conf = vim.deepcopy(tab_conf)
|
||||
conf.tabline.lualine_a = { { 'windows', max_length = 1e3, mode = 2, icons_enabled = false } }
|
||||
vim.cmd('e ' .. 'a.txt')
|
||||
vim.cmd('tabe ' .. 'b.txt')
|
||||
vim.cmd('vsplit ' .. 'c.txt')
|
||||
vim.cmd('tabe ' .. 'd.txt')
|
||||
require('lualine').setup(conf)
|
||||
require('lualine').statusline()
|
||||
tabline:expect([===[
|
||||
highlights = {
|
||||
1: lualine_a_windows_active = { bg = "#a89984", bold = true, fg = "#282828" }
|
||||
2: lualine_transitional_lualine_a_windows_active_to_lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
|
||||
3: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
|
||||
}
|
||||
|{1: 1 d.txt }
|
||||
{2:}
|
||||
{3: }|
|
||||
]===])
|
||||
|
||||
vim.cmd('tabprev')
|
||||
tabline:expect([===[
|
||||
highlights = {
|
||||
1: lualine_a_windows_active = { bg = "#a89984", bold = true, fg = "#282828" }
|
||||
2: lualine_transitional_lualine_a_windows_active_to_lualine_a_windows_inactive = { bg = "#3c3836", fg = "#a89984" }
|
||||
3: lualine_a_windows_inactive = { bg = "#3c3836", bold = true, fg = "#a89984" }
|
||||
4: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
|
||||
}
|
||||
|{1: 1 c.txt }
|
||||
{2:}
|
||||
{3: 2 b.txt }
|
||||
{4: }|
|
||||
]===])
|
||||
|
||||
vim.cmd('tabprev')
|
||||
tabline:expect([===[
|
||||
highlights = {
|
||||
1: lualine_a_windows_active = { bg = "#a89984", bold = true, fg = "#282828" }
|
||||
2: lualine_transitional_lualine_a_windows_active_to_lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
|
||||
3: lualine_c_normal = { bg = "#3c3836", fg = "#a89984" }
|
||||
}
|
||||
|{1: 1 a.txt }
|
||||
{2:}
|
||||
{3: }|
|
||||
]===])
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('diagnostics', function()
|
||||
|
|
Loading…
Reference in New Issue