neovim / nvim-lspconfig

Quickstart configs for Nvim LSP
Apache License 2.0
10.47k stars 2.06k forks source link

Cannot figure out, for the life of me, what to pass to vim.lsp.buf.code_action() as a range. #3283

Closed avario-cpu closed 1 month ago

avario-cpu commented 1 month ago

Description

So ....

  1. I get a visual range with:

    local start_pos = vim.fn.getcharpos("'<")
    local end_pos = vim.fn.getcharpos("'>")
    1. I have brute forced every single 1 and 0 possible there....
      local start_row = start_pos[2] - 1
      local start_col = start_pos[3] - 1
      local end_row = end_pos[2] - 1
      local end_col = end_pos[3] - 1
  2. I desperately try to pass the range to buf.code_action

    local opts = {
      context = {
        diagnostics = {}, 
        only = nil,
      },
      range = {
        start = { start_row, start_col },
        ["end"] = { end_row, end_col },
      },
    }
    vim.lsp.buf.code_action(opts)
  3. I have plenty of prints etc to show the value before/after the index modifs...

  4. Every single attempt at a method extraction I've made I've been told to "select a complete statement". Wether tried on just one line, or mutlitple. Whatest giveth ?

For those who want to see/try the whole function:

Click to expand ```lua local M = {} function M.code_action_on_selection() -- Capture the current mode local mode = vim.api.nvim_get_mode().mode print("Current mode:", mode) -- Check if we're in visual mode if not string.match(mode, "^[vV\22]") then vim.notify("This function should be called in visual mode", vim.log.levels.WARN) return end -- Markers update when leaving visual mode vim.cmd([[ execute "normal! \" ]]) local start_pos = vim.fn.getcharpos("'<") local end_pos = vim.fn.getcharpos("'>") -- Print raw positions print("Raw start position:", vim.inspect(start_pos)) print("Raw end position:", vim.inspect(end_pos)) -- Check if positions are valid if not start_pos or not end_pos or #start_pos < 4 or #end_pos < 4 then vim.notify("Invalid position data", vim.log.levels.ERROR) return end -- Convert positions to zero-indexed (LSP format) local start_row = start_pos[2] - 1 local start_col = start_pos[3] - 1 local end_row = end_pos[2] - 1 local end_col = end_pos[3] - 1 -- Print converted positions print("Converted start position: line =", start_row, "character =", start_col) print("Converted end position: line =", end_row, "character =", end_col) -- Ensure that the range is valid if start_row >= 0 and start_col >= 0 and end_row >= 0 and end_col >= 0 then local range = { start = { line = start_row, character = start_col }, ["end"] = { line = end_row, character = end_col }, } -- Print the final range print("Final range:", vim.inspect(range)) local opts = { context = { diagnostics = {}, only = nil, }, range = { start = { start_row, start_col }, ["end"] = { end_row, end_col }, }, } -- Invoke code action with the range vim.lsp.buf.code_action(opts) else vim.notify("Invalid selection range for code action", vim.log.levels.ERROR) end end return M ```

Before you ask... when using a fuzzzyfiner for code actions (Telescope), the visual selection will be dropped. This seems then to be the only way to pass a visual selection to a lsp client.

Not really a lsp config issue... but didn't know where else to post this sry.

And yes, I've tried with ...

  local start_pos = vim.fn.getpos("'<")
  local end_pos = vim.fn.getpos("'>")

... too, to apparently no avail. Not gonna brute force the 0/1 for this one too. Main issue with this one seems to be the "infinite/eof" number we get for the ending character, altough I'm not so sure it's really a problem.

glepnir commented 1 month ago

vim.fn.getpos