fix: detect duplicate filenames in buffer
This commit is contained in:
parent
9a03af7cb7
commit
bcb99ae95a
3 changed files with 55 additions and 3 deletions
|
|
@ -3,6 +3,8 @@ local M = {}
|
||||||
---@type boolean
|
---@type boolean
|
||||||
M.is_windows = vim.loop.os_uname().version:match("Windows")
|
M.is_windows = vim.loop.os_uname().version:match("Windows")
|
||||||
|
|
||||||
|
M.is_mac = vim.loop.os_uname().sysname == "Darwin"
|
||||||
|
|
||||||
---@type string
|
---@type string
|
||||||
M.sep = M.is_windows and "\\" or "/"
|
M.sep = M.is_windows and "\\" or "/"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
local cache = require("oil.cache")
|
local cache = require("oil.cache")
|
||||||
local columns = require("oil.columns")
|
local columns = require("oil.columns")
|
||||||
|
local fs = require("oil.fs")
|
||||||
local util = require("oil.util")
|
local util = require("oil.util")
|
||||||
local view = require("oil.view")
|
local view = require("oil.view")
|
||||||
local FIELD = require("oil.constants").FIELD
|
local FIELD = require("oil.constants").FIELD
|
||||||
|
|
@ -104,7 +105,7 @@ M.parse = function(bufnr)
|
||||||
local adapter = util.get_adapter(bufnr)
|
local adapter = util.get_adapter(bufnr)
|
||||||
if not adapter then
|
if not adapter then
|
||||||
table.insert(errors, {
|
table.insert(errors, {
|
||||||
lnum = 1,
|
lnum = 0,
|
||||||
col = 0,
|
col = 0,
|
||||||
message = string.format("Cannot parse buffer '%s': No adapter", bufname),
|
message = string.format("Cannot parse buffer '%s': No adapter", bufname),
|
||||||
})
|
})
|
||||||
|
|
@ -121,6 +122,18 @@ M.parse = function(bufnr)
|
||||||
original_entries[child[FIELD.name]] = child[FIELD.id]
|
original_entries[child[FIELD.name]] = child[FIELD.id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local seen_names = {}
|
||||||
|
local function check_dupe(name, i)
|
||||||
|
if fs.is_mac or fs.is_windows then
|
||||||
|
-- mac and windows use case-insensitive filesystems
|
||||||
|
name = name:lower()
|
||||||
|
end
|
||||||
|
if seen_names[name] then
|
||||||
|
table.insert(errors, { message = "Duplicate filename", lnum = i - 1, col = 0 })
|
||||||
|
else
|
||||||
|
seen_names[name] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
for i, line in ipairs(lines) do
|
for i, line in ipairs(lines) do
|
||||||
if line:match("^/%d+") then
|
if line:match("^/%d+") then
|
||||||
local parsed_entry, entry, err = M.parse_line(adapter, line, column_defs)
|
local parsed_entry, entry, err = M.parse_line(adapter, line, column_defs)
|
||||||
|
|
@ -143,11 +156,12 @@ M.parse = function(bufnr)
|
||||||
end
|
end
|
||||||
table.insert(errors, {
|
table.insert(errors, {
|
||||||
message = message,
|
message = message,
|
||||||
lnum = i,
|
lnum = i - 1,
|
||||||
col = 0,
|
col = 0,
|
||||||
})
|
})
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
|
check_dupe(parsed_entry.name, i)
|
||||||
local meta = entry[FIELD.meta]
|
local meta = entry[FIELD.meta]
|
||||||
if original_entries[parsed_entry.name] == parsed_entry.id then
|
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 meta or meta.link ~= parsed_entry.link_target) then
|
||||||
|
|
@ -187,7 +201,7 @@ M.parse = function(bufnr)
|
||||||
if vim.startswith(name, "/") then
|
if vim.startswith(name, "/") then
|
||||||
table.insert(errors, {
|
table.insert(errors, {
|
||||||
message = "Paths cannot start with '/'",
|
message = "Paths cannot start with '/'",
|
||||||
lnum = i,
|
lnum = i - 1,
|
||||||
col = 0,
|
col = 0,
|
||||||
})
|
})
|
||||||
goto continue
|
goto continue
|
||||||
|
|
@ -200,6 +214,7 @@ M.parse = function(bufnr)
|
||||||
entry_type = "link"
|
entry_type = "link"
|
||||||
name, link = unpack(link_pieces)
|
name, link = unpack(link_pieces)
|
||||||
end
|
end
|
||||||
|
check_dupe(name, i)
|
||||||
table.insert(diffs, {
|
table.insert(diffs, {
|
||||||
type = "new",
|
type = "new",
|
||||||
name = name,
|
name = name,
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,41 @@ a.describe("mutator", function()
|
||||||
}, errors)
|
}, errors)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("errors on duplicate names", function()
|
||||||
|
vim.cmd.edit({ args = { "oil-test:///foo/" } })
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
set_lines(bufnr, {
|
||||||
|
"foo",
|
||||||
|
"foo/",
|
||||||
|
})
|
||||||
|
local _, errors = parser.parse(bufnr)
|
||||||
|
assert.are.same({
|
||||||
|
{
|
||||||
|
message = "Duplicate filename",
|
||||||
|
lnum = 2,
|
||||||
|
col = 0,
|
||||||
|
},
|
||||||
|
}, errors)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("errors on duplicate names for existing files", function()
|
||||||
|
local file = cache.create_and_store_entry("oil-test:///foo/", "a.txt", "file")
|
||||||
|
vim.cmd.edit({ args = { "oil-test:///foo/" } })
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
set_lines(bufnr, {
|
||||||
|
"a.txt",
|
||||||
|
string.format("/%d a.txt", file[FIELD.id]),
|
||||||
|
})
|
||||||
|
local _, errors = parser.parse(bufnr)
|
||||||
|
assert.are.same({
|
||||||
|
{
|
||||||
|
message = "Duplicate filename",
|
||||||
|
lnum = 2,
|
||||||
|
col = 0,
|
||||||
|
},
|
||||||
|
}, errors)
|
||||||
|
end)
|
||||||
|
|
||||||
it("ignores new dirs with empty name", function()
|
it("ignores new dirs with empty name", function()
|
||||||
vim.cmd.edit({ args = { "oil-test:///foo/" } })
|
vim.cmd.edit({ args = { "oil-test:///foo/" } })
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue