Skip to content

Commit

Permalink
feat: case-insentive sorting (#598)
Browse files Browse the repository at this point in the history
* feat(config): `ignore_case` option

* feat(api): provide configured sort case converter in `with_pin_order`

This seems like the cleanest way to inject the conversion. We don't know
what is applicable to be converted from within the function, and so we
can't apply it automatically. On the other hand, if we make this a
separate helper function, it will be cumbersome to call it in each
sorting function that needs it.

I would be open to hearing other ideas, though.

* ref(api): use `to_sort_case` in sorting functions where applicable

* docs: `sort.ignore_case`

* perf(api): use function instead of closure

SEE: #598 (comment)
  • Loading branch information
Iron-E authored Jul 17, 2024
1 parent d181f2c commit 53b5a2f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 8 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@ require'barbar'.setup {
-- Sets the name of unnamed buffers. By default format is "[Buffer X]"
-- where X is the buffer number. But only a static string is accepted here.
no_name_title = nil,
-- sorting options
sort = {
-- tells barbar to ignore case differences while sorting buffers
ignore_case = true,
},
}
```
Expand Down
10 changes: 10 additions & 0 deletions doc/barbar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,16 @@ sidebar_filetypes ~
}}
<

*barbar-setup.sort*
sort ~
Configures the `:BufferOrderBy*` commands.

*barbar-setup.sort.ignore_case*
sort.ignore_case ~
`boolean` (default `false`)
If `true`, comparisons of names in buffer orderings will not take into
account differences in case (e.g. 'a' will equal 'A').

*barbar-setup.tabpages*
tabpages ~
`boolean` (default: `true`)
Expand Down
21 changes: 13 additions & 8 deletions lua/barbar/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ local command = vim.api.nvim_command --- @type function
local get_current_buf = vim.api.nvim_get_current_buf --- @type function
local getchar = vim.fn.getchar --- @type function
local set_current_buf = vim.api.nvim_set_current_buf --- @type function
local tolower = vim.fn.tolower

-- TODO: remove `vim.fs and` after 0.8 release
local normalize = vim.fs and vim.fs.normalize
Expand Down Expand Up @@ -59,9 +60,13 @@ local function notify_buffer_not_found(buffer_number)
end

--- Forwards some `order_func` after ensuring that all buffers sorted in the order of pinned first.
--- @param order_func fun(bufnr_a: integer, bufnr_b: integer): boolean accepts `(integer, integer)` params.
--- @param order_func fun(bufnr_a: integer, bufnr_b: integer, to_sort_case: fun(s: string): string): boolean accepts `(integer, integer)` params.
--- @return fun(bufnr_a: integer, bufnr_b: integer): boolean
local function with_pin_order(order_func)
local to_sort_case = config.options.sort.ignore_case and tolower or function(s)
return s
end

return function(a, b)
local a_pinned = state.is_pinned(a)
local b_pinned = state.is_pinned(b)
Expand All @@ -71,7 +76,7 @@ local function with_pin_order(order_func)
elseif b_pinned and not a_pinned then
return false
else
return order_func(a, b)
return order_func(a, b, to_sort_case)
end
end
end
Expand Down Expand Up @@ -364,12 +369,12 @@ end
--- Order the buffers by their name
--- @return nil
function api.order_by_name()
table_sort(state.buffers, with_pin_order(function(a, b)
table_sort(state.buffers, with_pin_order(function(a, b, to_sort_case)
local parts_of_a = vim.split(buf_get_name(a), '/')
local parts_of_b = vim.split(buf_get_name(b), '/')
local name_of_a = parts_of_a[#parts_of_a]
local name_of_b = parts_of_b[#parts_of_b]
return name_of_b > name_of_a
return to_sort_case(name_of_b) > to_sort_case(name_of_a)
end))

render.update()
Expand All @@ -378,10 +383,10 @@ end
--- Order the buffers by their parent directory.
--- @return nil
function api.order_by_directory()
table_sort(state.buffers, with_pin_order(function(a, b)
table_sort(state.buffers, with_pin_order(function(a, b, to_sort_case)
local name_of_a = buf_get_name(a)
local name_of_b = buf_get_name(b)
local compare_a_b = name_of_b > name_of_a
local compare_a_b = to_sort_case(name_of_b) > to_sort_case(name_of_a)

-- TODO: remove this block after 0.8 releases
if not normalize then
Expand Down Expand Up @@ -409,8 +414,8 @@ end
--- Order the buffers by filetype.
--- @return nil
function api.order_by_language()
table_sort(state.buffers, with_pin_order(function(a, b)
return buf_get_option(a, 'filetype') < buf_get_option(b, 'filetype')
table_sort(state.buffers, with_pin_order(function(a, b, to_sort_case)
return to_sort_case(buf_get_option(a, 'filetype')) < to_sort_case(buf_get_option(b, 'filetype'))
end))

render.update()
Expand Down
5 changes: 5 additions & 0 deletions lua/barbar/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ local DEPRECATED_OPTIONS = {
--- @field event? string
--- @field text? string

--- @class barbar.config.options.sort
--- @field ignore_case boolean

--- @class barbar.config.options
--- @field animation boolean
--- @field auto_hide integer
Expand All @@ -216,6 +219,7 @@ local DEPRECATED_OPTIONS = {
--- @field no_name_title? string
--- @field semantic_letters boolean
--- @field sidebar_filetypes {[string]: nil|barbar.config.options.sidebar_filetype}
--- @field sort barbar.config.options.sort
--- @field tabpages boolean

--- @class barbar.Config
Expand Down Expand Up @@ -341,6 +345,7 @@ function config.setup(options)
preset = 'default',
semantic_letters = true,
sidebar_filetypes = {},
sort = { ignore_case = false },
tabpages = true,
})

Expand Down

0 comments on commit 53b5a2f

Please sign in to comment.