perf: change default view_options.natural_order behavior to disable on large directories

This commit is contained in:
Steven Arcangeli 2024-11-14 19:18:19 -08:00
parent 7d4e62942f
commit 01b0b9d8ef
5 changed files with 42 additions and 25 deletions

View file

@ -220,9 +220,9 @@ require("oil").setup({
is_always_hidden = function(name, bufnr) is_always_hidden = function(name, bufnr)
return false return false
end, end,
-- Sort file names in a more intuitive order for humans. Is less performant, -- Sort file names with numbers in a more intuitive order for humans.
-- so you may want to set to false if you work with large directories. -- Can be "fast", true, or false. "fast" will turn it off for large directories.
natural_order = true, natural_order = "fast",
-- Sort file and directory names case insensitive -- Sort file and directory names case insensitive
case_insensitive = false, case_insensitive = false,
sort = { sort = {

View file

@ -105,9 +105,9 @@ CONFIG *oil-confi
is_always_hidden = function(name, bufnr) is_always_hidden = function(name, bufnr)
return false return false
end, end,
-- Sort file names in a more intuitive order for humans. Is less performant, -- Sort file names with numbers in a more intuitive order for humans.
-- so you may want to set to false if you work with large directories. -- Can be "fast", true, or false. "fast" will turn it off for large directories.
natural_order = true, natural_order = "fast",
-- Sort file and directory names case insensitive -- Sort file and directory names case insensitive
case_insensitive = false, case_insensitive = false,
sort = { sort = {

View file

@ -19,6 +19,7 @@ local all_columns = {}
---@field render_action? fun(action: oil.ChangeAction): string ---@field render_action? fun(action: oil.ChangeAction): string
---@field perform_action? fun(action: oil.ChangeAction, callback: fun(err: nil|string)) ---@field perform_action? fun(action: oil.ChangeAction, callback: fun(err: nil|string))
---@field get_sort_value? fun(entry: oil.InternalEntry): number|string ---@field get_sort_value? fun(entry: oil.InternalEntry): number|string
---@field create_sort_value_factory? fun(num_entries: integer): fun(entry: oil.InternalEntry): number|string
---@param name string ---@param name string
---@param column oil.ColumnDefinition ---@param column oil.ColumnDefinition
@ -292,18 +293,31 @@ M.register("name", {
error("Do not use the name column. It is for sorting only") error("Do not use the name column. It is for sorting only")
end, end,
get_sort_value = function(entry) create_sort_value_factory = function(num_entries)
local sort_value = entry[FIELD_NAME] if
config.view_options.natural_order == false
if config.view_options.natural_order then or (config.view_options.natural_order == "fast" and num_entries > 5000)
sort_value = sort_value:gsub("%d+", pad_number) then
if config.view_options.case_insensitive then
return function(entry)
return entry[FIELD_NAME]:lower()
end
else
return function(entry)
return entry[FIELD_NAME]
end
end
else
if config.view_options.case_insensitive then
return function(entry)
return entry[FIELD_NAME]:gsub("%d+", pad_number):lower()
end
else
return function(entry)
return entry[FIELD_NAME]:gsub("%d+", pad_number)
end
end
end end
if config.view_options.case_insensitive then
sort_value = sort_value:lower()
end
return sort_value
end, end,
}) })

View file

@ -90,9 +90,9 @@ local default_config = {
is_always_hidden = function(name, bufnr) is_always_hidden = function(name, bufnr)
return false return false
end, end,
-- Sort file names in a more intuitive order for humans. Is less performant, -- Sort file names with numbers in a more intuitive order for humans.
-- so you may want to set to false if you work with large directories. -- Can be "fast", true, or false. "fast" will turn it off for large directories.
natural_order = true, natural_order = "fast",
-- Sort file and directory names case insensitive -- Sort file and directory names case insensitive
case_insensitive = false, case_insensitive = false,
sort = { sort = {
@ -273,7 +273,7 @@ local M = {}
---@field show_hidden boolean ---@field show_hidden boolean
---@field is_hidden_file fun(name: string, bufnr: integer): boolean ---@field is_hidden_file fun(name: string, bufnr: integer): boolean
---@field is_always_hidden fun(name: string, bufnr: integer): boolean ---@field is_always_hidden fun(name: string, bufnr: integer): boolean
---@field natural_order boolean ---@field natural_order boolean|"fast"
---@field case_insensitive boolean ---@field case_insensitive boolean
---@field sort oil.SortSpec[] ---@field sort oil.SortSpec[]
@ -281,7 +281,7 @@ local M = {}
---@field show_hidden? boolean Show files and directories that start with "." ---@field show_hidden? boolean Show files and directories that start with "."
---@field is_hidden_file? fun(name: string, bufnr: integer): boolean This function defines what is considered a "hidden" file ---@field is_hidden_file? fun(name: string, bufnr: integer): boolean This function defines what is considered a "hidden" file
---@field is_always_hidden? fun(name: string, bufnr: integer): boolean This function defines what will never be shown, even when `show_hidden` is set ---@field is_always_hidden? fun(name: string, bufnr: integer): boolean This function defines what will never be shown, even when `show_hidden` is set
---@field natural_order? boolean Sort file names in a more intuitive order for humans. Is less performant, so you may want to set to false if you work with large directories. ---@field natural_order? boolean|"fast" Sort file names with numbers in a more intuitive order for humans. Can be slow for large directories.
---@field case_insensitive? boolean Sort file and directory names case insensitive ---@field case_insensitive? boolean Sort file and directory names case insensitive
---@field sort? oil.SortSpec[] Sort order for the file list ---@field sort? oil.SortSpec[] Sort order for the file list

View file

@ -537,8 +537,9 @@ M.initialize = function(bufnr)
end end
---@param adapter oil.Adapter ---@param adapter oil.Adapter
---@param num_entries integer
---@return fun(a: oil.InternalEntry, b: oil.InternalEntry): boolean ---@return fun(a: oil.InternalEntry, b: oil.InternalEntry): boolean
local function get_sort_function(adapter) local function get_sort_function(adapter, num_entries)
local idx_funs = {} local idx_funs = {}
local sort_config = config.view_options.sort local sort_config = config.view_options.sort
@ -560,7 +561,9 @@ local function get_sort_function(adapter)
) )
end end
local col = columns.get_column(adapter, col_name) local col = columns.get_column(adapter, col_name)
if col and col.get_sort_value then if col and col.create_sort_value_factory then
table.insert(idx_funs, { col.create_sort_value_factory(num_entries), order })
elseif col and col.get_sort_value then
table.insert(idx_funs, { col.get_sort_value, order }) table.insert(idx_funs, { col.get_sort_value, order })
else else
vim.notify_once( vim.notify_once(
@ -611,7 +614,7 @@ local function render_buffer(bufnr, opts)
local entries = cache.list_url(bufname) local entries = cache.list_url(bufname)
local entry_list = vim.tbl_values(entries) local entry_list = vim.tbl_values(entries)
table.sort(entry_list, get_sort_function(adapter)) table.sort(entry_list, get_sort_function(adapter, #entry_list))
local jump_idx local jump_idx
if opts.jump_first then if opts.jump_first then