@@ -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 )
226226end
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+
234279function 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
0 commit comments