Skip to content

Commit 01e6709

Browse files
committed
fix: sparse icons.diagnostics doesn't work
If you do: ```lua require'barbar'.setup { icons = { diagnostics = { [vim.diagnostic.ERROR] = {enabled = true}, [vim.diagnostic.HINT] = {enabled = true}, }, }, } ``` …it will not work. This is because a function in `Buffer` was using `ipairs`, which stops upon reaching the first `nil` numerical index in a `table`. However, upon fixing this, I discovered another bug: `icons` was not being fully merged. We had a snippet of code to "deep extend" `icons.diagnostics`, but since we were only using `vim.tbl_deep_extend` on the other `icons` options, they did not inherit the diagnostics. I extracted this snippet to a function and called it on all `icons.modified`, `icons.current`, etc.
1 parent c9430fd commit 01e6709

2 files changed

Lines changed: 78 additions & 67 deletions

File tree

‎lua/barbar/buffer.lua‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,29 @@ local min = math.min
77
local table_concat = table.concat
88
local table_insert = table.insert
99

10-
local bufnr = vim.fn.bufnr --- @type function
1110
local buf_get_name = vim.api.nvim_buf_get_name --- @type function
1211
local buf_get_option = vim.api.nvim_buf_get_option --- @type function
1312
local buf_is_valid = vim.api.nvim_buf_is_valid --- @type function
13+
local bufnr = vim.fn.bufnr --- @type function
1414
local bufwinnr = vim.fn.bufwinnr --- @type function
15-
local ERROR = vim.diagnostic.severity.ERROR --- @type integer
1615
local get_current_buf = vim.api.nvim_get_current_buf --- @type function
1716
local get_diagnostics = vim.diagnostic.get --- @type fun(bufnr: integer): {severity: integer}[]
18-
local HINT = vim.diagnostic.severity.HINT --- @type integer
19-
local INFO = vim.diagnostic.severity.INFO --- @type integer
2017
local matchlist = vim.fn.matchlist --- @type function
18+
local severity = vim.diagnostic.severity
2119
local split = vim.split
2220
local strcharpart = vim.fn.strcharpart --- @type function
2321
local strwidth = vim.api.nvim_strwidth --- @type function
24-
local WARN = vim.diagnostic.severity.WARN --- @type integer
2522

2623
local basename = require('barbar.fs').basename
2724
local config = require('barbar.config')
2825
local slice_from_end = require('barbar.utils.list').slice_from_end
2926

3027
local ELLIPSIS = '…'
3128
local ELLIPSIS_LEN = strwidth(ELLIPSIS)
29+
local ERROR = severity.ERROR
30+
local HINT = severity.HINT
31+
local INFO = severity.INFO
32+
local WARN = severity.WARN
3233

3334
--- @alias barbar.buffer.activity 1|2|3|4
3435

@@ -74,14 +75,15 @@ end
7475
--- @return nil
7576
function Buffer.for_each_counted_enabled_diagnostic(buffer_number, diagnostics, f)
7677
local count
77-
for severity_idx, severity_option in ipairs(diagnostics) do
78-
if severity_option.enabled then
78+
for i = 1, #severity do
79+
local option = diagnostics[i]
80+
if option.enabled then
7981
if count == nil then
8082
count = Buffer.count_diagnostics(buffer_number)
8183
end
8284

83-
if count[severity_idx] > 0 then
84-
f(count[severity_idx], severity_idx, severity_option)
85+
if count[i] > 0 then
86+
f(count[i], i, option)
8587
end
8688
end
8789
end

‎lua/barbar/config.lua‎

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -55,36 +55,58 @@ local DEFAULT_DIAGNOSTIC_ICONS = {
5555
[vim.diagnostic.severity.WARN] = { enabled = false, icon = '⚠️ ' },
5656
}
5757

