mirror of
https://github.com/folke/snacks.nvim
synced 2025-12-23 08:47:57 +00:00
fix(picker.diff): better filename parsing. See #2366
This commit is contained in:
parent
c91e23060c
commit
377f3bfeca
3 changed files with 20 additions and 55 deletions
|
|
@ -106,14 +106,8 @@ function M.parse(lines)
|
|||
emit()
|
||||
local file ---@type string?
|
||||
if text:find("^diff") then
|
||||
local parsed = Snacks.picker.util.parse_cmdline(text)
|
||||
for i = 2, #parsed do
|
||||
local arg = parsed[i]
|
||||
if not arg:find("^%-") then
|
||||
file = arg:match("^%a/(.*)") or arg
|
||||
break
|
||||
end
|
||||
end
|
||||
text = text:gsub("^diff%s*", ""):gsub("^%-%S+%s*", "")
|
||||
file = text:match('^"%a/(.-)"') or text:match("^%a/(.-) %a/") or text:match("^%a/(.*)$") or text
|
||||
elseif text:find("^%-%-%-") then
|
||||
file = text:match("^%-%-%- %a/([^\t]+)") or text:match("^%-%-%- ([^\t]+)")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -646,53 +646,9 @@ function M.globber(globs)
|
|||
end
|
||||
end
|
||||
|
||||
---@param cmdline string
|
||||
---@return string[]
|
||||
function M.parse_cmdline(cmdline)
|
||||
local args = {} ---@type string[]
|
||||
local current = ""
|
||||
local in_quote = false
|
||||
local quote_char = nil
|
||||
local i = 1
|
||||
|
||||
while i <= #cmdline do
|
||||
local char = cmdline:sub(i, i)
|
||||
local next_char = cmdline:sub(i + 1, i + 1)
|
||||
|
||||
if char == "\\" and next_char ~= "" then
|
||||
-- Escaped character - take next char literally
|
||||
current = current .. next_char
|
||||
i = i + 2
|
||||
elseif not in_quote and (char == '"' or char == "'") then
|
||||
-- Start quote
|
||||
in_quote = true
|
||||
quote_char = char
|
||||
i = i + 1
|
||||
elseif in_quote and char == quote_char then
|
||||
-- End quote
|
||||
in_quote = false
|
||||
quote_char = nil
|
||||
i = i + 1
|
||||
elseif not in_quote and char:match("%s") then
|
||||
-- Whitespace outside quotes - split arg
|
||||
if current ~= "" then
|
||||
args[#args + 1] = current
|
||||
current = ""
|
||||
end
|
||||
i = i + 1
|
||||
else
|
||||
-- Regular character or whitespace inside quotes
|
||||
current = current .. char
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Add last arg if any
|
||||
if current ~= "" then
|
||||
args[#args + 1] = current
|
||||
end
|
||||
|
||||
return args
|
||||
---@param buf number
|
||||
function M.spinner(buf)
|
||||
return require("snacks.picker.util.spinner").new(buf)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -235,6 +235,21 @@ describe("picker.diff", function()
|
|||
assert.equals("my file.txt", blocks[1].file)
|
||||
end)
|
||||
|
||||
it("handles files with spaces in name without quotes", function()
|
||||
local lines = {
|
||||
"diff --git a/my file.txt b/my file.txt",
|
||||
"--- a/my file.txt",
|
||||
"+++ b/my file.txt",
|
||||
"@@ -1,1 +1,1 @@",
|
||||
"-old",
|
||||
"+new",
|
||||
}
|
||||
|
||||
local blocks = diff.parse(lines)
|
||||
assert.equals(1, #blocks)
|
||||
assert.equals("my file.txt", blocks[1].file)
|
||||
end)
|
||||
|
||||
it("handles files in subdirectories", function()
|
||||
local lines = {
|
||||
"diff --git a/path/to/file.txt b/path/to/file.txt",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue