Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: ssr across files #13

Open
D00mch opened this issue Jan 2, 2023 · 10 comments
Open

Feature: ssr across files #13

D00mch opened this issue Jan 2, 2023 · 10 comments

Comments

@D00mch
Copy link

D00mch commented Jan 2, 2023

I'm not sure how difficult it would be to implement, but it would be a useful feature when you need to make a similar change in several files.

@cshuaimin
Copy link
Owner

There's a discussion on reddit. I'm not confident in project wide refactoring with treesitter rather than LSP servers, so ssr.nvim is focusing on single file UX now.

@llllvvuu
Copy link

llllvvuu commented Jul 18, 2023

From what I can tell, the Ui class already keeps track of the state globally even after you close the window, so you can just do

:cfdo lua require('ssr').replace_confirm()
:cfdo lua require('ssr').replace_all()

No need for the plugin to know about multiple files.

EDIT: OK, there are a few problems with this method:

  • cfdo runs concurrently
  • origin_win, origin_buf, and matches are cached

i'll see if there is a simple workaround...

llllvvuu added a commit to llllvvuu/ssr.nvim that referenced this issue Jul 18, 2023
llllvvuu added a commit to llllvvuu/ssr.nvim that referenced this issue Jul 18, 2023
@llllvvuu
Copy link

llllvvuu commented Jul 18, 2023

OK, different idea for the workflow: #26

Not as automated (this may actually be good) but should get the job done.

@cshuaimin
Copy link
Owner

Initially I thought it would be too slow to search entire project, because we need to open every file in vim, parse the buffer with treesitter and run a query, all in one single thread. However if you already have a small list of files in quickfix, it seems doable.

#26 is indeed a good improvement, I use :Telescope resume very often and wish there's a "resume" functionality in every plugin which uses a scratch buffer.

However I think if you want to replace in multiple files, instead of reopening ssr window in next file, it would be better to just not close it! If we make ssr window global and not related to the buffer it was opened from, we can apply the same ssr rule in other buffers, as long as ssr window is kept open. This is like when ssr window is open, the matched regions are kept highlighted and n/N are remapped to use ssr's next/prev.

This way, we can use :cfdo lua require('ssr').replace_all() proposed by @llllvvuu.

@llllvvuu
Copy link

llllvvuu commented Jul 18, 2023

However I think if you want to replace in multiple files, instead of reopening ssr window in next file, it would be better to just not close it! If we make ssr window global and not related to the buffer it was opened from

Yeah this is what I initially tried, but I couldn't figure out how, without refactoring a lot of things to be more "pure" functional style, which handles concurrency naturally. So I made #26 as a shorter-term feature that could hopefully get implemented/reviewed faster.

I think cfdo is feasible for replace_all(), if replaced some references to shared state with locals: e.g. search needs to take maybe buf and silent and then can do local matches = self.search(local_buf, silent = true). I suspect it's not enough to change the global self.origin_buf on BufEnter, due to concurrently entering multiple buffers at once. Unless self.matches is changed to a mapping from bufnr to matches.

For replace_confirm(), it might be harder since we don't want to show the confirm windows concurrently. For that maybe instead of cfdo it can be replace_confirm(bufs) which would show the confirm windows serially. And a helper like replace_confirm_qf() that would get the buf list from vim.fn.getqflist() and pass it to replace_confirm(bufs).

These are rough ideas, so maybe there are cleaner methods.

@cshuaimin
Copy link
Owner

I don't think cfdo is concurrently as the doc says

It works like doing this:  
	:cfirst
	:{cmd}
	:cnfile
	:{cmd}
	etc.

and can be verified by

:cfdo lua print(vim.api.nvim_get_current_buf()) vim.uv.sleep(100) print(vim.api.nvim_get_current_buf())                                                                                                                                                                                
                                                                                                                                                                                                                                                                                       
"~/Code/ssr.nvim/LICENSE" 21 lines --4%--                                                                                                                                                                                                                                              
(1 of 8): LICENSE                                                                                                                                                                                                                                                                      
10                                                                                                                                                                                                                                                                                     
10                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                       
"~/Code/ssr.nvim/README.md" 68 lines --1%--                                                                                                                                                                                                                                            
(2 of 8): README.md                                                                                                                                                                                                                                                                    
11                                                                                                                                                                                                                                                                                     
11                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                       
"~/Code/ssr.nvim/tests/ssr_spec.lua" 202 lines --0%--                                                                                                                                                                                                                                  
(3 of 8): tests/ssr_spec.lua                                                                                                                                                                                                                                                           
12                                                                                                                                                                                                                                                                                     
12                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

I suspect it's not enough to change the global self.origin_buf on BufEnter

To make ssr window global, fields like origin_buf need to be removed from the Ui class, and call nvim_get_current_buf() each time. I'll do that refactor later.

@llllvvuu
Copy link

llllvvuu commented Jul 18, 2023

I don't think cfdo is concurrently as the doc says

Ah OK, that makes sense. What I had mistaken as concurrent behavior was simply open_confirm_win() being non-blocking. In that case :cfdo lua require('ssr').replace_all() seems more feasible :)

To make ssr window global, fields like origin_buf need to be removed from the Ui class, and call nvim_get_current_buf() each time. I'll do that refactor later.

Need to also re-search() on BufEnter, but that might be a one-liner.

@cshuaimin
Copy link
Owner

I experimented in bind-win branch. I made replace_confirm blocking. Using cfdo works now.

Now I feel that using quickfix is not convenient. I need to populate the qf with a rough grep and type the long cfdo command. And if I run the cfdo command in the ssr float window, everything is messed up.

Initially I thought it would be too slow to search entire project, because we need to open every file in vim, parse the buffer with treesitter and run a query, all in one single thread.

I did some naive benchmark and it's surprising that this process itself is not that slow. The key is to turn off autocmd. I have 400 .ts files in qf, and running a simple replace takes less than 1 second.

noau cfdo lua vim.bo.ft='typescript' require'ssr'.replace_all()

So in my ultimate plan ssr.nvim will support project wide searching. I'll use ripgrep to search a fixed string in the pattern to find possible files.

@llllvvuu
Copy link

type the long cfdo command.

Can use keybinding for this.

So in my ultimate plan ssr.nvim will support project wide searching.

This is great too, very exciting.

@cshuaimin
Copy link
Owner

see also nvim-telescope/telescope.nvim#2611

@cshuaimin cshuaimin mentioned this issue Aug 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants