feat(mini.files): make file system actions LSP aware#2340
feat(mini.files): make file system actions LSP aware#2340TheLeoP wants to merge 9 commits intonvim-mini:mainfrom
Conversation
|
To test the PR using with the following content -- main.lua
local something = require("something").something
something()
-- something.lua
local M = {}
M.something = function()
print("something")
end
return Myou can then |
|
The tests errors seem to go away if I comment out Line 2898 in 134f9dd and Line 2911 in 134f9dd But I'm not sure why. In particular, the problematic lines seem to be Line 2754 in 134f9dd and Line 2802 in 134f9dd changing them to local clients = {}seems to also make the test pass. Are these tests specially time sensitive? I can't think of another reason of why they would be failing |
echasnovski
left a comment
There was a problem hiding this comment.
Thanks for the PR!
There are at least two good things: the LSP complexity seems to be understood and managed (the worst part for me :) ) and there is a room for making it more concise.
lua/mini/files.lua
Outdated
| uri = vim.uri_from_fname(path), | ||
| } }, | ||
| } | ||
| H.lsp_will_fs_do('create', lsp_params) |
There was a problem hiding this comment.
It seems that willCreateFiles is for files only, right? This will also send a request for a directory.
There was a problem hiding this comment.
It seems like language servers should exclude file/directories if they are not interested in those.
Edit: while looking this up, I realized that my current implementation of filters assumes that all filters should match a file for it to be considered, but it seems like any filter must match instead. This makes the implementation a bit more complex, let me know what you think
lua/mini/files.lua
Outdated
| rename = 'willRename', | ||
| } | ||
|
|
||
| H.lsp_will_fs_do = function(action, params) |
There was a problem hiding this comment.
I have so many questions (mostly due to LSP complexity, not only due to the PR itself) ...
- It seems that it is possible to make requests/notifications in bulk for every three operation kinds. I'd say it is worth taking advantage of that: it is less talking back-and-forth between the client and the server, less computation based on the client capabilities, etc.
- There is a lot of code duplication between two functions. Either moving that to a separate function is better. Or even probably just using a single function that has something like
if method:sub(1, 3) == 'did' then ... else ... end. - I think
H.lsp_{will,did}_fs_do_methodis a bit too much. Maybe supplying a method directly when calling a function is more explicit.
So all in all, my first instinct is that adding all LSP related stuff (done in bulk) in the H.fs_actions_apply() (so that it is "willXxx requests", "action", "didXxx notifications") should be less complex and more concise. Yes, it will probably require an duplicating check about if the actions is predicted to be successful, but can be worked around later. This way it can also reuse computed parameters.
There was a problem hiding this comment.
I pushed a couple of commits that should address all of these comments. The only difference is that instead of reusing the parameters for the LSP operations, I'm checking which operations succeeded for the didXxx notifications
I don't think so. Probably, some logic has been broken. Didn't read too much into the code.
Restricting this functionality to only Neovim<0.11 is fine.
I am okay with these checks for I'll also take a look into how to better handle the "close on lost focus" in 'mini.files'. It will probably have to be "don't close if inside non-normal buffer in a floating window" type of exception. |
Okay, I've looked into this. Going the "don't close explorer if in floating window" goes against some of the use cases that originally prompted the tracking of lost focus. Like "I want to I think the best compromise here would be to temporarily adjust Something like this (as of the current state of this PR) seems to work: diff --git a/lua/mini/files.lua b/lua/mini/files.lua
index 304e895f..fce1bbb7 100644
--- a/lua/mini/files.lua
+++ b/lua/mini/files.lua
@@ -1540,7 +1540,7 @@ end
H.explorer_track_lost_focus = function()
local track = vim.schedule_wrap(function()
local ft = vim.bo.filetype
- if ft == 'minifiles' or ft == 'minifiles-help' then return end
+ if H.skip_track_lost_focus or ft == 'minifiles' or ft == 'minifiles-help' then return end
local cur_win_id = vim.api.nvim_get_current_win()
MiniFiles.close()
pcall(vim.api.nvim_set_current_win, cur_win_id)
@@ -2753,6 +2753,15 @@ H.lsp_will_fs_do = function(action, params)
local full_method = 'workspace/' .. method .. 'Files'
local clients = vim.lsp.get_clients({ method = full_method })
+ local ui_select_orig = vim.ui.select
+ vim.ui.select = function(items, opts, on_choice)
+ H.skip_track_lost_focus = MiniFiles.get_explorer_state() ~= nil
+ ui_select_orig(items, opts, function(...)
+ H.skip_track_lost_focus, vim.ui.select = nil, ui_select_orig
+ on_choice(...)
+ end)
+ end
+
-- TODO(TheLeoP): configurable timeout
local timeout = 1000
for _, client in ipairs(clients) doOne thing to extra consider is whether there will be any side effects if Thinking about it more, maybe it is a good idea to have this kind of mock in general for the whole duration of the explorer. Will also work nicely with something like 'mini.snippets' (which can use |
Yeah, ignoring tracking lost focus while I tried it with this PR and:
|
|
Thanks for your feedback! I'll be a bit busy today and tomorrow, so I'll address your comments and I'll keep working on this PR on Sunday |
Soo... I spent some time investigating in the hopes of opening an issue in neovim/neovim to drop the
Repro steps for what I did:
|
Refactor `H.lsp_{will,did}_fs_do_metho` into a single function
Execute LSP requests/notifications in bulk inside `H.fs_actions_apply`
`string.lower()` -> `vim.fn.tolower()`
Add LSP filter for directory/file
Fix: join all checks within a single filter with AND and all the filters for a given server with OR
This seems to be need to make all tests pass. Can `from` be nil outside of tests?
|
The bulk LSP request/notifications should be working now. I left them on separated commits to make reviewing a bit easier. Let me know if you have any more feedback regarding the implementation. After that is done, I'll focus on creating some tests. What would be your preference for testing this? My guess is that it would be to mock a language server. I can take a look at |
Addresses #2215
This is a proof of concept to test the idea of including this kind of LSP support inside of mini.files. It may not be merged at all or it may help to add new autocmds to allow users/other plugins to implement this themselves.
A few things to take into account
H.fs_do.deletehad to be changed to allow checkingsuccessa single time before triggeringdidDeleteFilenotifications (actually, it seems like I broke something)timeoutforclient:request_syncis harcodedvim.glob.to_lpeghas a bug prior to 0.11 that requires manually sorting items inside brackets as a workaround,client:request_sync/client:notifyare not methods prior to 0.11, etc)libuvdoes not offer an abstraction on top of it. Maybefs_statrelated function would work on Windows with the same semantics, I haven't tested it yet)