feat: add windows component (#595)

Co-authored-by: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com>
This commit is contained in:
Camille Dejoye 2022-03-26 14:31:40 +01:00 committed by GitHub
parent 4480d91e60
commit e9b935ccd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 305 additions and 32 deletions

View File

@ -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

View File

@ -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 ~

View File

@ -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

View File

@ -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

View File

@ -48,6 +48,7 @@ function M:init(options)
inactive = get_hl('lualine_' .. options.self.section, false),
}
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
if self.options.component_name == 'buffers' then
self.highlights = {
active = highlight.create_component_highlight_group(
self.options.buffers_color.active,
@ -62,17 +63,33 @@ function M:init(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

View File

@ -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

View File

@ -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

View File

@ -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()