@@ -51,7 +51,8 @@ local function get_diff(block)
5151
5252 -- If we found a valid buffer, get the reference content
5353 if bufnr and utils .buf_valid (bufnr ) then
54- reference = table.concat (vim .api .nvim_buf_get_lines (bufnr , start_line - 1 , end_line , false ), ' \n ' )
54+ local lines = vim .api .nvim_buf_get_lines (bufnr , start_line - 1 , end_line , false )
55+ reference = table.concat (lines , ' \n ' )
5556 filetype = vim .bo [bufnr ].filetype
5657 end
5758 end
@@ -212,7 +213,7 @@ return {
212213 return
213214 end
214215
215- local lines = vim . split (message .content , ' \n ' )
216+ local lines = utils . split_lines (message .content )
216217 local new_lines = {}
217218 local changed = false
218219
@@ -241,9 +242,9 @@ return {
241242 return
242243 end
243244
244- local lines = vim . split (diff .change , ' \n ' , { trimempty = false } )
245+ local lines = utils . split_lines (diff .change )
245246 vim .api .nvim_buf_set_lines (diff .bufnr , diff .start_line - 1 , diff .end_line , false , lines )
246- copilot .set_selection (diff .bufnr , diff .start_line , diff .start_line + # lines - 1 )
247+ copilot .set_selection (diff .bufnr , diff .start_line , diff .end_line )
247248 end ,
248249 },
249250
@@ -352,10 +353,9 @@ return {
352353 }
353354
354355 if copilot .config .mappings .show_diff .full_diff then
355- local modified = utils .buf_valid (diff .bufnr ) and vim .api .nvim_buf_get_lines (diff .bufnr , 0 , - 1 , false ) or {}
356+ local original = utils .buf_valid (diff .bufnr ) and vim .api .nvim_buf_get_lines (diff .bufnr , 0 , - 1 , false ) or {}
356357
357- -- Apply all diffs from same file
358- if # modified > 0 then
358+ if # original > 0 then
359359 -- Find all diffs from the same file in this section
360360 local message = copilot .chat :get_message (constants .ROLE .ASSISTANT , true )
361361 local section = message and message .section
@@ -367,30 +367,38 @@ return {
367367 table.insert (same_file_diffs , block_diff )
368368 end
369369 end
370+ end
370371
371- -- Sort diffs bottom to top to preserve line numbering
372- table.sort (same_file_diffs , function (a , b )
373- return a .start_line > b .start_line
374- end )
372+ -- Ensure we at least apply the current diff
373+ if # same_file_diffs == 0 then
374+ table.insert (same_file_diffs , diff )
375375 end
376376
377- for _ , file_diff in ipairs (same_file_diffs ) do
378- local start_idx = file_diff .start_line
379- local end_idx = file_diff .end_line
380- for _ = start_idx , end_idx do
381- table.remove (modified , start_idx )
377+ -- Sort diffs by start_line in descending order (apply from bottom to top)
378+ table.sort (same_file_diffs , function (a , b )
379+ return a .start_line > b .start_line
380+ end )
381+
382+ local result = vim .deepcopy (original )
383+
384+ -- Apply diffs from bottom to top so line numbers remain valid
385+ for _ , d in ipairs (same_file_diffs ) do
386+ local change_lines = utils .split_lines (d .change )
387+
388+ -- Remove original lines (from end to start to avoid index shifting)
389+ for i = d .end_line , d .start_line , - 1 do
390+ if result [i ] then
391+ table.remove (result , i )
392+ end
382393 end
383- local change_lines = vim .split (file_diff .change , ' \n ' )
384- for i , line in ipairs (change_lines ) do
385- table.insert (modified , start_idx + i , line )
394+
395+ -- Insert replacement lines at start_line
396+ for i = # change_lines , 1 , - 1 do
397+ table.insert (result , d .start_line , change_lines [i ])
386398 end
387399 end
388400
389- modified = vim .tbl_filter (function (line )
390- return line ~= nil
391- end , modified )
392-
393- opts .text = table.concat (modified , ' \n ' )
401+ opts .text = table.concat (result , ' \n ' )
394402 else
395403 opts .text = diff .change
396404 end
0 commit comments