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)
|
- `mode` (vim mode)
|
||||||
- `progress` (%progress in file)
|
- `progress` (%progress in file)
|
||||||
- `tabs` (shows currently available tabs)
|
- `tabs` (shows currently available tabs)
|
||||||
|
- `windows` (shows currently available windows)
|
||||||
|
|
||||||
#### Custom components
|
#### 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
|
### Tabline
|
||||||
|
|
|
@ -240,6 +240,7 @@ CHANGING COMPONENTS IN LUALINE SECTIONS ~
|
||||||
- `mode` (vim mode)
|
- `mode` (vim mode)
|
||||||
- `progress` (%progress in file)
|
- `progress` (%progress in file)
|
||||||
- `tabs` (shows currently available tabs)
|
- `tabs` (shows currently available tabs)
|
||||||
|
- `windows` (shows currently available windows)
|
||||||
|
|
||||||
|
|
||||||
*lualine-Custom-components*
|
*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 ~
|
TABLINE ~
|
||||||
|
|
|
@ -277,8 +277,8 @@ local function set_statusline()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- lualine.statusline function
|
-- lualine.statusline function
|
||||||
--- Draw correct statusline for current winwow
|
--- Draw correct statusline for current window
|
||||||
---@param focused boolean : force the vale of is_focuased . useful for debugginf
|
---@param focused boolean : force the value of is_focused . useful for debugging
|
||||||
---@return string statusline string
|
---@return string statusline string
|
||||||
local function status_dispatch(focused)
|
local function status_dispatch(focused)
|
||||||
local retval
|
local retval
|
||||||
|
|
|
@ -15,6 +15,10 @@ function Buffer:init(opts)
|
||||||
self:get_props()
|
self:get_props()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Buffer:is_current()
|
||||||
|
return vim.api.nvim_get_current_buf() == self.bufnr
|
||||||
|
end
|
||||||
|
|
||||||
---setup icons, modified status for buffer
|
---setup icons, modified status for buffer
|
||||||
function Buffer:get_props()
|
function Buffer:get_props()
|
||||||
self.file = modules.utils.stl_escape(vim.api.nvim_buf_get_name(self.bufnr))
|
self.file = modules.utils.stl_escape(vim.api.nvim_buf_get_name(self.bufnr))
|
||||||
|
@ -48,6 +52,13 @@ function Buffer:get_props()
|
||||||
end
|
end
|
||||||
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
|
---returns rendered buffer
|
||||||
---@return string
|
---@return string
|
||||||
function Buffer:render()
|
function Buffer:render()
|
||||||
|
@ -59,19 +70,13 @@ function Buffer:render()
|
||||||
if self.ellipse then -- show elipsis
|
if self.ellipse then -- show elipsis
|
||||||
name = '...'
|
name = '...'
|
||||||
else
|
else
|
||||||
if self.options.mode == 0 then
|
name = self:apply_mode(name)
|
||||||
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
|
|
||||||
end
|
end
|
||||||
name = Buffer.apply_padding(name, self.options.padding)
|
name = Buffer.apply_padding(name, self.options.padding)
|
||||||
self.len = vim.fn.strchars(name)
|
self.len = vim.fn.strchars(name)
|
||||||
|
|
||||||
-- setup for mouse clicks
|
-- setup for mouse clicks
|
||||||
local line = string.format('%%%s@LualineSwitchBuffer@%s%%T', self.bufnr, name)
|
local line = self:configure_mouse_click(name)
|
||||||
-- apply highlight
|
-- apply highlight
|
||||||
line = modules.highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')])
|
line = modules.highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')])
|
||||||
.. line
|
.. line
|
||||||
|
@ -119,6 +124,9 @@ function Buffer:name()
|
||||||
elseif self.buftype == 'terminal' then
|
elseif self.buftype == 'terminal' then
|
||||||
local match = string.match(vim.split(self.file, ' ')[1], 'term:.*:(%a+)')
|
local match = string.match(vim.split(self.file, ' ')[1], 'term:.*:(%a+)')
|
||||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
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
|
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||||
return vim.fn.fnamemodify(self.file, ':p:.')
|
return vim.fn.fnamemodify(self.file, ':p:.')
|
||||||
elseif self.file == '' then
|
elseif self.file == '' then
|
||||||
|
@ -139,4 +147,16 @@ function Buffer.apply_padding(str, padding)
|
||||||
return string.rep(' ', l_padding) .. str .. string.rep(' ', r_padding)
|
return string.rep(' ', l_padding) .. str .. string.rep(' ', r_padding)
|
||||||
end
|
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
|
return Buffer
|
||||||
|
|
|
@ -48,6 +48,7 @@ function M:init(options)
|
||||||
inactive = get_hl('lualine_' .. options.self.section, false),
|
inactive = get_hl('lualine_' .. options.self.section, false),
|
||||||
}
|
}
|
||||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||||
|
if self.options.component_name == 'buffers' then
|
||||||
self.highlights = {
|
self.highlights = {
|
||||||
active = highlight.create_component_highlight_group(
|
active = highlight.create_component_highlight_group(
|
||||||
self.options.buffers_color.active,
|
self.options.buffers_color.active,
|
||||||
|
@ -63,16 +64,32 @@ function M:init(options)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function M:update_status()
|
function M:new_buffer(bufnr)
|
||||||
local data = {}
|
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 = {}
|
local buffers = {}
|
||||||
for b = 1, vim.fn.bufnr('$') do
|
for b = 1, vim.fn.bufnr('$') do
|
||||||
if vim.fn.buflisted(b) ~= 0 and vim.api.nvim_buf_get_option(b, 'buftype') ~= 'quickfix' then
|
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 }
|
buffers[#buffers + 1] = self:new_buffer(b)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local current_bufnr = vim.api.nvim_get_current_buf()
|
|
||||||
|
return buffers
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:update_status()
|
||||||
|
local data = {}
|
||||||
|
local buffers = self:buffers()
|
||||||
local current = -2
|
local current = -2
|
||||||
-- mark the first, last, current, before current, after current buffers
|
-- mark the first, last, current, before current, after current buffers
|
||||||
-- for rendering
|
-- for rendering
|
||||||
|
@ -83,7 +100,7 @@ function M:update_status()
|
||||||
buffers[#buffers].last = true
|
buffers[#buffers].last = true
|
||||||
end
|
end
|
||||||
for i, buffer in ipairs(buffers) do
|
for i, buffer in ipairs(buffers) do
|
||||||
if buffer.bufnr == current_bufnr then
|
if buffer:is_current() then
|
||||||
buffer.current = true
|
buffer.current = true
|
||||||
current = i
|
current = i
|
||||||
end
|
end
|
||||||
|
@ -112,7 +129,7 @@ function M:update_status()
|
||||||
-- start drawing from current buffer and draw left and right of it until
|
-- start drawing from current buffer and draw left and right of it until
|
||||||
-- all buffers are drawn or max_length has been reached.
|
-- all buffers are drawn or max_length has been reached.
|
||||||
if current == -2 then
|
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
|
b.current = true
|
||||||
if self.options.self.section < 'x' then
|
if self.options.self.section < 'x' then
|
||||||
b.last = true
|
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)
|
||||||
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)
|
end)
|
||||||
|
|
||||||
describe('diagnostics', function()
|
describe('diagnostics', function()
|
||||||
|
|
Loading…
Reference in New Issue