58+
--- Deeply extend `icons` to include the `DEFAULT_DIAGNOSTIC_ICONS`
59+
--- HACK: required because `vim.tbl_deep_extend` does not deep extend lists.
60+
--- @param icons table
61+
--- @see vim.tbl_deep_extend
62+
local function tbl_deep_extend_diagnostic_icons(icons)
63+
for i, default_diagnostic_severity_icons in ipairs(DEFAULT_DIAGNOSTIC_ICONS) do
64+
local diagnostic_severity_icons = icons.diagnostics[i]
65+
if diagnostic_severity_icons == nil then
66+
diagnostic_severity_icons = {}
67+
icons.diagnostics[i] = diagnostic_severity_icons
68+
end
69+
70+
if diagnostic_severity_icons.enabled == nil then
71+
diagnostic_severity_icons.enabled = default_diagnostic_severity_icons.enabled
72+
end
73+
74+
if diagnostic_severity_icons.icon == nil then
75+
diagnostic_severity_icons.icon = default_diagnostic_severity_icons.icon
76+
end
77+
end
78+
end
79+
5880
--- @class barbar.config.options.icons.buffer.filetype
5981
--- @field custom_colors? boolean if present, this color will be used for ALL filetype icons
60-
--- @field enabled? boolean iff `true`, show the `devicons` for the associated buffer's `filetype`.
82+
--- @field enabled boolean iff `true`, show the `devicons` for the associated buffer's `filetype`.
6183

6284
--- @class barbar.config.options.icons.buffer.separator
63-
--- @field left? string a buffer's left separator
64-
--- @field right? string a buffer's right separator
85+
--- @field left string a buffer's left separator
86+
--- @field right string a buffer's right separator
6587

6688
--- @class barbar.config.options.icons.scroll
6789
--- @field left string
6890
--- @field right string
6991

7092
--- @class barbar.config.options.icons.buffer
71-
--- @field buffer_index? boolean iff `true`, show the index of the associated buffer with respect to the ordering of the buffers in the tabline.
72-
--- @field buffer_number? boolean iff `true`, show the `bufnr` for the associated buffer.
73-
--- @field filename? boolean iff `true`, show the filename
74-
--- @field button? false|string the button which is clicked to close / save a buffer, or indicate that it is pinned.
75-
--- @field diagnostics? barbar.config.options.icons.buffer.diagnostics the diagnostic icons
76-
--- @field filetype? barbar.config.options.icons.buffer.filetype filetype icon options
77-
--- @field separator? barbar.config.options.icons.buffer.separator the left-hand separator between buffers in the tabline
93+
--- @field buffer_index boolean iff `true`, show the index of the associated buffer with respect to the ordering of the buffers in the tabline.
94+
--- @field buffer_number boolean iff `true`, show the `bufnr` for the associated buffer.
95+
--- @field filename boolean iff `true`, show the filename
96+
--- @field button false|string the button which is clicked to close / save a buffer, or indicate that it is pinned.
97+
--- @field diagnostics barbar.config.options.icons.buffer.diagnostics the diagnostic icons
98+
--- @field filetype barbar.config.options.icons.buffer.filetype filetype icon options
99+
--- @field separator barbar.config.options.icons.buffer.separator the left-hand separator between buffers in the tabline
78100

79101
--- @class barbar.config.options.icons.state: barbar.config.options.icons.buffer
80-
--- @field modified? barbar.config.options.icons.buffer the icons used for an modified buffer
81-
--- @field pinned? barbar.config.options.icons.buffer the icons used for a pinned buffer
102+
--- @field modified barbar.config.options.icons.buffer the icons used for an modified buffer
103+
--- @field pinned barbar.config.options.icons.buffer the icons used for a pinned buffer
82104

