Skip to content

Commit 1b59ff5

Browse files
committed
refactor(core): Changed how buffers are attached
feat(core): Added ability to update different bars & lines on filetype changes
1 parent da5a456 commit 1b59ff5

File tree

5 files changed

+173
-21
lines changed

5 files changed

+173
-21
lines changed

lua/bars/statuscolumn.lua

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
local statuscolumn = {};
2+
local utils = require("bars.utils");
23
local components = require("bars.components.statuscolumn");
34

45
---@type statuscolumn.config
56
statuscolumn.config = {
6-
ignore_filetypes = {},
7+
ignore_filetypes = { "query" },
78
ignore_buftypes = { "nofile", "help" },
89

910
default = {
@@ -115,6 +116,19 @@ statuscolumn.config = {
115116
end
116117
},
117118
}
119+
},
120+
121+
query = {
122+
condition = function (buffer)
123+
return vim.bo[buffer].ft == "query";
124+
end,
125+
parts = {
126+
{
127+
kind = "empty",
128+
len = 1,
129+
hl = "Normal"
130+
},
131+
}
118132
}
119133
};
120134

@@ -174,7 +188,7 @@ statuscolumn.render = function (buffer, window)
174188

175189
if window ~= vim.g.statusline_winid then
176190
return "";
177-
elseif vim.list_contains(statuscolumn.state.attached_windows, window) == false then
191+
elseif statuscolumn.state.attached_windows[window] ~= true then
178192
return "";
179193
end
180194

@@ -214,16 +228,21 @@ statuscolumn.detach = function (buffer)
214228
return;
215229
end
216230

217-
for w, win in ipairs(statuscolumn.state.attached_windows) do
218-
if vim.api.nvim_win_get_buf(win) ~= buffer then
219-
goto continue;
220-
end
221-
222-
vim.w[win].__scID = nil;
223-
vim.wo[win].statuscolumn = "";
224-
table.remove(statuscolumn.state.attached_windows, w);
231+
local windows = vim.fn.win_findbuf(buffer)
225232

226-
::continue::
233+
for _, win in ipairs(windows) do
234+
statuscolumn.state.attached_windows[win] = false;
235+
236+
vim.defer_fn(function ()
237+
if vim.w[win].__statuscolumn then
238+
vim.wo[win].statuscolumn = vim.w[win].__statuscolumn[1];
239+
vim.w[win].__statuscolumn = nil;
240+
else
241+
vim.wo[win].statuscolumn = "";
242+
end
243+
244+
vim.w[win].__scID = nil;
245+
end, 1)
227246
end
228247

229248
---|fE
@@ -252,20 +271,33 @@ statuscolumn.attach = function (buffer)
252271
elseif vim.list_contains(statuscolumn.config.ignore_buftypes, bt) then
253272
statuscolumn.detach(buffer);
254273
return;
274+
elseif statuscolumn.config.condition then
275+
local checked_condition, result = pcall(statuscolumn.config.condition, buffer);
276+
277+
if checked_condition == false then
278+
statuscolumn.detach(buffer);
279+
return;
280+
elseif result == false then
281+
statuscolumn.detach(buffer);
282+
return;
283+
end
255284
end
256285

257286
local windows = vim.fn.win_findbuf(buffer);
258287

259288
for _, win in ipairs(windows) do
260-
if vim.list_contains(statuscolumn.state.attached_windows) == true then
289+
if statuscolumn.state.attached_windows[win] == true then
261290
goto continue;
262291
end
263292

264293
local scID = statuscolumn.update_id(win);
265-
table.insert(statuscolumn.state.attached_windows, win);
294+
statuscolumn.state.attached_windows[win] = true;
266295

267296
vim.w[win].__scID = scID;
268297

298+
vim.w[win].__numberwidth = utils.to_constant(vim.wo[win].numberwidth);
299+
vim.w[win].__statuscolumn = utils.to_constant(vim.wo[win].statuscolumn);
300+
269301
vim.wo[win].numberwidth = 1;
270302
vim.wo[win].statuscolumn = "%!v:lua.require('bars.statuscolumn').render(" .. buffer .."," .. win ..")";
271303

