Skip to content

Commit 01b0b9d

Browse files
committed
perf: change default view_options.natural_order behavior to disable on large directories
1 parent 7d4e629 commit 01b0b9d

File tree

5 files changed

+42
-25
lines changed

5 files changed

+42
-25
lines changed

README.md

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

doc/oil.txt

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

lua/oil/columns.lua

+25-11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ local all_columns = {}
1919
---@field render_action? fun(action: oil.ChangeAction): string
2020
---@field perform_action? fun(action: oil.ChangeAction, callback: fun(err: nil|string))
2121
---@field get_sort_value? fun(entry: oil.InternalEntry): number|string
22+
---@field create_sort_value_factory? fun(num_entries: integer): fun(entry: oil.InternalEntry): number|string
2223

2324
---@param name string
2425
---@param column oil.ColumnDefinition
@@ -292,18 +293,31 @@ M.register("name", {
292293
error("Do not use the name column. It is for sorting only")
293294
end,
294295

295-
get_sort_value = function(entry)
296-
local sort_value = entry[FIELD_NAME]
297-
298-
if config.view_options.natural_order then
299-
sort_value = sort_value:gsub("%d+", pad_number)
300-
end
301-
302-
if config.view_options.case_insensitive then
303-
sort_value = sort_value:lower()
296+
create_sort_value_factory = function(num_entries)
297+
if
298+
config.view_options.natural_order == false
299+
or (config.view_options.natural_order == "fast" and num_entries > 5000)
300+
then
301+
if config.view_options.case_insensitive then
302+
return function(entry)
303+
return entry[FIELD_NAME]:lower()
304+
end
305+
else
306+
return function(entry)
307+
return entry[FIELD_NAME]
308+
end
309+
end
310+
else
311+
if config.view_options.case_insensitive then
312+
return function(entry)
313+
return entry[FIELD_NAME]:gsub("%d+", pad_number):lower()
314+
end
315+
else
316+
return function(entry)
317+
return entry[FIELD_NAME]:gsub("%d+", pad_number)
318+
end
319+
end
304320
end
305-
306-
return sort_value
307321
end,
308322
})
309323

lua/oil/config.lua

+5-5
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ local default_config = {
9090
is_always_hidden = function(name, bufnr)
9191
return false
9292
end,
93-
-- Sort file names in a more intuitive order for humans. Is less performant,
94-
-- so you may want to set to false if you work with large directories.
95-
natural_order = true,
93+
-- Sort file names with numbers in a more intuitive order for humans.
94+
-- Can be "fast", true, or false. "fast" will turn it off for large directories.
95+
natural_order = "fast",
9696
-- Sort file and directory names case insensitive
9797
case_insensitive = false,
9898
sort = {
@@ -273,15 +273,15 @@ local M = {}
273273
---@field show_hidden boolean
274274
---@field is_hidden_file fun(name: string, bufnr: integer): boolean
275275
---@field is_always_hidden fun(name: string, bufnr: integer): boolean
276-
---@field natural_order boolean
276+
---@field natural_order boolean|"fast"
277277
---@field case_insensitive boolean
278278
---@field sort oil.SortSpec[]
279279

280280
---@class (exact) oil.SetupViewOptions
281281
---@field show_hidden? boolean Show files and directories that start with "."
282282
---@field is_hidden_file? fun(name: string, bufnr: integer): boolean This function defines what is considered a "hidden" file
283283
---@field is_always_hidden? fun(name: string, bufnr: integer): boolean This function defines what will never be shown, even when `show_hidden` is set
284-
---@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.
284+
---@field natural_order? boolean|"fast" Sort file names with numbers in a more intuitive order for humans. Can be slow for large directories.
285285
---@field case_insensitive? boolean Sort file and directory names case insensitive
286286
---@field sort? oil.SortSpec[] Sort order for the file list
287287

lua/oil/view.lua

+6-3
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,9 @@ M.initialize = function(bufnr)
537537
end
538538

539539
---@param adapter oil.Adapter
540+
---@param num_entries integer
540541
---@return fun(a: oil.InternalEntry, b: oil.InternalEntry): boolean
541-
local function get_sort_function(adapter)
542+
local function get_sort_function(adapter, num_entries)
542543
local idx_funs = {}
543544
local sort_config = config.view_options.sort
544545

@@ -560,7 +561,9 @@ local function get_sort_function(adapter)
560561
)
561562
end
562563
local col = columns.get_column(adapter, col_name)
563-
if col and col.get_sort_value then
564+
if col and col.create_sort_value_factory then
565+
table.insert(idx_funs, { col.create_sort_value_factory(num_entries), order })
566+
elseif col and col.get_sort_value then
564567
table.insert(idx_funs, { col.get_sort_value, order })
565568
else
566569
vim.notify_once(
@@ -611,7 +614,7 @@ local function render_buffer(bufnr, opts)
611614
local entries = cache.list_url(bufname)
612615
local entry_list = vim.tbl_values(entries)
613616

614-
table.sort(entry_list, get_sort_function(adapter))
617+
table.sort(entry_list, get_sort_function(adapter, #entry_list))
615618

616619
local jump_idx
617620
if opts.jump_first then

0 commit comments

Comments
 (0)