From ee813638d2d042e4b8e6e8ffd00dae438bdbd4ca Mon Sep 17 00:00:00 2001 From: Steven Arcangeli Date: Sat, 30 Sep 2023 14:19:12 -0700 Subject: [PATCH] feat: make gf work in ssh files (#186) --- lua/oil/adapters/ssh.lua | 43 ++++++++++++++++++++++++++++++++++++++++ lua/oil/util.lua | 29 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/lua/oil/adapters/ssh.lua b/lua/oil/adapters/ssh.lua index d0584f83..b69b0748 100644 --- a/lua/oil/adapters/ssh.lua +++ b/lua/oil/adapters/ssh.lua @@ -10,6 +10,7 @@ local shell = require("oil.shell") local util = require("oil.util") local M = {} +local FIELD_NAME = constants.FIELD_NAME local FIELD_META = constants.FIELD_META ---@class (exact) oil.sshUrl @@ -385,6 +386,7 @@ M.read_file = function(bufnr) end vim.cmd.doautocmd({ args = { "BufReadPost", bufname }, mods = { silent = true } }) vim.api.nvim_buf_delete(tmp_bufnr, { force = true }) + vim.keymap.set("n", "gf", M.goto_file, { buffer = bufnr }) end) end @@ -416,4 +418,45 @@ M.write_file = function(bufnr) end) end +M.goto_file = function() + local url = M.parse_url(vim.api.nvim_buf_get_name(0)) + local word = vim.fn.expand("") + local fname = vim.fn.matchlist(word, "\\v\\f+")[1] + local fullpath = fname + if not fs.is_absolute(fname) then + local pardir = vim.fs.dirname(url.path) + fullpath = fs.join(pardir, fname) + end + url.path = vim.fs.dirname(fullpath) + local parurl = url_to_str(url) + + util.adapter_list_all(M, parurl, {}, function(err, entries) + if err then + vim.notify(string.format("Error finding file '%s': %s", fname, err), vim.log.levels.ERROR) + return + end + assert(entries) + local name_map = {} + for _, entry in ipairs(entries) do + name_map[entry[FIELD_NAME]] = entry + end + + local basename = vim.fs.basename(fullpath) + if name_map[basename] then + url.path = fullpath + vim.cmd.edit({ args = { url_to_str(url) } }) + return + end + for suffix in vim.gsplit(vim.o.suffixesadd, ",", { plain = true, trimempty = true }) do + local suffixname = basename .. suffix + if name_map[suffixname] then + url.path = fullpath .. suffix + vim.cmd.edit({ args = { url_to_str(url) } }) + return + end + end + vim.notify(string.format("Can't find file '%s'", fname), vim.log.levels.ERROR) + end) +end + return M diff --git a/lua/oil/util.lua b/lua/oil/util.lua index 55a151bf..4020d70d 100644 --- a/lua/oil/util.lua +++ b/lua/oil/util.lua @@ -667,4 +667,33 @@ M.buf_get_win = function(bufnr, preferred_win) return nil end +---@param adapter oil.Adapter +---@param url string +---@param opts {columns?: string[], no_cache?: boolean} +---@param callback fun(err: nil|string, entries: nil|oil.InternalEntry[]) +M.adapter_list_all = function(adapter, url, opts, callback) + local cache = require("oil.cache") + if not opts.no_cache then + local entries = cache.list_url(url) + if not vim.tbl_isempty(entries) then + return callback(nil, vim.tbl_values(entries)) + end + end + local ret = {} + adapter.list(url, opts.columns or {}, function(err, entries, fetch_more) + if err then + callback(err) + return + end + if entries then + vim.list_extend(ret, entries) + end + if fetch_more then + vim.defer_fn(fetch_more, 4) + else + callback(nil, ret) + end + end) +end + return M