@@ -275,6 +307,50 @@ statuscolumn.attach = function (buffer)
275307
---|fE
276308
end
277309

310+
--- Cleans up invalid buffers and recalculates
311+
--- valid buffers config ID.
312+
statuscolumn.clean = function ()
313+
for window, _ in pairs(statuscolumn.state.attached_windows) do
314+
if vim.api.nvim_win_is_valid(window) == false then
315+
statuscolumn.state.attached_windows[window] = false;
316+
goto continue;
317+
end
318+
319+
local buffer = vim.api.nvim_win_get_buf(window);
320+
321+
local ft, bt = vim.bo[buffer].ft, vim.bo[buffer].bt;
322+
323+
if type(buffer) ~= "number" then
324+
statuscolumn.detach(buffer);
325+
return;
326+
elseif vim.api.nvim_buf_is_loaded(buffer) == false then
327+
statuscolumn.detach(buffer);
328+
return;
329+
elseif vim.api.nvim_buf_is_valid(buffer) == false then
330+
statuscolumn.detach(buffer);
331+
return;
332+
elseif vim.list_contains(statuscolumn.config.ignore_filetypes, ft) then
333+
statuscolumn.detach(buffer);
334+
return;
335+
elseif vim.list_contains(statuscolumn.config.ignore_buftypes, bt) then
336+
statuscolumn.detach(buffer);
337+
return;
338+
elseif statuscolumn.config.condition then
339+
local checked_condition, result = pcall(statuscolumn.config.condition, buffer);
340+
341+
if checked_condition == false then
342+
statuscolumn.detach(buffer);
343+
return;
344+
elseif result == false then
345+
statuscolumn.detach(buffer);
346+
return;
347+
end
348+
end
349+
350+
::continue::
351+
end
352+
end
353+
278354
--- Sets up the statuscolumn module.
279355
---@param config statuscolumn.config | nil
280356
statuscolumn.setup = function (config)

lua/bars/statusline.lua

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ statusline.render = function (buffer, window)
445445

446446
if window ~= vim.g.statusline_winid then
447447
return "";
448-
elseif vim.list_contains(statusline.state.attached_windows, window) == false then
448+
elseif statusline.state.attached_windows[window] == false then
449449
return "";
450450
end
451451

@@ -485,15 +485,15 @@ statusline.detach = function (buffer)
485485
return;
486486
end
487487

488-
for w, win in ipairs(statusline.state.attached_windows) do
488+
for win, _ in pairs(statusline.state.attached_windows) do
489489
if vim.api.nvim_win_get_buf(win) ~= buffer then
490490
goto continue;
491491
end
492492

493493
vim.w[win].__slID = nil;
494494
vim.wo[win].statusline = "";
495-
table.remove(statusline.state.attached_windows, w);
496495

496+
statusline.state.attached_windows[win] = false;
497497
::continue::
498498
end
499499

@@ -528,12 +528,12 @@ statusline.attach = function (buffer)
528528
local windows = vim.fn.win_findbuf(buffer);
529529

530530
for _, win in ipairs(windows) do
531-
if vim.list_contains(statusline.state.attached_windows) == true then
531+
if statusline.state.attached_windows[win] == true then
532532
goto continue;
533533
end
534534

535535
local slID = statusline.update_id(win);
536-
table.insert(statusline.state.attached_windows, win);
536+
statusline.state.attached_windows[win] = true;
537537

538538
vim.w[win].__slID = slID;
539539
vim.wo[win].statusline = "%!v:lua.require('bars.statusline').render(" .. buffer .."," .. win ..")";
@@ -544,14 +544,62 @@ statusline.attach = function (buffer)
544544
---|fE
545545
end
546546

