diff --git a/lua/oil/init.lua b/lua/oil/init.lua index 3254d66..f5ff70a 100644 --- a/lua/oil/init.lua +++ b/lua/oil/init.lua @@ -11,6 +11,7 @@ local M = {} ---@alias oil.TextChunk string|string[] ---@class oil.Adapter +---@field name string ---@field list fun(path: string, cb: fun(err: nil|string, entries: nil|oil.InternalEntry[])) ---@field is_modifiable fun(bufnr: integer): boolean ---@field url_to_buffer_name fun(url: string): string @@ -191,7 +192,7 @@ M.get_buffer_parent_url = function(bufname) scheme = config.remap_schemes[scheme] or scheme local adapter = config.get_adapter_by_scheme(scheme) local parent_url - if adapter.get_parent then + if adapter and adapter.get_parent then local adapter_scheme = config.adapter_to_scheme[adapter.name] parent_url = adapter.get_parent(adapter_scheme .. path) else @@ -213,6 +214,9 @@ M.open_float = function(dir) local util = require("oil.util") local view = require("oil.view") local parent_url, basename = M.get_url_for_path(dir) + if not parent_url then + return + end if basename then view.set_last_cursor(parent_url, basename) end @@ -617,6 +621,7 @@ M.setup = function(opts) if vim.bo.filetype == "oil" then view.set_win_options() vim.api.nvim_win_set_var(0, "oil_did_enter", true) + view.maybe_set_cursor() elseif vim.w.oil_did_enter then vim.api.nvim_win_del_var(0, "oil_did_enter") -- We are entering a non-oil buffer *after* having been in an oil buffer diff --git a/lua/oil/view.lua b/lua/oil/view.lua index 1cbb413..4363d9f 100644 --- a/lua/oil/view.lua +++ b/lua/oil/view.lua @@ -21,11 +21,33 @@ M.should_display = function(entry) end ---@param bufname string ----@param name string +---@param name nil|string M.set_last_cursor = function(bufname, name) last_cursor_entry[bufname] = name end +---Set the cursor to the last_cursor_entry if one exists +M.maybe_set_cursor = function() + local oil = require("oil") + local bufname = vim.api.nvim_buf_get_name(0) + local entry_name = last_cursor_entry[bufname] + if not entry_name then + return + end + local line_count = vim.api.nvim_buf_line_count(0) + for lnum = 1, line_count do + local entry = oil.get_entry_on_line(0, lnum) + if entry and entry.name == entry_name then + local line = vim.api.nvim_buf_get_lines(0, lnum - 1, lnum, true)[1] + local id_str = line:match("^/(%d+)") + local col = line:find(entry_name, 1, true) or (id_str:len() + 1) + vim.api.nvim_win_set_cursor(0, { lnum, col - 1 }) + M.set_last_cursor(bufname, nil) + break + end + end +end + ---@param bufname string ---@return nil|string M.get_last_cursor = function(bufname) @@ -245,6 +267,7 @@ local function render_buffer(bufnr, opts) if seek_after_render == name then seek_after_render_found = true jump_idx = #line_table + M.set_last_cursor(bufname, nil) end ::continue:: end @@ -387,6 +410,9 @@ M.render_buffer_async = function(bufnr, opts, callback) loading.set_loading(bufnr, true) local finish = vim.schedule_wrap(function() + if not vim.api.nvim_buf_is_valid(bufnr) then + return + end loading.set_loading(bufnr, false) render_buffer(bufnr, { jump = true }) if not preserve_undo then diff --git a/tests/regression_spec.lua b/tests/regression_spec.lua index 46eade8..9f63e97 100644 --- a/tests/regression_spec.lua +++ b/tests/regression_spec.lua @@ -1,4 +1,5 @@ require("plenary.async").tests.add_to_env() +local oil = require("oil") local test_util = require("tests.test_util") a.describe("regression tests", function() @@ -17,4 +18,17 @@ a.describe("regression tests", function() a.util.sleep(10) assert.equals("oil", vim.bo.filetype) end) + + -- https://github.com/stevearc/oil.nvim/issues/37 + a.it("places the cursor on correct entry when opening on file", function() + vim.cmd.edit({ args = { "." } }) + a.util.sleep(10) + local entry = oil.get_cursor_entry() + assert.not_equals("README.md", entry and entry.name) + vim.cmd.edit({ args = { "README.md" } }) + oil.open() + a.util.sleep(10) + entry = oil.get_cursor_entry() + assert.equals("README.md", entry and entry.name) + end) end)