diff --git a/lua/oil/adapters/files.lua b/lua/oil/adapters/files.lua index 73d6972..8d4cc18 100644 --- a/lua/oil/adapters/files.lua +++ b/lua/oil/adapters/files.lua @@ -213,19 +213,13 @@ end ---@param url string ---@param column_defs string[] ----@param callback fun(err: nil|string, entries: nil|oil.InternalEntry[]) -M.list = function(url, column_defs, callback) +---@param cb fun(err?: string, fetch_more?: fun()) +M.list = function(url, column_defs, cb) local _, path = util.parse_url(url) assert(path) local dir = fs.posix_to_os_path(path) local fetch_meta = columns.get_metadata_fetcher(M, column_defs) - cache.begin_update_url(url) - local function cb(err, data) - if err or not data then - cache.end_update_url(url) - end - callback(err, data) - end + ---@diagnostic disable-next-line: param-type-mismatch uv.fs_opendir(dir, function(open_err, fd) if open_err then @@ -238,11 +232,7 @@ M.list = function(url, column_defs, callback) end end local read_next - read_next = function(read_err) - if read_err then - cb(read_err) - return - end + read_next = function() uv.fs_readdir(fd, function(err, entries) if err then uv.fs_closedir(fd, function() @@ -254,8 +244,7 @@ M.list = function(url, column_defs, callback) if inner_err then cb(inner_err) else - cb(nil, true) - read_next() + cb(nil, read_next) end end) for _, entry in ipairs(entries) do diff --git a/lua/oil/adapters/ssh.lua b/lua/oil/adapters/ssh.lua index fb87166..05abfe3 100644 --- a/lua/oil/adapters/ssh.lua +++ b/lua/oil/adapters/ssh.lua @@ -206,18 +206,12 @@ end ---@param url string ---@param column_defs string[] ----@param callback fun(err: nil|string, entries: nil|oil.InternalEntry[]) +---@param callback fun(err: nil|string, fetch_more?: fun()) M.list = function(url, column_defs, callback) local res = M.parse_url(url) - cache.begin_update_url(url) local conn = get_connection(url) - conn:list_dir(url, res.path, function(err, data) - if err or not data then - cache.end_update_url(url) - end - callback(err, data) - end) + conn:list_dir(url, res.path, callback) end ---@param bufnr integer diff --git a/lua/oil/adapters/ssh/sshfs.lua b/lua/oil/adapters/ssh/sshfs.lua index 42d7af7..6b4bf10 100644 --- a/lua/oil/adapters/ssh/sshfs.lua +++ b/lua/oil/adapters/ssh/sshfs.lua @@ -124,6 +124,9 @@ end local dir_meta = {} +---@param url string +---@param path string +---@param callback fun(err: nil|string, fetch_more?: fun()) function SSHFS:list_dir(url, path, callback) local path_postfix = "" if path ~= "" then diff --git a/lua/oil/adapters/test.lua b/lua/oil/adapters/test.lua index 0cd0eec..a495269 100644 --- a/lua/oil/adapters/test.lua +++ b/lua/oil/adapters/test.lua @@ -9,9 +9,9 @@ end ---@param url string ---@param column_defs string[] ----@param cb fun(err: nil|string, entries: nil|oil.InternalEntry[]) +---@param cb fun(err?: string, fetch_more?: fun()) M.list = function(url, column_defs, cb) - cb(nil, cache.list_url(url)) + cb() end ---@param name string diff --git a/lua/oil/cache.lua b/lua/oil/cache.lua index 04d82eb..5f0e60c 100644 --- a/lua/oil/cache.lua +++ b/lua/oil/cache.lua @@ -88,12 +88,14 @@ M.create_and_store_entry = function(parent_url, name, type) return entry end +---@param parent_url string M.begin_update_url = function(parent_url) parent_url = util.addslash(parent_url) tmp_url_directory[parent_url] = url_directory[parent_url] url_directory[parent_url] = {} end +---@param parent_url string M.end_update_url = function(parent_url) parent_url = util.addslash(parent_url) if not tmp_url_directory[parent_url] then diff --git a/lua/oil/init.lua b/lua/oil/init.lua index 08200c0..db25c44 100644 --- a/lua/oil/init.lua +++ b/lua/oil/init.lua @@ -10,17 +10,16 @@ local M = {} ---@alias oil.TextChunk string|string[] ---@class oil.Adapter ----@field name string ----@field list fun(path: string, column_defs: string[], cb: fun(err: nil|string, entries: nil|oil.InternalEntry[])) ----@field is_modifiable fun(bufnr: integer): boolean ----@field get_column fun(name: string): nil|oil.ColumnDefinition ----@field normalize_url fun(url: string, callback: fun(url: string)) ----@field get_parent nil|fun(bufname: string): string ----@field supports_xfer nil|table ----@field render_action nil|fun(action: oil.Action): string ----@field perform_action nil|fun(action: oil.Action, cb: fun(err: nil|string)) ----@field read_file fun(bufnr: integer) ----@field write_file fun(bufnr: integer) +---@field name string The unique name of the adapter (this will be set automatically) +---@field list fun(path: string, column_defs: string[], cb: fun(err: nil|string, fetch_more: nil|fun())) Async function to list a directory. Entries should be stored in the cache. +---@field is_modifiable fun(bufnr: integer): boolean Return true if this directory is modifiable (allows for directories with read-only permissions). +---@field get_column fun(name: string): nil|oil.ColumnDefinition If the adapter has any adapter-specific columns, return them when fetched by name. +---@field normalize_url fun(url: string, callback: fun(url: string)) Before oil opens a url it will be normalized. This allows for link following, path normalizing, and converting an oil file url to the actual path of a file. +---@field render_action? fun(action: oil.Action): string Render a mutation action for display in the preview window. Only needed if adapter is modifiable. +---@field perform_action? fun(action: oil.Action, cb: fun(err: nil|string)) Perform a mutation action. Only needed if adapter is modifiable. +---@field read_file? fun(bufnr: integer) Used for adapters that deal with remote/virtual files. Read the contents of the file into a buffer. +---@field write_file? fun(bufnr: integer) Used for adapters that deal with remote/virtual files. Write the contents of a buffer to the destination. +---@field supports_xfer? table This and all other parts of cross-adapter actions are WIP and not a stable API. -- TODO remove after https://github.com/folke/neodev.nvim/pull/163 lands ---@diagnostic disable: undefined-field diff --git a/lua/oil/view.lua b/lua/oil/view.lua index 2342d37..5012c1d 100644 --- a/lua/oil/view.lua +++ b/lua/oil/view.lua @@ -578,12 +578,14 @@ M.render_buffer_async = function(bufnr, opts, callback) return end - adapter.list(bufname, config.columns, function(err, has_more) + cache.begin_update_url(bufname) + adapter.list(bufname, config.columns, function(err, fetch_more) loading.set_loading(bufnr, false) if err then + cache.end_update_url(bufname) handle_error(err) return - elseif has_more then + elseif fetch_more then local now = vim.loop.hrtime() / 1e6 local delta = now - start_ms -- If we've been chugging for more than 40ms, go ahead and render what we have @@ -595,7 +597,9 @@ M.render_buffer_async = function(bufnr, opts, callback) end) end first = false + vim.defer_fn(fetch_more, 4) else + cache.end_update_url(bufname) -- done iterating finish() end