From 9be36a648889c37d11bc65e8422049dc33dd6a3f Mon Sep 17 00:00:00 2001 From: Steven Arcangeli Date: Wed, 21 Jun 2023 17:15:57 -0700 Subject: [PATCH] fix: symbolic link target parsing fails if it has a trailing slash (#131) --- lua/oil/mutator/parser.lua | 15 ++++++++++++++- tests/mutator_spec.lua | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lua/oil/mutator/parser.lua b/lua/oil/mutator/parser.lua index c314ec5..ff16c48 100644 --- a/lua/oil/mutator/parser.lua +++ b/lua/oil/mutator/parser.lua @@ -38,6 +38,19 @@ local function parsedir(name) return name, isdir end +---@param meta nil|table +---@param parsed_entry table +---@return boolean True if metadata and parsed entry have the same link target +local function compare_link_target(meta, parsed_entry) + if not meta or not meta.link then + return false + end + -- Make sure we trim off any trailing path slashes from both sources + local meta_name = meta.link:gsub("[/\\]$", "") + local parsed_name = parsed_entry.link_target:gsub("[/\\]$", "") + return meta_name == parsed_name +end + ---@class oil.ParseResult ---@field data table Parsed entry data ---@field ranges table Locations of the various columns @@ -182,7 +195,7 @@ M.parse = function(bufnr) check_dupe(parsed_entry.name, i) local meta = entry[FIELD.meta] if original_entries[parsed_entry.name] == parsed_entry.id then - if entry[FIELD.type] == "link" and (not meta or meta.link ~= parsed_entry.link_target) then + if entry[FIELD.type] == "link" and not compare_link_target(meta, parsed_entry) then table.insert(diffs, { type = "new", name = parsed_entry.name, diff --git a/tests/mutator_spec.lua b/tests/mutator_spec.lua index 45c115e..167253a 100644 --- a/tests/mutator_spec.lua +++ b/tests/mutator_spec.lua @@ -41,6 +41,19 @@ a.describe("mutator", function() assert.are.same({ { entry_type = "directory", name = "foo", type = "new" } }, diffs) end) + it("detects new links", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "a.txt -> b.txt", + }) + local diffs = parser.parse(bufnr) + assert.are.same( + { { entry_type = "link", name = "a.txt", type = "new", link = "b.txt" } }, + diffs + ) + end) + it("detects deleted files", function() local file = cache.create_and_store_entry("oil-test:///foo/", "a.txt", "file") vim.cmd.edit({ args = { "oil-test:///foo/" } }) @@ -63,6 +76,18 @@ a.describe("mutator", function() }, diffs) end) + it("detects deleted links", function() + local file = cache.create_and_store_entry("oil-test:///foo/", "a.txt", "link") + file[FIELD.meta] = { link = "b.txt" } + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, {}) + local diffs = parser.parse(bufnr) + assert.are.same({ + { name = "a.txt", type = "delete", id = file[FIELD.id] }, + }, diffs) + end) + it("ignores empty lines", function() local file = cache.create_and_store_entry("oil-test:///foo/", "a.txt", "file") vim.cmd.edit({ args = { "oil-test:///foo/" } }) @@ -194,6 +219,18 @@ a.describe("mutator", function() { name = "b.txt", type = "delete", id = bfile[FIELD.id] }, }, last_two) end) + + it("views link targets with trailing slashes as the same", function() + local file = cache.create_and_store_entry("oil-test:///foo/", "mydir", "link") + file[FIELD.meta] = { link = "dir/" } + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + string.format("/%d mydir/ -> dir/", file[FIELD.id]), + }) + local diffs = parser.parse(bufnr) + assert.are.same({}, diffs) + end) end) describe("build actions", function()