mfussenegger / nvim-jdtls

Extensions for the built-in LSP support in Neovim for eclipse.jdt.ls
GNU General Public License v3.0
1.09k stars 62 forks source link

Extract_* Methods Should Allow Renaming The Extracted Object #472

Closed rohit-s8 closed 1 year ago

rohit-s8 commented 1 year ago

Problem Statement

Right now, the extract methods only perform the refactoring. However, i almost always want to rename the refactored object post that. Of course I can jump to the refactored object and then trigger vim.lsp.buf.rename myself, but since i'm always doing this it would be great if this plugin could handle that and save me some extra keystrokes.

I tried wrapping the extract methods to do this myself, but i think the refactor happens asynchronously so the rename is not able to occur. Here is my wrapper function

local function extract_constant(visual)
  jdtls.extract_constant(visual)
  if visual then
   -- it stays in visual mode post refactoring so manually go back to normal mode
    local keys = vim.api.nvim_replace_termcodes("<esc>", true, false, true)
    vim.api.nvim_feedkeys(keys, "in", false)
  end
  vim.lsp.buf.rename()
end

-- extract_variable and extract_method functions are defined in the same way

The refactor works as before, but the rename fails with error Error on prepareRename: Renaming this element is not supported.

The extract_method is a bit trickier because unlike the other methods, i notice that it doesn't automatically jump to the newly extracted object. So we have to jump to it first and then trigger rename.

Ideas or possible solutions

I think it would be best if the plugin could handle this, but if not maybe expose an autocmd event which can then be hooked into. Something like JavaExtractComplete perhaps?

mfussenegger commented 1 year ago

The extract_method is a bit trickier because unlike the other methods, i notice that it doesn't automatically jump to the newly extracted object. So we have to jump to it first and then trigger rename.

You can trigger the rename from the call-site as well, you don't need to be on the method declaration. It actually intentionally always jumps to the extracted variable, so that you could follow up with a rename

Added a name parameter with https://github.com/mfussenegger/nvim-jdtls/pull/518, so you can call require("jdtls").extract_constant({ visual = false, name = "new_constant_name"}).

To get a prompt you can use vim.fn.input():

require("jdtls").extract_constant({ name = vim.fn.input("New name: ") })

And if you want the prompt after the narrowing-selection, you can make it lazy:

require("jdtls").extract_constant({ name = function() return vim.fn.input("New name: ") end })
rohit-s8 commented 1 year ago

@mfussenegger Thanks!!