refactor(fugitive): return status character from parse_file_line

Problem: parse_file_line discarded the git status character (M, A, D,
U, etc.), making it impossible to distinguish unmerged files from
modified ones in the fugitive status buffer.

Solution: capture and return the status character as a 3rd return value
from parse_file_line, propagate it through get_file_at_line as a 5th
return value, and pass unmerged=true to gdiff_file when status is 'U'.
This commit is contained in:
Barrett Ruth 2026-02-08 17:45:51 -05:00
parent 49fc446aae
commit a20555667e

View file

@ -27,19 +27,19 @@ function M.get_section_at_line(bufnr, lnum)
end end
---@param line string ---@param line string
---@return string?, string? ---@return string?, string?, string?
local function parse_file_line(line) local function parse_file_line(line)
local old, new = line:match('^R%d*%s+(.-)%s+->%s+(.+)$') local old, new = line:match('^R%d*%s+(.-)%s+->%s+(.+)$')
if old and new then if old and new then
return vim.trim(new), vim.trim(old) return vim.trim(new), vim.trim(old), 'R'
end end
local filename = line:match('^[MADRCU?][MADRCU%s]*%s+(.+)$') local status, filename = line:match('^([MADRCU?])[MADRCU%s]*%s+(.+)$')
if filename then if status and filename then
return vim.trim(filename), nil return vim.trim(filename), nil, status
end end
return nil, nil return nil, nil, nil
end end
---@param line string ---@param line string
@ -57,34 +57,34 @@ end
---@param bufnr integer ---@param bufnr integer
---@param lnum integer ---@param lnum integer
---@return string?, diffs.FugitiveSection, boolean, string? ---@return string?, diffs.FugitiveSection, boolean, string?, string?
function M.get_file_at_line(bufnr, lnum) function M.get_file_at_line(bufnr, lnum)
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
local current_line = lines[lnum] local current_line = lines[lnum]
if not current_line then if not current_line then
return nil, nil, false, nil return nil, nil, false, nil, nil
end end
local section_header = parse_section_header(current_line) local section_header = parse_section_header(current_line)
if section_header then if section_header then
return nil, section_header, true, nil return nil, section_header, true, nil, nil
end end
local filename, old_filename = parse_file_line(current_line) local filename, old_filename, status = parse_file_line(current_line)
if filename then if filename then
local section = M.get_section_at_line(bufnr, lnum) local section = M.get_section_at_line(bufnr, lnum)
return filename, section, false, old_filename return filename, section, false, old_filename, status
end end
local prefix = current_line:sub(1, 1) local prefix = current_line:sub(1, 1)
if prefix == '+' or prefix == '-' or prefix == ' ' then if prefix == '+' or prefix == '-' or prefix == ' ' then
for i = lnum - 1, 1, -1 do for i = lnum - 1, 1, -1 do
local prev_line = lines[i] local prev_line = lines[i]
filename, old_filename = parse_file_line(prev_line) filename, old_filename, status = parse_file_line(prev_line)
if filename then if filename then
local section = M.get_section_at_line(bufnr, i) local section = M.get_section_at_line(bufnr, i)
return filename, section, false, old_filename return filename, section, false, old_filename, status
end end
if prev_line:match('^%w+ %(') or prev_line == '' then if prev_line:match('^%w+ %(') or prev_line == '' then
break break
@ -92,7 +92,7 @@ function M.get_file_at_line(bufnr, lnum)
end end
end end
return nil, nil, false, nil return nil, nil, false, nil, nil
end end
---@class diffs.HunkPosition ---@class diffs.HunkPosition
@ -150,7 +150,7 @@ function M.diff_file_under_cursor(vertical)
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local lnum = vim.api.nvim_win_get_cursor(0)[1] local lnum = vim.api.nvim_win_get_cursor(0)[1]
local filename, section, is_header, old_filename = M.get_file_at_line(bufnr, lnum) local filename, section, is_header, old_filename, status = M.get_file_at_line(bufnr, lnum)
local repo_root = get_repo_root_from_fugitive(bufnr) local repo_root = get_repo_root_from_fugitive(bufnr)
if not repo_root then if not repo_root then
@ -192,6 +192,7 @@ function M.diff_file_under_cursor(vertical)
vertical = vertical, vertical = vertical,
staged = section == 'staged', staged = section == 'staged',
untracked = section == 'untracked', untracked = section == 'untracked',
unmerged = status == 'U',
old_filepath = old_filepath, old_filepath = old_filepath,
hunk_position = hunk_position, hunk_position = hunk_position,
}) })