Hi, coming back to thank for the report. Compilation warnings were not longer consider an error during installation .
I’m glad that you liked it! My Elixir theme is Tokyo Night
Hello, the binding do work for me, can you check if it’s correctly configured in your keywords shortcuts?
Unfortunately, no, renames don’t work across the whole project yet, only inside that function module. However, I do intend to work on that next year.
Fantastic work @gpereira ! Looking forward to the ZED port
@synic I’ve only recently started usingg Neovim. How am I meant to use this plugin? I’ve installed it, but calling vim.lsp.buf.code_action()
doesn’t do anything, for example. Is there something I need to do to set it up?
@zachdaniel you have to be in a context that has an action, or select a block of code that can be actioned upon. You can see examples of what’s possible here: GitHub - gp-pereira/refactorex: A VS Code extension for fast and reliable Elixir code refactoring.
Also vim.lsp.buf.rename()
should work to rename local symbols
If you’re using lspconfig, you can use :LspInfo
to see if it’s running and attached to the current buffer
Just to report that using AstroNvim I was able to create a file in my config directory with the relative path lua/plugins/refactorex.lua
with these contents:
return {
"synic/refactorex.nvim",
ft = "elixir",
---@module "refactorex.nvim"
---@type refactorex.Config
opts = {
auto_update = true,
pin_version = nil,
},
}
Then after opening an Elixir project then refactorex
was downloaded and compiled and I was able to see LSP code actions provided by RefactorEx. So it seems your addon is working fine.
Though have in mind that the line with the type shows me a warning:
Undefined type or alias `refactorex.Config`.
But it does not seem to impede any functionality (tried two refactorings and they worked).
Something I’m noticing is that if I have content selected in visual line mode, I can use the refactors, but not if I just have some text in visual block. i.e this doesn’t offer a refactor to extract into a variable. Am I doing it wrong?
But it does not seem to impede any functionality (tried two refactorings and they worked).
Yeah, that’s just the type hints (if you have lazydev or something - lua_ls supports type hinting sorta like python or typescript). You can remove the ---@module
and ---@type
hint lines safely
We will have to defer to @gpereira on this one, I am not sure (refactorex.nvim just sets up the connection to the refactorex language server, and the language server handles everything else)
Hi there, hope you are enjoying the tool so far.
So, the problem you’re facing is that extractors currently work on a specific node of the AST. In the example you provided, the generated AST is:
+
|- +
| |- x
| \- y
\- z
So, selecting y + z really won’t show you any available refactorings because a node like that doesn’t exist in the tree. I see how inconvenient that might be while refactoring math expressions like the example, so I’ll def look into that in the future.
Selecting x + y should yield the expected refactorings.
Hm… Interesting. I don’t see refactorings provided for either actually, but I do see what you mean about the AST structure there. I imagine something could be done for operators specifically which is the only place you’d have this problem, but it may not be worth the effort to make it work.
Specifically, the associativity of the operators is known, and so before attempting to provide a refactoring you could attempt to rewrite nested operator calls in some equivalent way to cover the range. Like in this case
+
|- +
| |- x
| \- y
\- z
is equivalent to
+
|- +
| |- x
| \- +
| | y
| | z
The interesting thing (and I’m actually surprised the Elixir formatter doesn’t step in here to solve this ambiguity, @josevalim)
If you were to highlight y - z
in x - y - z
you definitely could not extract y - z
into a variable as it would actually change the outcome of that statement. I’m pretty surprised that the formatter doesn’t turn x - y - z
into (x - y) - z
automatically, because then selecting y) - z
would not even appear to be something you could refactor.
Going to try this. Thanks!
Adding a tangential and self-serving comment here: this would be nice. I dislike how the formatter is operator precedent aware. Even though I did just fine in math, (3 * 2) + 1
is a lot nicer in code. Just like you say: it makes it clear what could be extracted.
EDIT: I can see how this would be a deal-breaker for math-heavy projects.
That’s weird. I just installed neovim (which I didn’t have before), lazynvim and refactorex via the plugin by synic and the refactorings show up for me.
I had to explicitly set the keybindings in the init.lua
though.
...
vim.keymap.set('v', '<space>r', vim.lsp.buf.code_action)
vim.keymap.set('n', '<space>r', vim.lsp.buf.code_action)
vim.keymap.set('v', '<F2>', vim.lsp.buf.rename)
vim.keymap.set('n', '<F2>', vim.lsp.buf.rename)
After setting them and doing valid selections, I could choose between the refactorings. Is that setup something every new neovim user must do @synic? If so, we should include it in the docs. Btw, super easy to install and switch versions using the plugin. Great work, man!
I’ve been thinkering with ideas on how to make this work. Since I look for the selection subtree inside the complete AST, I’d have to generate the combinatory equivalences on the AST, like the example you showed. So when it found some +
containing another +
, it would compare both orderings. The only operators that fall in this category are +
and *
, right? However, this can become quite computationally expensive depending on how it is implemented.
EDIT: Sorry, I just now understood your problem, visual block is a different mode (not sure) in neovim and on it the refactorings aren’t working. I did some testing and apparently the payload sent to the LSP is different from visual mode
visual block mode
{
id = 4,
...,
range = {
["end"] = <1>{
character = 9,
line = 9
},
start = <table 1>
}
}
visual mode
{
id = 5,
...,
range = {
["end"] = {
character = 9,
line = 9
},
start = {
character = 4,
line = 9
}
}
}
I have no clue why they seem different and couldn’t check if they don’t end up being the same value after some conversion of this table thing. What I can confirm is that only renaming and same line refactorings work on this mode, as you stated.
Sort of, it’s more of a general LSP thing though and not refactorex.nvim specific. People generally set up their own keybinds (that’s the vim way) or just run :lua vim.lsp.buf.code_action()
That being said, couldn’t hurt to throw something in the docs saying that those are the two commands they should use with some examples! I’ll add something later today
Zed
team made again a great job!
https://zed.dev/blog/edit-prediction
I wonder if project like that can be integrated with this zed
feature to provide better Elixir
predictions.
hey @gpereira
I’m getting this error all the times that I started my VScode. not sure what I can do on my end, can you take a look please?
[Info - 11:03:25 AM] Client is waiting server
[Info - 11:03:26 AM]
[Info - 11:03:28 AM] Server started on port 39929
[Error - 11:03:59 AM] Refactorex client: couldn't create connection to server.
Error: Client could not connect to the server.
at Socket.<anonymous> (/home/isabelle/.vscode-server/extensions/gp-pereira.refatorex-0.1.44/src/extension.ts:138:13)
at Socket.emit (node:events:524:28)
at Socket.emit (node:domain:489:12)
at emitErrorNT (node:internal/streams/destroy:169:8)
at emitErrorCloseNT (node:internal/streams/destroy:128:3)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
if you need something else, let me know