Skip to content

Commit 09b231d

Browse files
authored
Merge pull request #32 from coder/fix-proposed-diff-filetype
Fix missing syntax highlighting in proposed diff view
2 parents 72a4a41 + ddad527 commit 09b231d

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed

Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
# Default target
44
all: format check test
55

6+
# Detect if we are already inside a Nix shell
7+
ifeq (,$(IN_NIX_SHELL))
8+
NIX_PREFIX := nix develop .#ci -c
9+
else
10+
NIX_PREFIX :=
11+
endif
12+
613
# Check for syntax errors
714
check:
815
@echo "Checking Lua files for syntax errors..."
9-
nix develop .#ci -c find lua -name "*.lua" -type f -exec lua -e "assert(loadfile('{}'))" \;
16+
$(NIX_PREFIX) find lua -name "*.lua" -type f -exec lua -e "assert(loadfile('{}'))" \;
1017
@echo "Running luacheck..."
11-
nix develop .#ci -c luacheck lua/ tests/ --no-unused-args --no-max-line-length
18+
$(NIX_PREFIX) luacheck lua/ tests/ --no-unused-args --no-max-line-length
1219

1320
# Format all files
1421
format:

lua/claudecode/diff.lua

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,57 @@ function M._cleanup_diff_layout(tab_name, target_win, new_win)
225225
logger.debug("diff", "[CLEANUP] Layout cleanup completed for:", tab_name)
226226
end
227227

228+
-- Detect filetype from a path or existing buffer (best-effort)
229+
local function _detect_filetype(path, buf)
230+
-- 1) Try Neovim's builtin matcher if available (>=0.10)
231+
if vim.filetype and type(vim.filetype.match) == "function" then
232+
local ok, ft = pcall(vim.filetype.match, { filename = path })
233+
if ok and ft and ft ~= "" then
234+
return ft
235+
end
236+
end
237+
238+
-- 2) Try reading from existing buffer
239+
if buf and vim.api.nvim_buf_is_valid(buf) then
240+
local ft = vim.api.nvim_buf_get_option(buf, "filetype")
241+
if ft and ft ~= "" then
242+
return ft
243+
end
244+
end
245+
246+
-- 3) Fallback to simple extension mapping
247+
local ext = path:match("%.([%w_%-]+)$") or ""
248+
local simple_map = {
249+
lua = "lua",
250+
ts = "typescript",
251+
js = "javascript",
252+
jsx = "javascriptreact",
253+
tsx = "typescriptreact",
254+
py = "python",
255+
go = "go",
256+
rs = "rust",
257+
c = "c",
258+
h = "c",
259+
cpp = "cpp",
260+
hpp = "cpp",
261+
md = "markdown",
262+
sh = "sh",
263+
zsh = "zsh",
264+
bash = "bash",
265+
json = "json",
266+
yaml = "yaml",
267+
yml = "yaml",
268+
toml = "toml",
269+
}
270+
return simple_map[ext]
271+
end
228272
--- Open diff using native Neovim functionality
229273
-- @param old_file_path string Path to the original file
230274
-- @param new_file_path string Path to the new file (used for naming)
231275
-- @param new_file_contents string Contents of the new file
232276
-- @param tab_name string Name for the diff tab/view
233277
-- @return table Result with provider, tab_name, and success status
278+
234279
function M._open_native_diff(old_file_path, new_file_path, new_file_contents, tab_name)
235280
local new_filename = vim.fn.fnamemodify(new_file_path, ":t") .. ".new"
236281
local tmp_file, err = M._create_temp_file(new_file_contents, new_filename)
@@ -259,9 +304,16 @@ function M._open_native_diff(old_file_path, new_file_path, new_file_contents, ta
259304
vim.cmd("edit " .. vim.fn.fnameescape(tmp_file))
260305
vim.api.nvim_buf_set_name(0, new_file_path .. " (New)")
261306

307+
-- Propagate filetype to the proposed buffer for proper syntax highlighting (#20)
308+
local proposed_buf = vim.api.nvim_get_current_buf()
309+
local old_filetype = _detect_filetype(old_file_path)
310+
if old_filetype and old_filetype ~= "" then
311+
vim.api.nvim_set_option_value("filetype", old_filetype, { buf = proposed_buf })
312+
end
313+
262314
vim.cmd("wincmd =")
263315

264-
local new_buf = vim.api.nvim_get_current_buf()
316+
local new_buf = proposed_buf
265317
vim.api.nvim_set_option_value("buftype", "nofile", { buf = new_buf })
266318
vim.api.nvim_set_option_value("bufhidden", "wipe", { buf = new_buf })
267319
vim.api.nvim_set_option_value("swapfile", false, { buf = new_buf })
@@ -665,6 +717,12 @@ function M._create_diff_view_from_window(target_window, old_file_path, new_buffe
665717
vim.cmd("vsplit")
666718
local new_win = vim.api.nvim_get_current_win()
667719
vim.api.nvim_win_set_buf(new_win, new_buffer)
720+
721+
-- Ensure new buffer inherits filetype from original for syntax highlighting (#20)
722+
local original_ft = _detect_filetype(old_file_path, original_buffer)
723+
if original_ft and original_ft ~= "" then
724+
vim.api.nvim_set_option_value("filetype", original_ft, { buf = new_buffer })
725+
end
668726
vim.cmd("diffthis")
669727
logger.debug("diff", "Created split window", new_win, "with new buffer", new_buffer)
670728

tests/unit/diff_spec.lua

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,40 @@ describe("Diff Module", function()
215215
end)
216216
end)
217217

218+
describe("Filetype Propagation", function()
219+
it("should propagate original filetype to proposed buffer", function()
220+
diff.setup({})
221+
222+
-- Spy on nvim_set_option_value
223+
spy.on(_G.vim.api, "nvim_set_option_value")
224+
225+
local mock_file = {
226+
write = function() end,
227+
close = function() end,
228+
}
229+
local old_io_open = io.open
230+
rawset(io, "open", function()
231+
return mock_file
232+
end)
233+
234+
local result = diff._open_native_diff("/tmp/test.ts", "/tmp/test.ts", "-- new", "Propagate FT")
235+
expect(result.success).to_be_true()
236+
237+
-- Verify spy called with filetype typescript
238+
local calls = _G.vim.api.nvim_set_option_value.calls or {}
239+
local found = false
240+
for _, c in ipairs(calls) do
241+
if c.vals[1] == "filetype" and c.vals[2] == "typescript" then
242+
found = true
243+
break
244+
end
245+
end
246+
expect(found).to_be_true()
247+
248+
rawset(io, "open", old_io_open)
249+
end)
250+
end)
251+
218252
describe("Open Diff Function", function()
219253
it("should use native provider", function()
220254
diff.setup({})

0 commit comments

Comments
 (0)