547+
--- Cleans up invalid buffers and recalculates
548+
--- valid buffers config ID.
549+
statusline.clean = function ()
550+
---|fS
551+
552+
for window, _ in pairs(statusline.state.attached_windows) do
553+
if vim.api.nvim_win_is_valid(window) == false then
554+
statusline.state.attached_windows[window] = false;
555+
goto continue;
556+
end
557+
558+
local buffer = vim.api.nvim_win_get_buf(window);
559+
560+
local ft, bt = vim.bo[buffer].ft, vim.bo[buffer].bt;
561+
562+
if type(buffer) ~= "number" then
563+
statusline.detach(buffer);
564+
return;
565+
elseif vim.api.nvim_buf_is_loaded(buffer) == false then
566+
statusline.detach(buffer);
567+
return;
568+
elseif vim.api.nvim_buf_is_valid(buffer) == false then
569+
statusline.detach(buffer);
570+
return;
571+
elseif vim.list_contains(statusline.config.ignore_filetypes, ft) then
572+
statusline.detach(buffer);
573+
return;
574+
elseif vim.list_contains(statusline.config.ignore_buftypes, bt) then
575+
statusline.detach(buffer);
576+
return;
577+
elseif statusline.config.condition then
578+
local checked_condition, result = pcall(statusline.config.condition, buffer);
579+
580+
if checked_condition == false then
581+
statusline.detach(buffer);
582+
return;
583+
elseif result == false then
584+
statusline.detach(buffer);
585+
return;
586+
end
587+
end
588+
589+
::continue::
590+
end
591+
592+
---|fE
593+
end
594+
547595
--- Sets up the statusline module.
548596
---@param config statusline.config | nil
549597
statusline.setup = function (config)
550598
if type(config) == "table" then
551599
statusline.config = vim.tbl_extend("force", statusline.config, config);
552600
end
553601

554-
for _, window in ipairs(statusline.state.attached_windows) do
602+
for window, _ in pairs(statusline.state.attached_windows) do
555603
statusline.update_id(window);
556604
end
557605
end

lua/definitions/statuscolumn.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
---@class statuscolumn.state
55
---
66
---@field enable boolean
7-
---@field attached_windows integer[]
7+
---@field attached_windows { [integer]: boolean }
88

99

1010
---@class statuscolumn.config
1111
---
1212
---@field ignore_filetypes string[]
1313
---@field ignore_buftypes string[]
1414
---
15+
---@field condition? fun(buffer: integer): boolean | nil
16+
---
1517
---@field default table
1618
---@field [string] table
1719

lua/definitions/statusline.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ local M = {};
1010
--- When `true`, attach to new windows.
1111
---@field enable boolean
1212
--- List of attached windows.
13-
---@field attached_windows integer[]
13+
---@field attached_windows { [integer]: boolean }
1414

1515
-----------------------------------------------------------------------------
1616

@@ -22,6 +22,8 @@ local M = {};
2222
--- Buftypes to ignore.
2323
---@field ignore_buftypes? string[]
2424
---
25+
---@field condition? fun(buffer: integer): boolean | nil
26+
---
2527
--- Default configuration.
2628
---@field default statusline.group
2729
--- Custom configuration group {string}.

plugin/bars.lua

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,29 @@ vim.api.nvim_create_autocmd({ "VimEnter", "BufEnter", "WinEnter" }, {
55
callback = function (ev)
66
require("bars.statusline").attach(ev.buf);
77
require("bars.statuscolumn").attach(ev.buf);
8+
require("bars.winbar").attach(ev.buf);
9+
end
10+
});
11+
12+
vim.api.nvim_create_autocmd({ "OptionSet" }, {
13+
callback = function (ev)
14+
local buffer = ev.buf;
15+
16+
local option = vim.fn.expand("<amatch>");
17+
local valid_options = { "filetype", "buftype" };
18+
19+
if vim.list_contains(valid_options, option) == false then
20+
return;
21+
elseif buffer == 0 then
22+
buffer = vim.api.nvim_get_current_buf();
23+
end
24+
25+
require("bars.statusline").clean();
26+
require("bars.statuscolumn").clean();
27+
require("bars.winbar").clean();
28+
29+
-- require("bars.statusline").attach(ev.buf);
30+
-- require("bars.statuscolumn").attach(ev.buf);
31+
-- require("bars.winbar").attach(ev.buf);
832
end
933
});

0 commit comments

Comments
 (0)