Skip to content

Commit 8c43622

Browse files
committed
feat(tabline): Added buffer list part
fix(tabline): Fixed navigation function
1 parent 975db26 commit 8c43622

File tree

4 files changed

+334
-3
lines changed

4 files changed

+334
-3
lines changed

lua/bars/components/tabline.lua

Lines changed: 205 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ tlC.tabs = function (config)
5757
end
5858

5959
---@type integer Start index. Must be above 0;
60-
local from = math.max(vim.g.__bars_tabpage_from, 1);
60+
local from = utils.clamp(vim.g.__bars_tabpage_from, 1, #tabs);
6161
---@type integer Number of tabs to show.
6262
local max = config.max or 5;
6363
---@type boolean Is the list position locked?
@@ -193,6 +193,210 @@ tlC.tabs = function (config)
193193
---|fE
194194
end
195195

196+
--- Tab list.
197+
---@param config tabline.parts.tabs
198+
---@return string
199+
tlC.bufs = function (config)
200+
---|fS
201+
202+
local function truncate_fname (fname, name_len)
203+
name_len = name_len or 15;
204+
205+
if vim.fn.strchars(fname) <= name_len then
206+
return fname;
207+
else
208+
local truncate_symbol = config.truncate_symbol or "";
209+
210+
local ext = vim.fn.fnamemodify(fname, ":e");
211+
local name = vim.fn.fnamemodify(fname, ":t:r");
212+
213+
local available_len = name_len - vim.fn.strchars(ext .. truncate_symbol .. ".");
214+
215+
return string.format(
216+
"%s%s%s%s",
217+
vim.fn.strcharpart(name, 0, math.max(available_len, 2)),
218+
truncate_symbol,
219+
ext ~= "" and "." or "",
220+
ext ~= "" and ext or ""
221+
);
222+
end
223+
end
224+
225+
local bufs = utils.get_valid_bufs();
226+
local _o = "";
227+
228+
if not vim.g.__bars_buf_from then
229+
vim.g.__bars_buf_from = 1;
230+
elseif vim.g.__bars_buf_from > #bufs then
231+
vim.g.__bars_buf_from = 1;
232+
end
233+
234+
if not vim.g.__bars_tabpage_list_locked then
235+
vim.g.__bars_tabpage_list_locked = false;
236+
end
237+
238+
---@type integer Start index. Must be above 0;
239+
local from = utils.clamp(vim.g.__bars_buf_from, 1, #bufs);
240+
---@type integer Number of bufs to show.
241+
local max = config.max or 5;
242+
---@type boolean Is the list position locked?
243+
local locked = vim.g.__bars_tabpage_list_locked;
244+
245+
--- Maximum number of bufs to show.
246+
--- Stored to he used by `autocmds`.
247+
vim.g.__tabline_max_bufs = max;
248+
249+
if from ~= 1 then
250+
if locked == true then
251+
_o = table.concat({
252+
_o,
253+
254+
utils.create_segmant(config.nav_left_locked, config.nav_left_locked_hl),
255+
});
256+
else
257+
_o = table.concat({
258+
_o,
259+
260+
"%@v:lua.__buf_from_decrease@",
261+
utils.create_segmant(config.nav_left, config.nav_left_hl),
262+
"%X"
263+
});
264+
end
265+
end
266+
267+
local wrapped = false;
268+
269+
for t = from, from + (max - 1), 1 do
270+
local buf_index = wrapped_index(#bufs, t);
271+
local buffer = bufs[buf_index];
272+
273+
if t > #bufs then
274+
if buf_index == wrapped_index(#bufs, from) and wrapped == true then
275+
--- Do not wrap around multiple
276+
--- times.
277+
break;
278+
elseif from == 1 and #bufs < max then
279+
--- If we are showing bufs from
280+
--- the start and the number of
281+
--- bufs are less than the amount
282+
--- we can show, then don't wrap.
283+
break;
284+
elseif buf_index == 1 then
285+
--- Wrap marker should only be added
286+
--- to the 1st entry.
287+
wrapped = true;
288+
289+
_o = table.concat({
290+
_o,
291+
utils.set_hl(config.overflow_hl),
292+
config.overflow or ""
293+
});
294+
else
295+
_o = table.concat({
296+
_o,
297+
utils.create_segmant(config.separator, config.separator_hl)
298+
});
299+
end
300+
elseif buf_index ~= 1 then
301+
_o = table.concat({
302+
_o,
303+
utils.create_segmant(config.separator, config.separator_hl)
304+
});
305+
end
306+
307+
local current = buffer == vim.api.nvim_get_current_buf();
308+
local buf_config = current == true and (config.active or {}) or (config.inactive or {});
309+
310+
if current == false then
311+
utils.create_to_buf(buffer)
312+
end
313+
314+
local name = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(buffer), ":t");
315+
316+
if name == "" then
317+
name = "New file";
318+
end
319+
320+
if buf_config.ft_icon ~= false and pcall(require, "icons") then
321+
local icon_config = require("icons").get(
322+
vim.fn.fnamemodify(name, ":e"),
323+
{
324+
buf_config.icon_hl, buf_config.icon,
325+
buf_config.icon_hl, buf_config.icon,
326+
buf_config.icon_hl, buf_config.icon,
327+
}
328+
);
329+
330+
buf_config.icon = icon_config.icon;
331+
---@type string
332+
buf_config.icon_hl = buf_config.icon_hl or icon_config.hl;
333+
end
334+
335+
_o = table.concat({
336+
_o,
337+
338+
current == false and "%@v:lua.__tabline_to_buf.b" .. buffer .. "@" or "",
339+
340+
utils.create_segmant(buf_config.corner_left, buf_config.corner_left_hl or buf_config.hl),
341+
utils.create_segmant(buf_config.padding_left, buf_config.padding_left_hl or buf_config.hl),
342+
343+
utils.create_segmant(buf_config.icon, buf_config.icon_hl),
344+
});
345+
346+
if type(buf_config.win_count) == "string" then
347+
local wins = vim.fn.win_findbuf(buffer);
348+
349+
_o = table.concat({
350+
_o,
351+
352+
utils.create_segmant(truncate_fname(name), buf_config.hl),
353+
utils.create_segmant(
354+
string.format(buf_config.win_count, #wins),
355+
buf_config.win_count_hl
356+
),
357+
});
358+
else
359+
_o = table.concat({
360+
_o,
361+
utils.create_segmant(truncate_fname(name, buf_config.max_name_len), buf_config.hl)
362+
});
363+
end
364+
365+
_o = table.concat({
366+
_o,
367+
368+
utils.create_segmant(buf_config.padding_right, buf_config.padding_right_hl or buf_config.hl),
369+
utils.create_segmant(buf_config.corner_right, buf_config.corner_right_hl or buf_config.hl),
370+
371+
current == false and "%T" or ""
372+
});
373+
end
374+
375+
if max < #bufs then
376+
if locked == true then
377+
_o = table.concat({
378+
_o,
379+
380+
utils.create_segmant(config.separator, config.separator_hl),
381+
utils.create_segmant(config.nav_right_locked, config.nav_right_locked_hl),
382+
});
383+
else
384+
_o = table.concat({
385+
_o,
386+
387+
utils.create_segmant(config.separator, config.separator_hl),
388+
389+
"%@v:lua.__buf_from_increase@",
390+
utils.create_segmant(config.nav_right, config.nav_right_hl),
391+
"%X"
392+
});
393+
end
394+
end
395+
396+
return _o;
397+
---|fE
398+
end
399+
196400
--- Returns the output of the section {name}.
197401
---@param part_config table
198402
---@param tabline string

lua/bars/global.lua

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
local statusline = require("bars.statusline");
2+
local utils = require("bars.utils");
23

34
--- Changes the type of diagnostic
45
--- that are shown on the statusline.
@@ -26,7 +27,8 @@ _G.__change_diagnostic_state = function ()
2627
});
2728
end
2829

29-
_G.__tab_from_decrease = function ()
30+
31+
_G.__tab_from_increase = function ()
3032
if not vim.g.__bars_tabpage_from then
3133
vim.g.__bars_tabpage_from = 1;
3234
return;
@@ -47,7 +49,7 @@ _G.__tab_from_decrease = function ()
4749
});
4850
end
4951

