smjonas / inc-rename.nvim

Incremental LSP renaming based on Neovim's command-preview feature.
MIT License
668 stars 9 forks source link

vim.ui.input() support #11

Closed RaafatTurki closed 2 years ago

RaafatTurki commented 2 years ago

I'll preface this with saying that I'm brand new to the command-preview business so there's a chance this isn't even possible but here it goes:

It would be great to use vim.ui.input() to get the new variable name instead of passing it as a command argument. That way users would be able to render the input however they desire (by using dressing.nvim for example) which helps a lot by keeping your eyes at the current line you're working on

image my own LSP rename command using vim.ui.input()

smjonas commented 2 years ago

That is definitely a better user experience than the current version! It has actually been requested from someone on Reddit but I also wasn't sure how to implement it. That is because Neovim's command preview feature is only made for commands. I have found something useful in the docs however (:h input()-highlight):

The optional `highlight` key allows specifying function which will be used for highlighting user input. [...]
Highlight function is called at least once for each new displayed input string, before command-line is redrawn.

So I think it should be possible by passing a highlight function to vim.ui.input() and updating the buffers inside this function.

If you want to create an initial PR that can be used to further discuss this, please feel free to do it (it does not have to be complete or working)! I will probably have some time later today to have a look at this.

smjonas commented 2 years ago

So I tested this a bit but it doesn't seem like it is possible using the highlight function: If we use this code:

local function rename() 
  vim.ui.input({
    prompt = "New name: ",
    highlight = function(new_name)
      vim.api.nvim_buf_set_lines(0, 0, 1, false, { "Test" })
      return { { 0, #new_name, "Substitute" } }
    end,
  }, function()
    print("Executing...")
  end)
end

and call the rename function, the lines in the buffer will not change until the user presses enter. So it seems like this feature is currently not possible to implement. It probably requires proper support for vim.ui.input preview in Neovim.

Let me know if you have any other ideas on how this could be achieved!

RaafatTurki commented 2 years ago

I got it working, You were on the right track You just needed to use the correct buffer number, I bet you've forgotten that vim.ui.input() is a tiny buffer itself (I use dressing.nvim idk about vanilla). What you had to do was nvim_get_current_buf() before the cursor jumps inside the input box and pass that to nvim_buf_set_lines()

Try this function and keep an eye on the 1st line of your file.

  function test() 
    local bufnr = vim.api.nvim_get_current_buf()
    vim.ui.input({
      prompt = "New name: ",
      highlight = function(new_name)
        vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, { new_name })
        return {}
      end,
    }, function()
        print("Executing...")
      end)
  end
smjonas commented 2 years ago

Ok it's good to know that it's working for dressing.nvim! For vanilla Nvim, no new buffer is created so it doesn't work. I'll add support for dressing.nvim then :+1:

RaafatTurki commented 2 years ago

Superb, To be fair even if it supported vanilla nvim it wouldn't be an improvement since it doesn't provide much (if any) benefit over the user command argument method.

Can't wait to see what you'd do.

smjonas commented 2 years ago

Closed by #12.