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

Code before:
    if text_edit.annotationId then
      assert(
        change_annotations ~= nil,
        'change_annotations must be provided for annotated text edits'
      )

      local annotation = assert(
        change_annotations[text_edit.annotationId],
        string.format('No change annotation found for ID: %s', text_edit.annotationId)
      )

      if annotation.needsConfirmation then
        confirmations[annotation.label] = (confirmations[annotation.label] or 0) + 1
      end

      change_count[text_edit.annotationId] = (change_count[text_edit.annotationId] or 0) + 1
    end
  end

  if next(confirmations) then
    local message = { 'Apply all changes?' }
    for label, count in pairs(confirmations) do
      message[#message + 1] = label .. (count > 1 and string.format(' (%d)', count) or '')
    end

    vim.ui.select({ 'Yes', 'No' }, { prompt = table.concat(message, '\n') }, function(input)
      if input == 'Yes' then
        -- Proceed with applying text edits.
        apply_text_edits()
      end
    end)
  else
    -- No confirmations needed, apply text edits directly.
    apply_text_edits()
  end

  if change_annotations ~= nil and next(change_count) then
    local change_message = { 'Applied changes:' }
    for id, count in pairs(change_count) do
      local annotation = change_annotations[id]
      change_message[#change_message + 1] = annotation.label
        .. (annotation.description and (': ' .. annotation.description) or '')
        .. (count > 1 and string.format(' (%d)', count) or '')
    end
    vim.notify(table.concat(change_message, '\n'), vim.log.levels.INFO)
  end

  local max = api.nvim_buf_line_count(bufnr)

  -- no need to restore marks that still exist
  for _, m in pairs(vim.fn.getmarklist(bufnr)) do

Review comment (suggestion):
I'd say that `vim.ui.select()` is probably not the best approach to use here. It is more intended for selecting from a list of items and not quite for showing message to receive a confirm/deny. There is `vim.fn.confirm()` just for that with a bit more design towards "confirm" use case (like allowing to press `y` for `Yes` and `n` for `No`).

One big downside of `vim.ui.select()` (and all of its popular implementations via floating windows) is that it is not really designed to show multiline `prompt`, which I'd guess is very common in this use case. The default implementation handles that mostly by coincidence (as it uses `vim.fn.inputlist()` which shows message in command line), but so does `vim.fn.confirm`.

The difference of `vim.fn.confirm()` and `vim.ui.select()` is that the first is blocking by design. But I'd guess it is even more appropriate here. Besides, the default `vim.ui.select()` is also blocking.

Code after:
    if text_edit.annotationId then
      assert(
        change_annotations ~= nil,
        'change_annotations must be provided for annotated text edits'
      )

      local annotation = assert(
        change_annotations[text_edit.annotationId],
        string.format('No change annotation found for ID: %s', text_edit.annotationId)
      )

      if annotation.needsConfirmation then
        confirmations[text_edit.annotationId] = (confirmations[text_edit.annotationId] or 0) + 1
      end

      change_count[text_edit.annotationId] = (change_count[text_edit.annotationId] or 0) + 1
    end
  end

  if next(confirmations) then
    local message = { 'Apply all changes?' }
    for id, count in pairs(confirmations) do
      local annotation = assert(change_annotations)[id]
      message[#message + 1] = annotation.label
        .. (annotation.description and (string.format(': %s', annotation.description)) or '')
        .. (count > 1 and string.format(' (%d)', count) or '')
    end

    local response = vim.fn.confirm(table.concat(message, '\n'), '&Yes\n&No', 1, 'Question')
    if response == 1 then
      -- Proceed with applying text edits.
      apply_text_edits()
    else
      -- Don't apply any text edits.
      return
    end
  else
    -- No confirmations needed, apply text edits directly.
    apply_text_edits()
  end

  if change_annotations ~= nil and next(change_count) then
    local change_message = { 'Applied changes:' }
    for id, count in pairs(change_count) do
      local annotation = change_annotations[id]
      change_message[#change_message + 1] = annotation.label
        .. (annotation.description and (': ' .. annotation.description) or '')
        .. (count > 1 and string.format(' (%d)', count) or '')
    end
    vim.notify(table.concat(change_message, '\n'), vim.log.levels.INFO)
  end