feat: api to sort directory contents (#169)
This commit is contained in:
parent
ca2560cae8
commit
879d280617
11 changed files with 256 additions and 54 deletions
|
|
@ -100,6 +100,17 @@ M.set_columns = function(cols)
|
|||
end
|
||||
end
|
||||
|
||||
M.set_sort = function(new_sort)
|
||||
local any_modified = are_any_modified()
|
||||
if any_modified then
|
||||
vim.notify("Cannot change sorting when you have unsaved changes", vim.log.levels.WARN)
|
||||
else
|
||||
config.view_options.sort = new_sort
|
||||
-- TODO only refetch if we don't have all the necessary data for the columns
|
||||
M.rerender_all_oil_buffers({ refetch = true })
|
||||
end
|
||||
end
|
||||
|
||||
-- List of bufnrs
|
||||
local session = {}
|
||||
|
||||
|
|
@ -351,17 +362,46 @@ M.initialize = function(bufnr)
|
|||
keymap_util.set_keymaps("", config.keymaps, bufnr)
|
||||
end
|
||||
|
||||
---@param entry oil.InternalEntry
|
||||
---@return boolean
|
||||
local function is_entry_directory(entry)
|
||||
local type = entry[FIELD_TYPE]
|
||||
if type == "directory" then
|
||||
return true
|
||||
elseif type == "link" then
|
||||
local meta = entry[FIELD_META]
|
||||
return meta and meta.link_stat and meta.link_stat.type == "directory"
|
||||
else
|
||||
return false
|
||||
---@param adapter oil.Adapter
|
||||
---@return fun(a: oil.InternalEntry, b: oil.InternalEntry): boolean
|
||||
local function get_sort_function(adapter)
|
||||
local idx_funs = {}
|
||||
for _, sort_pair in ipairs(config.view_options.sort) do
|
||||
local col_name, order = unpack(sort_pair)
|
||||
if order ~= "asc" and order ~= "desc" then
|
||||
vim.notify_once(
|
||||
string.format(
|
||||
"Column '%s' has invalid sort order '%s'. Should be either 'asc' or 'desc'",
|
||||
col_name,
|
||||
order
|
||||
),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end
|
||||
local col = columns.get_column(adapter, col_name)
|
||||
if col and col.get_sort_value then
|
||||
table.insert(idx_funs, { col.get_sort_value, order })
|
||||
else
|
||||
vim.notify_once(
|
||||
string.format("Column '%s' does not support sorting", col_name),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end
|
||||
end
|
||||
return function(a, b)
|
||||
for _, sort_fn in ipairs(idx_funs) do
|
||||
local get_sort_value, order = unpack(sort_fn)
|
||||
local a_val = get_sort_value(a)
|
||||
local b_val = get_sort_value(b)
|
||||
if a_val ~= b_val then
|
||||
if order == "desc" then
|
||||
return a_val > b_val
|
||||
else
|
||||
return a_val < b_val
|
||||
end
|
||||
end
|
||||
end
|
||||
return a[FIELD_NAME] < b[FIELD_NAME]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -390,14 +430,7 @@ local function render_buffer(bufnr, opts)
|
|||
local entries = cache.list_url(bufname)
|
||||
local entry_list = vim.tbl_values(entries)
|
||||
|
||||
table.sort(entry_list, function(a, b)
|
||||
local a_isdir = is_entry_directory(a)
|
||||
local b_isdir = is_entry_directory(b)
|
||||
if a_isdir ~= b_isdir then
|
||||
return a_isdir
|
||||
end
|
||||
return a[FIELD_NAME] < b[FIELD_NAME]
|
||||
end)
|
||||
table.sort(entry_list, get_sort_function(adapter))
|
||||
|
||||
local jump_idx
|
||||
if opts.jump_first then
|
||||
|
|
@ -512,6 +545,21 @@ M.format_entry_cols = function(entry, column_defs, col_width, adapter)
|
|||
return cols
|
||||
end
|
||||
|
||||
---Get the column names that are used for view and sort
|
||||
---@return string[]
|
||||
local function get_used_columns()
|
||||
local cols = {}
|
||||
for _, def in ipairs(config.columns) do
|
||||
local name = util.split_config(def)
|
||||
table.insert(cols, name)
|
||||
end
|
||||
for _, sort_pair in ipairs(config.view_options.sort) do
|
||||
local name = sort_pair[1]
|
||||
table.insert(cols, name)
|
||||
end
|
||||
return cols
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@param opts nil|table
|
||||
--- preserve_undo nil|boolean
|
||||
|
|
@ -579,7 +627,7 @@ M.render_buffer_async = function(bufnr, opts, callback)
|
|||
end
|
||||
|
||||
cache.begin_update_url(bufname)
|
||||
adapter.list(bufname, config.columns, function(err, entries, fetch_more)
|
||||
adapter.list(bufname, get_used_columns(), function(err, entries, fetch_more)
|
||||
loading.set_loading(bufnr, false)
|
||||
if err then
|
||||
cache.end_update_url(bufname)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue