Repository: neovim/neovim
File: runtime/lua/vim/lsp/util.lua (Lua)

Code before:
  end

  assert(bufnr ~= 0, 'Explicit buffer number is required')

  if not api.nvim_buf_is_loaded(bufnr) then
    vim.fn.bufload(bufnr)
  end
  vim.bo[bufnr].buflisted = true

  -- Fix reversed range and indexing each text_edits
  for index, text_edit in ipairs(text_edits) do
    --- @cast text_edit lsp.TextEdit|{_index: integer}
    text_edit._index = index

    if
      text_edit.range.start.line > text_edit.range['end'].line
      or text_edit.range.start.line == text_edit.range['end'].line
        and text_edit.range.start.character > text_edit.range['end'].character
    then
      local start = text_edit.range.start
      text_edit.range.start = text_edit.range['end']
      text_edit.range['end'] = start
    end
  end

  --- @alias TextEdit lsp.TextEdit|lsp.AnnotatedTextEdit|{_index: integer}
  --- @cast text_edits TextEdit[]

  -- Sort text_edits
  ---@param a TextEdit
  ---@param b TextEdit
  ---@return boolean
  table.sort(text_edits, function(a, b)
    if a.range.start.line ~= b.range.start.line then
      return a.range.start.line > b.range.start.line
    end
    if a.range.start.character ~= b.range.start.character then
      return a.range.start.character > b.range.start.character
    end
    return a._index > b._index
  end)

  -- save and restore local marks since they get deleted by nvim_buf_set_lines
  local marks = {} --- @type table<string,[integer,integer]>
  for _, m in pairs(vim.fn.getmarklist(bufnr)) do
    if m.mark:match("^'[a-z]$") then
      marks[m.mark:sub(2, 2)] = { m.pos[2], m.pos[3] - 1 } -- api-indexed
    end
  end

  local has_eol_text_edit = false

Review comment (suggestion):
```suggestion
  --- @alias vim.lsp.TextEdit lsp.TextEdit|lsp.AnnotatedTextEdit|{_index: integer}
```


Code after:
  end

  assert(bufnr ~= 0, 'Explicit buffer number is required')

  if not api.nvim_buf_is_loaded(bufnr) then
    vim.fn.bufload(bufnr)
  end
  vim.bo[bufnr].buflisted = true

  local marks = {} --- @type table<string,[integer,integer]>
  local has_eol_text_edit = false

  local function apply_text_edits()
    -- Fix reversed range and indexing each text_edits
    for index, text_edit in ipairs(text_edits) do
      --- @cast text_edit lsp.TextEdit|{_index: integer}
      text_edit._index = index

      if
        text_edit.range.start.line > text_edit.range['end'].line
        or text_edit.range.start.line == text_edit.range['end'].line
          and text_edit.range.start.character > text_edit.range['end'].character
      then
        local start = text_edit.range.start
        text_edit.range.start = text_edit.range['end']
        text_edit.range['end'] = start
      end
    end

    --- @cast text_edits (lsp.TextEdit|lsp.AnnotatedTextEdit|{_index: integer})[]

    -- Sort text_edits
    ---@param a (lsp.TextEdit|lsp.AnnotatedTextEdit|{_index: integer})
    ---@param b (lsp.TextEdit|lsp.AnnotatedTextEdit|{_index: integer})
    ---@return boolean
    table.sort(text_edits, function(a, b)
      if a.range.start.line ~= b.range.start.line then
        return a.range.start.line > b.range.start.line
      end
      if a.range.start.character ~= b.range.start.character then
        return a.range.start.character > b.range.start.character
      end
      return a._index > b._index
    end)

    -- save and restore local marks since they get deleted by nvim_buf_set_lines
    for _, m in pairs(vim.fn.getmarklist(bufnr)) do
      if m.mark:match("^'[a-z]$") then
        marks[m.mark:sub(2, 2)] = { m.pos[2], m.pos[3] - 1 } -- api-indexed
      end
    end