@@ -225,12 +225,57 @@ function M._cleanup_diff_layout(tab_name, target_win, new_win)
225
225
logger .debug (" diff" , " [CLEANUP] Layout cleanup completed for:" , tab_name )
226
226
end
227
227
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
228
272
--- Open diff using native Neovim functionality
229
273
-- @param old_file_path string Path to the original file
230
274
-- @param new_file_path string Path to the new file (used for naming)
231
275
-- @param new_file_contents string Contents of the new file
232
276
-- @param tab_name string Name for the diff tab/view
233
277
-- @return table Result with provider, tab_name, and success status
278
+
234
279
function M ._open_native_diff (old_file_path , new_file_path , new_file_contents , tab_name )
235
280
local new_filename = vim .fn .fnamemodify (new_file_path , " :t" ) .. " .new"
236
281
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
259
304
vim .cmd (" edit " .. vim .fn .fnameescape (tmp_file ))
260
305
vim .api .nvim_buf_set_name (0 , new_file_path .. " (New)" )
261
306
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
+
262
314
vim .cmd (" wincmd =" )
263
315
264
- local new_buf = vim . api . nvim_get_current_buf ()
316
+ local new_buf = proposed_buf
265
317
vim .api .nvim_set_option_value (" buftype" , " nofile" , { buf = new_buf })
266
318
vim .api .nvim_set_option_value (" bufhidden" , " wipe" , { buf = new_buf })
267
319
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
665
717
vim .cmd (" vsplit" )
666
718
local new_win = vim .api .nvim_get_current_win ()
667
719
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
668
726
vim .cmd (" diffthis" )
669
727
logger .debug (" diff" , " Created split window" , new_win , " with new buffer" , new_buffer )
670
728
0 commit comments