diff --git a/README.md b/README.md index 71f12b0..63b06b4 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,8 @@ require("oil").setup({ conceallevel = 3, concealcursor = "n", }, + -- Oil will take over directory buffers (e.g. `vim .` or `:e src/` + default_file_explorer = true, -- Restore window options to previous values when leaving an oil buffer restore_win_options = true, -- Skip the confirmation popup for simple operations @@ -234,6 +236,21 @@ Change the display columns for oil | ----- | ------------------ | ---- | | cols | `oil.ColumnSpec[]` | | +### set_is_hidden_file(is_hidden_file) + +`set_is_hidden_file(is_hidden_file)` \ +Change how oil determines if the file is hidden + +| Param | Type | Desc | +| -------------- | ----------------------------------------------------- | -------------------------------------------- | +| is_hidden_file | `fun(filename: string, bufnr: nil\|integer): boolean` | Return true if the file/dir should be hidden | + +### toggle_hidden() + +`toggle_hidden()` \ +Toggle hidden files and directories + + ### get_current_dir() `get_current_dir(): nil|string` \ diff --git a/doc/oil.txt b/doc/oil.txt index b995f3a..22c4fc0 100644 --- a/doc/oil.txt +++ b/doc/oil.txt @@ -37,6 +37,8 @@ OPTIONS *oil-option conceallevel = 3, concealcursor = "n", }, + -- Oil will take over directory buffers (e.g. `vim .` or `:e src/` + default_file_explorer = true, -- Restore window options to previous values when leaving an oil buffer restore_win_options = true, -- Skip the confirmation popup for simple operations @@ -110,6 +112,17 @@ set_columns({cols}) *oil.set_column Parameters: {cols} `oil.ColumnSpec[]` +set_is_hidden_file({is_hidden_file}) *oil.set_is_hidden_file* + Change how oil determines if the file is hidden + + Parameters: + {is_hidden_file} `fun(filename: string, bufnr: nil|integer): boolean` Retu + rn true if the file/dir should be hidden + +toggle_hidden() *oil.toggle_hidden* + Toggle hidden files and directories + + get_current_dir(): nil|string *oil.get_current_dir* Get the current directory diff --git a/doc/tags b/doc/tags index 15908ba..6ef51f2 100644 --- a/doc/tags +++ b/doc/tags @@ -53,5 +53,7 @@ oil.open_float oil.txt /*oil.open_float* oil.save oil.txt /*oil.save* oil.select oil.txt /*oil.select* oil.set_columns oil.txt /*oil.set_columns* +oil.set_is_hidden_file oil.txt /*oil.set_is_hidden_file* oil.setup oil.txt /*oil.setup* +oil.toggle_hidden oil.txt /*oil.toggle_hidden* oil.txt oil.txt /*oil.txt* diff --git a/lua/oil/adapters/files.lua b/lua/oil/adapters/files.lua index 1b307c9..5f0c24c 100644 --- a/lua/oil/adapters/files.lua +++ b/lua/oil/adapters/files.lua @@ -180,7 +180,17 @@ M.normalize_url = function(url, callback) vim.loop.fs_stat( realpath, vim.schedule_wrap(function(stat_err, stat) - if not stat or stat.type == "directory" then + local is_directory + if stat then + is_directory = stat.type == "directory" + elseif vim.endswith(realpath, "/") then + is_directory = true + else + local filetype = vim.filetype.match({ filename = vim.fs.basename(realpath) }) + is_directory = filetype == nil + end + + if is_directory then local norm_path = util.addslash(fs.os_to_posix_path(realpath)) callback(scheme .. norm_path) else diff --git a/lua/oil/columns.lua b/lua/oil/columns.lua index 7ac894d..ca0e978 100644 --- a/lua/oil/columns.lua +++ b/lua/oil/columns.lua @@ -27,11 +27,16 @@ local function get_column(adapter, defn) return all_columns[name] or adapter.get_column(name) end ----@param scheme string +---@param adapter_or_scheme string|oil.Adapter ---@return oil.ColumnSpec[] -M.get_supported_columns = function(scheme) +M.get_supported_columns = function(adapter_or_scheme) + local adapter + if type(adapter_or_scheme) == "string" then + adapter = config.get_adapter_by_scheme(adapter_or_scheme) + else + adapter = adapter_or_scheme + end local ret = {} - local adapter = config.get_adapter_by_scheme(scheme) for _, def in ipairs(config.columns) do if get_column(adapter, def) then table.insert(ret, def) diff --git a/lua/oil/config.lua b/lua/oil/config.lua index 53115f7..fdf4ccd 100644 --- a/lua/oil/config.lua +++ b/lua/oil/config.lua @@ -22,6 +22,8 @@ local default_config = { conceallevel = 3, concealcursor = "n", }, + -- Oil will take over directory buffers (e.g. `vim .` or `:e src/` + default_file_explorer = true, -- Restore window options to previous values when leaving an oil buffer restore_win_options = true, -- Skip the confirmation popup for simple operations @@ -142,9 +144,12 @@ M.get_trash_url = function() return M.adapter_to_scheme.files .. fs.os_to_posix_path(M.trash) end ----@param scheme string +---@param scheme nil|string ---@return nil|oil.Adapter M.get_adapter_by_scheme = function(scheme) + if not scheme then + return nil + end if not vim.endswith(scheme, "://") then local pieces = vim.split(scheme, "://", { plain = true }) if #pieces <= 2 then diff --git a/lua/oil/init.lua b/lua/oil/init.lua index 736ae52..c937d3d 100644 --- a/lua/oil/init.lua +++ b/lua/oil/init.lua @@ -5,7 +5,7 @@ local M = {} ---@class oil.Entry ---@field name string ---@field type oil.EntryType ----@field id nil|string Will be nil if it hasn't been persisted to disk yet +---@field id nil|integer Will be nil if it hasn't been persisted to disk yet ---@alias oil.EntryType "file"|"directory"|"socket"|"link" ---@alias oil.TextChunk string|string[] @@ -29,15 +29,12 @@ local M = {} ---@return nil|oil.Entry M.get_entry_on_line = function(bufnr, lnum) local columns = require("oil.columns") - local config = require("oil.config") local parser = require("oil.mutator.parser") local util = require("oil.util") if vim.bo[bufnr].filetype ~= "oil" then return nil end - local bufname = vim.api.nvim_buf_get_name(0) - local scheme = util.parse_url(bufname) - local adapter = config.get_adapter_by_scheme(scheme) + local adapter = util.get_adapter(bufnr) if not adapter then return nil end @@ -46,15 +43,15 @@ M.get_entry_on_line = function(bufnr, lnum) if not line then return nil end - local column_defs = columns.get_supported_columns(scheme) - local parsed_entry, entry = parser.parse_line(adapter, line, column_defs) - if parsed_entry then - if entry then - return util.export_entry(entry) + local column_defs = columns.get_supported_columns(adapter) + local result = parser.parse_line(adapter, line, column_defs) + if result then + if result.entry then + return util.export_entry(result.entry) else return { - name = parsed_entry.name, - type = parsed_entry._type, + name = result.data.name, + type = result.data._type, } end end @@ -138,6 +135,17 @@ M.set_columns = function(cols) require("oil.view").set_columns(cols) end +---Change how oil determines if the file is hidden +---@param is_hidden_file fun(filename: string, bufnr: nil|integer): boolean Return true if the file/dir should be hidden +M.set_is_hidden_file = function(is_hidden_file) + require("oil.view").set_is_hidden_file(is_hidden_file) +end + +---Toggle hidden files and directories +M.toggle_hidden = function() + require("oil.view").toggle_hidden() +end + ---Get the current directory ---@return nil|string M.get_current_dir = function() @@ -298,13 +306,19 @@ M.close = function() return end local ok, bufnr = pcall(vim.api.nvim_win_get_var, 0, "oil_original_buffer") - if ok then - if vim.api.nvim_buf_is_valid(bufnr) then - vim.api.nvim_win_set_buf(0, bufnr) - return + if ok and vim.api.nvim_buf_is_valid(bufnr) then + vim.api.nvim_win_set_buf(0, bufnr) + if vim.w.oil_original_view then + vim.fn.winrestview(vim.w.oil_original_view) end + return end - vim.api.nvim_buf_delete(0, { force = true }) + + -- Deleting the buffer closes all windows with that buffer open, so navigate to a different + -- buffer first + local oilbuf = vim.api.nvim_get_current_buf() + vim.cmd.bprev() + vim.api.nvim_buf_delete(oilbuf, { force = true }) end ---Select the entry under the cursor @@ -368,11 +382,10 @@ M.select = function(opts) vim.notify("Cannot preview multiple entries", vim.log.levels.WARN) entries = { entries[1] } end - -- Close the preview window - for _, winid in ipairs(vim.api.nvim_tabpage_list_wins(0)) do - if vim.api.nvim_win_is_valid(winid) and vim.api.nvim_win_get_option(winid, "previewwindow") then - vim.api.nvim_win_close(winid, true) - end + -- Close the preview window if we're not previewing the selection + local preview_win = util.get_preview_win() + if not opts.preview and preview_win then + vim.api.nvim_win_close(preview_win, true) end local bufname = vim.api.nvim_buf_get_name(0) local prev_win = vim.api.nvim_get_current_win() @@ -380,15 +393,15 @@ M.select = function(opts) local scheme, dir = util.parse_url(bufname) local child = dir .. entry.name local url = scheme .. child - if - entry.type == "directory" + local is_directory = entry.type == "directory" or ( entry.type == "link" and entry.meta and entry.meta.link_stat and entry.meta.link_stat.type == "directory" ) - then + if is_directory then + url = url .. "/" -- If this is a new directory BUT we think we already have an entry with this name, disallow -- entry. This prevents the case of MOVE /foo -> /bar + CREATE /foo. -- If you enter the new /foo, it will show the contents of the old /foo. @@ -401,27 +414,34 @@ M.select = function(opts) vim.api.nvim_win_close(0, false) end end + local mods = { vertical = opts.vertical, horizontal = opts.horizontal, split = opts.split, + keepalt = true, } - if vim.tbl_isempty(mods) then - mods = nil - end - local cmd - if opts.tab then - cmd = "tabedit" - elseif opts.split then - cmd = "split" + if opts.preview and preview_win then + vim.api.nvim_set_current_win(preview_win) + vim.cmd.edit({ args = { url }, mods = mods }) else - cmd = "edit" + if vim.tbl_isempty(mods) then + mods = nil + end + local cmd + if opts.tab then + cmd = "tabedit" + elseif opts.split then + cmd = "split" + else + cmd = "edit" + end + vim.cmd({ + cmd = cmd, + args = { url }, + mods = mods, + }) end - vim.cmd({ - cmd = cmd, - args = { url }, - mods = mods, - }) if opts.preview then vim.api.nvim_win_set_option(0, "previewwindow", true) vim.api.nvim_win_set_var(0, "oil_entry_id", entry.id) @@ -439,6 +459,9 @@ end local function maybe_hijack_directory_buffer(bufnr) local config = require("oil.config") local util = require("oil.util") + if not config.default_file_explorer then + return + end local bufname = vim.api.nvim_buf_get_name(bufnr) if bufname == "" then return @@ -599,6 +622,17 @@ local function load_oil_buffer(bufnr) -- have BufReadCmd called for it return end + + -- If the renamed buffer doesn't have a scheme anymore, this is a normal file. + -- Finish setting it up as a normal buffer. + local new_scheme = util.parse_url(new_url) + if not new_scheme then + loading.set_loading(bufnr, false) + vim.cmd.doautocmd({ args = { "BufReadPre", new_url }, mods = { emsg_silent = true } }) + vim.cmd.doautocmd({ args = { "BufReadPost", new_url }, mods = { emsg_silent = true } }) + return + end + bufname = new_url end if vim.endswith(bufname, "/") then @@ -687,19 +721,20 @@ M.setup = function(opts) end end, }) - vim.api.nvim_create_autocmd("BufWinLeave", { + vim.api.nvim_create_autocmd("BufLeave", { desc = "Save alternate buffer for later", group = aug, pattern = "*", callback = function() local util = require("oil.util") if not util.is_oil_bufnr(0) then - vim.api.nvim_win_set_var(0, "oil_original_buffer", vim.api.nvim_get_current_buf()) - vim.api.nvim_win_set_var(0, "oil_original_alternate", vim.fn.bufnr("#")) + vim.w.oil_original_buffer = vim.api.nvim_get_current_buf() + vim.w.oil_original_view = vim.fn.winsaveview() + vim.w.oil_original_alternate = vim.fn.bufnr("#") end end, }) - vim.api.nvim_create_autocmd("BufWinEnter", { + vim.api.nvim_create_autocmd("BufEnter", { desc = "Set/unset oil window options and restore alternate buffer", group = aug, pattern = "*", @@ -715,6 +750,10 @@ M.setup = function(opts) if has_orig and vim.api.nvim_buf_is_valid(orig_buffer) then vim.fn.setreg("#", orig_buffer) end + if not vim.w.oil_did_enter then + require("oil.view").set_win_options() + vim.w.oil_did_enter = true + end elseif vim.fn.isdirectory(bufname) == 0 then -- Only run this logic if we are *not* in an oil buffer (and it's not a directory, which -- will be replaced by an oil:// url) @@ -783,16 +822,9 @@ M.setup = function(opts) end -- Then transfer over the relevant window vars vim.w.oil_did_enter = true - local has_orig, orig_buffer = - pcall(vim.api.nvim_win_get_var, parent_win, "oil_original_buffer") - if has_orig and vim.api.nvim_buf_is_valid(orig_buffer) then - vim.w.oil_original_buffer = orig_buffer - end - local has_orig_alt, alt_buffer = - pcall(vim.api.nvim_win_get_var, parent_win, "oil_original_alternate") - if has_orig_alt and vim.api.nvim_buf_is_valid(alt_buffer) then - vim.w.oil_original_alternate = alt_buffer - end + vim.w.oil_original_buffer = vim.w[parent_win].oil_original_buffer + vim.w.oil_original_view = vim.w[parent_win].oil_original_view + vim.w.oil_original_alternate = vim.w[parent_win].oil_original_alternate for k in pairs(config.win_options) do local varname = "_oil_" .. k local has_opt, opt = pcall(vim.api.nvim_win_get_var, parent_win, varname) diff --git a/lua/oil/mutator/parser.lua b/lua/oil/mutator/parser.lua index f185749..c314ec5 100644 --- a/lua/oil/mutator/parser.lua +++ b/lua/oil/mutator/parser.lua @@ -38,27 +38,40 @@ local function parsedir(name) return name, isdir end +---@class oil.ParseResult +---@field data table Parsed entry data +---@field ranges table Locations of the various columns +---@field entry nil|oil.InternalEntry If the entry already exists + ---Parse a single line in a buffer ---@param adapter oil.Adapter ---@param line string ---@param column_defs oil.ColumnSpec[] ----@return nil|table Parsed entry data ----@return nil|oil.InternalEntry If the entry already exists ----@return nil|string Error message +---@return nil|oil.ParseResult +---@return nil|string Error M.parse_line = function(adapter, line, column_defs) local ret = {} + local ranges = {} + local start = 1 local value, rem = line:match("^/(%d+) (.+)$") if not value then - return nil, nil, "Malformed ID at start of line" + return nil, "Malformed ID at start of line" end + ranges.id = { start, value:len() + 1 } + start = ranges.id[2] + 1 ret.id = tonumber(value) for _, def in ipairs(column_defs) do local name = util.split_config(def) + local range = { start } + local start_len = string.len(rem) value, rem = columns.parse_col(adapter, rem, def) - if not value then - return nil, nil, string.format("Parsing %s failed", name) + if not value or not rem then + return nil, string.format("Parsing %s failed", name) end ret[name] = value + range[2] = range[1] + start_len - string.len(rem) - 1 + ranges[name] = range + start = range[2] + 1 end local name = rem if name then @@ -70,8 +83,9 @@ M.parse_line = function(adapter, line, column_defs) ret._type = isdir and "directory" or "file" end local entry = cache.get_entry_by_id(ret.id) + ranges.name = { start, start + string.len(rem) - 1 } if not entry then - return ret + return { data = ret, ranges = ranges } end -- Parse the symlink syntax @@ -81,8 +95,9 @@ M.parse_line = function(adapter, line, column_defs) local name_pieces = vim.split(ret.name, " -> ", { plain = true }) if #name_pieces ~= 2 then ret.name = "" - return ret + return { data = ret, ranges = ranges } end + ranges.name = { start, start + string.len(name_pieces[1]) - 1 } ret.name = parsedir(vim.trim(name_pieces[1])) ret.link_target = name_pieces[2] ret._type = "link" @@ -93,7 +108,7 @@ M.parse_line = function(adapter, line, column_defs) ret._type = entry[FIELD.type] end - return ret, entry + return { data = ret, entry = entry, ranges = ranges } end ---@param bufnr integer @@ -113,8 +128,8 @@ M.parse = function(bufnr) return diffs, errors end local scheme, path = util.parse_url(bufname) - local column_defs = columns.get_supported_columns(scheme) local parent_url = scheme .. path + local column_defs = columns.get_supported_columns(adapter) local children = cache.list_url(parent_url) local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, true) local original_entries = {} @@ -137,8 +152,8 @@ M.parse = function(bufnr) end for i, line in ipairs(lines) do if line:match("^/%d+") then - local parsed_entry, entry, err = M.parse_line(adapter, line, column_defs) - if not parsed_entry then + local result, err = M.parse_line(adapter, line, column_defs) + if not result or err then table.insert(errors, { message = err, lnum = i - 1, @@ -146,6 +161,8 @@ M.parse = function(bufnr) }) goto continue end + local parsed_entry = result.data + local entry = result.entry if not parsed_entry.name or parsed_entry.name:match("/") or not entry then local message if not parsed_entry.name then diff --git a/lua/oil/mutator/preview.lua b/lua/oil/mutator/preview.lua index be302cf..48893b2 100644 --- a/lua/oil/mutator/preview.lua +++ b/lua/oil/mutator/preview.lua @@ -64,6 +64,7 @@ M.show = vim.schedule_wrap(function(actions, should_confirm, cb) height = height, row = math.floor((vim.o.lines - vim.o.cmdheight - height) / 2), col = math.floor((vim.o.columns - width) / 2), + zindex = 152, -- render on top of the floating window title style = "minimal", border = "rounded", }) diff --git a/lua/oil/util.lua b/lua/oil/util.lua index 156aa5b..d5bef4f 100644 --- a/lua/oil/util.lua +++ b/lua/oil/util.lua @@ -102,11 +102,16 @@ M.rename_buffer = function(src_bufnr, dest_buf_name) -- rename logic. The only reason we can't use nvim_buf_set_name on files is because vim will -- think that the new buffer conflicts with the file next time it tries to save. if not vim.loop.fs_stat(dest_buf_name) then + local altbuf = vim.fn.bufnr("#") -- This will fail if the dest buf name already exists local ok = pcall(vim.api.nvim_buf_set_name, src_bufnr, dest_buf_name) if ok then -- Renaming the buffer creates a new buffer with the old name. Find it and delete it. vim.api.nvim_buf_delete(vim.fn.bufadd(bufname), {}) + if altbuf and vim.api.nvim_buf_is_valid(altbuf) then + vim.fn.setreg("#", altbuf) + end + return false end end diff --git a/lua/oil/view.lua b/lua/oil/view.lua index b3bd75e..8133669 100644 --- a/lua/oil/view.lua +++ b/lua/oil/view.lua @@ -54,8 +54,7 @@ M.get_last_cursor = function(bufname) end local function are_any_modified() - local view = require("oil.view") - local buffers = view.get_all_buffers() + local buffers = M.get_all_buffers() for _, bufnr in ipairs(buffers) do if vim.bo[bufnr].modified then return true @@ -65,25 +64,34 @@ local function are_any_modified() end M.toggle_hidden = function() - local view = require("oil.view") local any_modified = are_any_modified() if any_modified then vim.notify("Cannot toggle hidden files when you have unsaved changes", vim.log.levels.WARN) else config.view_options.show_hidden = not config.view_options.show_hidden - view.rerender_all_oil_buffers({ refetch = false }) + M.rerender_all_oil_buffers({ refetch = false }) + end +end + +---@param is_hidden_file fun(filename: string, bufnr: nil|integer): boolean +M.set_is_hidden_file = function(is_hidden_file) + local any_modified = are_any_modified() + if any_modified then + vim.notify("Cannot change is_hidden_file when you have unsaved changes", vim.log.levels.WARN) + else + config.view_options.is_hidden_file = is_hidden_file + M.rerender_all_oil_buffers({ refetch = false }) end end M.set_columns = function(cols) - local view = require("oil.view") local any_modified = are_any_modified() if any_modified then vim.notify("Cannot change columns when you have unsaved changes", vim.log.levels.WARN) else config.columns = cols -- TODO only refetch if we don't have all the necessary data for the columns - view.rerender_all_oil_buffers({ refetch = true }) + M.rerender_all_oil_buffers({ refetch = true }) end end @@ -245,11 +253,36 @@ M.initialize = function(bufnr) group = "Oil", buffer = bufnr, callback = function() + local oil = require("oil") + local parser = require("oil.mutator.parser") + if vim.wo.previewwindow then + return + end + + -- Force the cursor to be after the (concealed) ID at the beginning of the line + local adapter = util.get_adapter(bufnr) + if adapter then + local cur = vim.api.nvim_win_get_cursor(0) + local line = vim.api.nvim_buf_get_lines(bufnr, cur[1] - 1, cur[1], true)[1] + local column_defs = columns.get_supported_columns(adapter) + local result = parser.parse_line(adapter, line, column_defs) + if result and result.data then + local min_col = result.ranges.id[2] + 1 + if cur[2] < min_col then + vim.api.nvim_win_set_cursor(0, { cur[1], min_col }) + end + end + end + + -- Debounce and update the preview window if timer then timer:again() return end timer = vim.loop.new_timer() + if not timer then + return + end timer:start(10, 100, function() timer:stop() timer:close() @@ -258,7 +291,6 @@ M.initialize = function(bufnr) if vim.api.nvim_get_current_buf() ~= bufnr then return end - local oil = require("oil") local entry = oil.get_cursor_entry() if entry then local winid = util.get_preview_win() @@ -398,7 +430,6 @@ local function render_buffer(bufnr, opts) end ---@private ----@param adapter oil.Adapter ---@param entry oil.InternalEntry ---@param column_defs table[] ---@param col_width integer[] diff --git a/tests/altbuf_spec.lua b/tests/altbuf_spec.lua index 3c0113f..df481f1 100644 --- a/tests/altbuf_spec.lua +++ b/tests/altbuf_spec.lua @@ -81,6 +81,34 @@ a.describe("Alternate buffer", function() assert.equals("bar", vim.fn.expand("#")) end) + a.it("preserves alternate when traversing oil dirs", function() + vim.cmd.edit({ args = { "foo" } }) + oil.open() + test_util.wait_for_autocmd("BufReadPost") + assert.equals("foo", vim.fn.expand("#")) + vim.wait(1000, function() + return oil.get_cursor_entry() + end, 10) + vim.api.nvim_win_set_cursor(0, { 1, 1 }) + oil.select() + test_util.wait_for_autocmd("BufReadPost") + assert.equals("foo", vim.fn.expand("#")) + end) + + a.it("preserves alternate when opening preview", function() + vim.cmd.edit({ args = { "foo" } }) + oil.open() + test_util.wait_for_autocmd("BufReadPost") + assert.equals("foo", vim.fn.expand("#")) + vim.wait(1000, function() + return oil.get_cursor_entry() + end, 10) + vim.api.nvim_win_set_cursor(0, { 1, 1 }) + oil.select({ preview = true }) + test_util.wait_for_autocmd("BufReadPost") + assert.equals("foo", vim.fn.expand("#")) + end) + a.describe("floating window", function() a.it("sets previous buffer as alternate", function() vim.cmd.edit({ args = { "foo" } }) diff --git a/tests/files_spec.lua b/tests/files_spec.lua index e254608..6e15bea 100644 --- a/tests/files_spec.lua +++ b/tests/files_spec.lua @@ -2,6 +2,7 @@ require("plenary.async").tests.add_to_env() local fs = require("oil.fs") local files = require("oil.adapters.files") local cache = require("oil.cache") +local test_util = require("tests.test_util") local function throwiferr(err, ...) if err then @@ -308,4 +309,27 @@ a.describe("files adapter", function() ["a/"] = true, }) end) + + a.it("Editing a new oil://path/ creates an oil buffer", function() + local tmpdir_url = "oil://" .. vim.fn.fnamemodify(tmpdir.path, ":p") .. "/" + vim.cmd.edit({ args = { tmpdir_url } }) + test_util.wait_for_autocmd("BufReadPost") + local new_url = "oil://" .. vim.fn.fnamemodify(tmpdir.path, ":p") .. "newdir" + vim.cmd.edit({ args = { new_url } }) + test_util.wait_for_autocmd("BufReadPost") + assert.equals("oil", vim.bo.filetype) + -- The normalization will add a '/' + assert.equals(new_url .. "/", vim.api.nvim_buf_get_name(0)) + end) + + a.it("Editing a new oil://file.rb creates a normal buffer", function() + local tmpdir_url = "oil://" .. vim.fn.fnamemodify(tmpdir.path, ":p") .. "/" + vim.cmd.edit({ args = { tmpdir_url } }) + test_util.wait_for_autocmd("BufReadPost") + local new_url = "oil://" .. vim.fn.fnamemodify(tmpdir.path, ":p") .. "file.rb" + vim.cmd.edit({ args = { new_url } }) + test_util.wait_for_autocmd("BufReadPost") + assert.equals("ruby", vim.bo.filetype) + assert.equals(vim.fn.fnamemodify(tmpdir.path, ":p") .. "file.rb", vim.api.nvim_buf_get_name(0)) + end) end) diff --git a/tests/regression_spec.lua b/tests/regression_spec.lua index dd7651a..675853d 100644 --- a/tests/regression_spec.lua +++ b/tests/regression_spec.lua @@ -47,4 +47,19 @@ a.describe("regression tests", function() a.util.sleep(10) assert.equals(winid, vim.api.nvim_get_current_win()) end) + + -- https://github.com/stevearc/oil.nvim/issues/64 + a.it("doesn't close splits on oil.close", function() + vim.cmd.edit({ args = { "README.md" } }) + vim.cmd.vsplit() + local winid = vim.api.nvim_get_current_win() + local bufnr = vim.api.nvim_get_current_buf() + oil.open() + a.util.sleep(10) + oil.close() + a.util.sleep(10) + assert.equals(2, #vim.api.nvim_tabpage_list_wins(0)) + assert.equals(winid, vim.api.nvim_get_current_win()) + assert.equals(bufnr, vim.api.nvim_get_current_buf()) + end) end) diff --git a/tests/win_options_spec.lua b/tests/win_options_spec.lua index 05f84d0..49ab811 100644 --- a/tests/win_options_spec.lua +++ b/tests/win_options_spec.lua @@ -57,4 +57,16 @@ a.describe("window options", function() vim.cmd.edit({ args = { "README.md" } }) assert.equals("auto", vim.o.signcolumn) end) + + a.it("Sets the window options when re-entering oil buffer", function() + oil.open() + test_util.wait_for_autocmd("BufReadPost") + assert.truthy(vim.w.oil_did_enter) + vim.cmd.edit({ args = { "README.md" } }) + assert.falsy(vim.w.oil_did_enter) + oil.open() + assert.truthy(vim.w.oil_did_enter) + vim.cmd.vsplit() + assert.truthy(vim.w.oil_did_enter) + end) end)