50-
_G.__tab_from_increase = function ()
52+
_G.__tab_from_decrease = function ()
5153
if not vim.g.__bars_tabpage_from then
5254
vim.g.__bars_tabpage_from = 1;
5355
return;
@@ -68,3 +70,48 @@ _G.__tab_from_increase = function ()
6870
});
6971
end
7072

73+
74+
_G.__buf_from_decrease = function ()
75+
if not vim.g.__bars_buf_from then
76+
vim.g.__bars_buf_from = 1;
77+
return;
78+
end
79+
80+
---@type integer Number of buffers.
81+
local bufs = #utils.get_valid_bufs();
82+
83+
if vim.g.__bars_buf_from - 1 < 1 then
84+
vim.g.__bars_buf_from = bufs;
85+
else
86+
vim.g.__bars_buf_from = vim.g.__bars_buf_from - 1;
87+
end
88+
89+
pcall(vim.api.nvim__redraw, {
90+
flush = true,
91+
tabline = true
92+
});
93+
end
94+
95+
_G.__buf_from_increase = function ()
96+
if not vim.g.__bars_buf_from then
97+
vim.g.__bars_buf_from = 1;
98+
return;
99+
end
100+
101+
---@type integer Number of buffers.
102+
local bufs = #utils.get_valid_bufs();
103+
104+
if vim.g.__bars_buf_from + 1 > bufs then
105+
vim.g.__bars_buf_from = 1;
106+
else
107+
vim.g.__bars_buf_from = vim.g.__bars_buf_from + 1;
108+
end
109+
110+
pcall(vim.api.nvim__redraw, {
111+
flush = true,
112+
tabline = true
113+
});
114+
end
115+
116+
_G.__tabline_to_buf = {};
117+

