@@ -459,59 +459,52 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
459459text = split (text_edit .newText ,' \n ' ,true ),
460460 }
461461
462- -- Some LSP servers may return +1 range of the buffer content but nvim_buf_set_text can't accept it so we should fix it here.
463462local max = api .nvim_buf_line_count (bufnr )
464- if max <= e .start_row or max <= e .end_row then
465- local len = # (get_line (bufnr ,max - 1 )or ' ' )
466- if max <= e .start_row then
467- e .start_row = max - 1
468- e .start_col = len
469- table.insert (e .text ,1 ,' ' )
470- end
463+ -- If the whole edit is after the lines in the buffer we can simply add the new text to the end
464+ -- of the buffer.
465+ if max <= e .start_row then
466+ api .nvim_buf_set_lines (bufnr ,max ,max ,false ,e .text )
467+ else
468+ local last_line_len = # (get_line (bufnr ,math.min (e .end_row ,max - 1 ))or ' ' )
469+ -- Some LSP servers may return +1 range of the buffer content but nvim_buf_set_text can't
470+ -- accept it so we should fix it here.
471471if max <= e .end_row then
472472e .end_row = max - 1
473- e .end_col = len
473+ e .end_col = last_line_len
474+ has_eol_text_edit = true
475+ else
476+ -- If the replacement is over the end of a line (i.e. e.end_col is out of bounds and the
477+ -- replacement text ends with a newline We can likely assume that the replacement is assumed
478+ -- to be meant to replace the newline with another newline and we need to make sure this
479+ -- doens't add an extra empty line. E.g. when the last line to be replaced contains a '\r'
480+ -- in the file some servers (clangd on windows) will include that character in the line
481+ -- while nvim_buf_set_lines doesn't count it as part of the line.
482+ if
483+ e .end_col > last_line_len
484+ and # text_edit .newText > 0
485+ and string.sub (text_edit .newText ,- 1 )== ' \n '
486+ then
487+ table.remove (e .text ,# e .text )
488+ end
474489end
475- has_eol_text_edit = true
476- end
490+ -- Make sure we don't go out of bounds for e.end_col
491+ e . end_col = math.min ( last_line_len , e . end_col )
477492
478- -- If the replacement is over the end of a line (i.e. e.end_col is out of bounds and the
479- -- replacement text ends with a newline We can likely assume that the replacement is assumed to
480- -- be meant to replace the newline with another newline and we need to make sure this doens't
481- -- add an extra empty line. E.g. when the last line to be replaced contains a '\r' in the file
482- -- some servers (clangd on windows) will include that character in the line while
483- -- nvim_buf_set_lines doesn't count it as part of the line.
484- local last_line = get_line (bufnr ,e .end_row )
485- if
486- e .end_col > # last_line
487- and # text_edit .newText > 0
488- and string.sub (text_edit .newText ,- 1 )== ' \n '
489- then
490- table.remove (e .text ,# e .text )
491- end
492- -- Make sure we don't go out of bounds for e.end_col
493- e .end_col = math.min (# last_line ,e .end_col )
494-
495- -- If the replacement is over full lines it is recommended to use nvim_buf_set_lines
496- -- see. https://neovim.io/doc/user/api.html#nvim_buf_set_test()
497- if e .end_col == # last_line and e .start_col == 0 then
498- api .nvim_buf_set_lines (bufnr ,e .start_row ,e .end_row + 1 ,false ,e .text )
499- else
500493api .nvim_buf_set_text (bufnr ,e .start_row ,e .start_col ,e .end_row ,e .end_col ,e .text )
501- end
502494
503- -- Fix cursor position.
504- local row_count = (e .end_row - e .start_row )+ 1
505- if e .end_row < cursor .row then
506- cursor .row = cursor .row + (# e .text - row_count )
507- is_cursor_fixed = true
508- elseif e .end_row == cursor .row and e .end_col <= cursor .col then
509- cursor .row = cursor .row + (# e .text - row_count )
510- cursor .col = # e .text [# e .text ]+ (cursor .col - e .end_col )
511- if # e .text == 1 then
512- cursor .col = cursor .col + e .start_col
495+ -- Fix cursor position.
496+ local row_count = (e .end_row - e .start_row )+ 1
497+ if e .end_row < cursor .row then
498+ cursor .row = cursor .row + (# e .text - row_count )
499+ is_cursor_fixed = true
500+ elseif e .end_row == cursor .row and e .end_col <= cursor .col then
501+ cursor .row = cursor .row + (# e .text - row_count )
502+ cursor .col = # e .text [# e .text ]+ (cursor .col - e .end_col )
503+ if # e .text == 1 then
504+ cursor .col = cursor .col + e .start_col
505+ end
506+ is_cursor_fixed = true
513507end
514- is_cursor_fixed = true
515508end
516509end
517510