83105
--- @class barbar.config.options.icons: barbar.config.options.icons.state
84-
--- @field alternate? barbar.config.options.icons.state the icons used for an alternate buffer
85-
--- @field current? barbar.config.options.icons.state the icons for the current buffer
106+
--- @field alternate barbar.config.options.icons.state the icons used for an alternate buffer
107+
--- @field current barbar.config.options.icons.state the icons for the current buffer
86108
--- @field inactive barbar.config.options.icons.state the icons for inactive buffers
87-
--- @field visible? barbar.config.options.icons.state the icons for visible buffers
109+
--- @field visible barbar.config.options.icons.state the icons for visible buffers
88110
--- @field scroll barbar.config.options.icons.scroll the scroll arrows
89111
local DEFAULT_ICONS = {
90112
buffer_index = false,
@@ -253,51 +275,38 @@ function config.setup(options)
253275

254276
config.options = tbl_deep_extend('keep', options, DEFAULT_OPTIONS, { icons = default_icons })
255277

256-
-- NOTE: we do this because `vim.tbl_deep_extend` doesn't deep copy lists
257-
for i, default_diagnostic_severity_icons in ipairs(DEFAULT_DIAGNOSTIC_ICONS) do
258-
local diagnostic_severity_icons = config.options.icons.diagnostics[i] or {}
259-
260-
if diagnostic_severity_icons.enabled == nil then
261-
diagnostic_severity_icons.enabled = default_diagnostic_severity_icons.enabled
262-
end
263-
264-
if diagnostic_severity_icons.icon == nil then
265-
diagnostic_severity_icons.icon = default_diagnostic_severity_icons.icon
278+
do
279+
local icons = config.options.icons
280+
281+
--- `config.options.icons` without the recursive structure
282+
--- @type barbar.config.options.icons.buffer
283+
local base_options = {
284+
buffer_index = icons.buffer_index,
285+
buffer_number = icons.buffer_number,
286+
filename = icons.filename,
287+
button = icons.button,
288+
diagnostics = icons.diagnostics,
289+
filetype = icons.filetype,
290+
separator = icons.separator,
291+
}
292+
293+
local modified_icons = icons.modified or {}
294+
local pinned_icons = icons.pinned or {}
295+
296+
-- resolve all of the icons for the activities
297+
for _, activity in ipairs { 'alternate', 'current', 'inactive', 'visible' } do
298+
local activity_icons = tbl_deep_extend('keep', config.options.icons[activity] or {}, base_options)
299+
tbl_deep_extend_diagnostic_icons(activity_icons)
300+
301+
activity_icons.pinned = tbl_deep_extend('keep', activity_icons.pinned or {}, pinned_icons, activity_icons)
302+
tbl_deep_extend_diagnostic_icons(activity_icons.pinned)
303+
304+
activity_icons.modified = tbl_deep_extend('keep', activity_icons.modified or {}, modified_icons, activity_icons)
305+
tbl_deep_extend_diagnostic_icons(activity_icons.modified)
306+
307+
icons[activity] = activity_icons
266308
end
267309
end
268-
269-
local icons = config.options.icons
270-
271-
--- `config.options.icons` without the recursive structure
272-
--- @type barbar.config.options.icons.buffer
273-
local base_options = {
274-
buffer_index = icons.buffer_index,
275-
buffer_number = icons.buffer_number,
276-
filename = icons.filename,
277-
button = icons.button,
278-
diagnostics = icons.diagnostics,
279-
filetype = icons.filetype,
280-
separator = icons.separator,
281-
}
282-
283-
-- resolve all of the icons for the activities
284-
for _, activity in ipairs { 'alternate', 'current', 'inactive', 'visible' } do
285-
local activity_options = tbl_deep_extend('keep', config.options.icons[activity] or {}, base_options)
286-
config.options.icons[activity] = activity_options
287-
config.options.icons[activity].modified = tbl_deep_extend(
288-
'keep',
289-
config.options.icons[activity].modified or {},
290-
config.options.icons.modified or {},
291-
activity_options
292-
)
293-
294-
config.options.icons[activity].pinned = tbl_deep_extend(
295-
'keep',
296-
config.options.icons[activity].pinned or {},
297-
config.options.icons.pinned or {},
298-
activity_options
299-
)
300-
end
301310
end
302311

303312
return config

0 commit comments

Comments
 (0)