lua/bars/tabline.lua

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ tabline.config = {
1111
{ kind = "empty", hl = "Normal" },
1212
{
1313
kind = "tabs",
14+
condition = function ()
15+
return vim.g.__show_bufs ~= true;
16+
end,
17+
1418

1519
separator = " ",
1620
separator_hl = "Normal",
@@ -50,6 +54,51 @@ tabline.config = {
5054
hl = "Color0B"
5155
}
5256
},
57+
{
58+
kind = "bufs",
59+
condition = function ()
60+
return vim.g.__show_bufs == true;
61+
end,
62+
63+
separator = " ",
64+
separator_hl = "Normal",
65+
66+
overflow = "",
67+
overflow_hl = "Layer1I",
68+
69+
nav_left = "",
70+
nav_left_hl = "Color0",
71+
72+
nav_left_locked = " ",
73+
nav_left_locked_hl = "Color1",
74+
75+
nav_right = "",
76+
nav_right_hl = "Color0",
77+
78+
nav_right_locked = " 󰌾 ",
79+
nav_right_locked_hl = "Color1",
80+
81+
active = {
82+
padding_left = " ",
83+
padding_right = " ",
84+
85+
win_count = " ┃ 󰨝 %d",
86+
win_count_hl = nil,
87+
88+
icon = "",
89+
90+
hl = "Color7R"
91+
},
92+
inactive = {
93+
padding_left = " ",
94+
padding_right = " ",
95+
96+
icon = "",
97+
98+
hl = "Color0B",
99+
max_name_len = 10,
100+
}
101+
},
53102
{ kind = "empty", hl = "Normal" },
54103
}
55104
}

lua/bars/utils.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,35 @@ utils.create_segmant = function (text, hl)
128128
---|fE
129129
end
130130

131+
--- Gets the list of valid buffers
132+
---@return integer[]
133+
utils.get_valid_bufs = function ()
134+
local bufs = vim.api.nvim_list_bufs();
135+
local _b = {};
136+
137+
for _, buf in ipairs(bufs) do
138+
if vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].bt == "" then
139+
table.insert(_b, buf);
140+
end
141+
end
142+
143+
return _b;
144+
end
145+
146+
utils.create_to_buf = function (buffer)
147+
if type(_G.__tabline_to_buf) ~= "table" then
148+
_G.__tabline_to_buf = {};
149+
end
150+
151+
_G.__tabline_to_buf["b" .. buffer] = function ()
152+
if vim.api.nvim_buf_is_valid(buffer) == false then
153+
return;
154+
elseif #vim.fn.win_findbuf(buffer) > 0 then
155+
vim.api.nvim_set_current_win(vim.fn.win_findbuf(buffer)[1]);
156+
else
157+
vim.api.nvim_set_current_buf(buffer);
158+
end
159+
end
160+
end
161+
131162
return utils;

0 commit comments

Comments
 (0)