-
-
Notifications
You must be signed in to change notification settings - Fork 226
add multi window support #419
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
Conversation
Oh why the formatting is changed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested yet but overall the approach & feature looks good to me.
lua/treesitter-context.lua
Outdated
autocmd({ 'WinScrolled' }, function() | ||
for winid, bufnr_map in pairs(require('treesitter-context.render').get_bufnr_maps()) do | ||
update(bufnr_map.bufnr, winid) | ||
end | ||
end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we updating all the windows on scroll? Shouldn't we be only updating the scrolled one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commands such as split will trigger winscroll, and every window width should be adjusted to new width, how should we differentiate scroll and resizing? Should I use winresized instead? Ideally if user create a new split, I’d like to close all of them and reopen again to avoid position flashing, will try again.
There is one thing I can't understand iShot_2024-03-20_12.35.51.mp4but in kitty(as well as wezterm), when new window created, the position becomes wrong(if I focus the window again, position will be correct): iShot_2024-03-20_12.37.36.mp4Can you help with me what causes the difference? |
@romgrk @lewis6991 Hello could you test this? The only issue remains is the attached[buf] I'm not sure how to change it, since now we have multiple windows. Edit: I found local update = throttle(function()
local bufnr = api.nvim_get_current_buf()
local winid = api.nvim_get_current_win() these two lines have race conditions that autocmd({ 'WinScrolled', 'BufEnter', 'WinEnter', 'VimResized' }, function()
vim.defer_fn(function()
update()
end, 1)
end) |
For your issue, I don't like adding an async delay there, even if just |
lua/treesitter-context.lua
Outdated
do | ||
for _, window_id in pairs(window_ids) do | ||
if stored_winid == window_id then | ||
throttle(function() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work for anonymous functions since it is only ever called once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe no need for throttle? Just directly calling
open() to update state, and the same for WinEnter, since some plugin may open many windows in a short time , we should instantly trigger open().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling throttle like this (throttle(...)()
) doesn't work. It needs to be.
local f = throttle(...)
f()
f() -- throttled
Not:
throttle(...)()
throttle(...)() -- not throttled!
return buf | ||
--- @param winid integer? | ||
local function win_close(winid) | ||
vim.schedule(function() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code doesn't show why this is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I move win_close to top since store_context needs to call close if underline buffer changed
lua/treesitter-context.lua
Outdated
@@ -155,7 +198,18 @@ function M.enable() | |||
|
|||
autocmd({ 'BufLeave', 'WinLeave' }, close) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe bufleave and winleave is no longer needed, winleave can be replaced by winclosed, and bufleave's close behavior is expressed in store_contest's win_close call.
relative = 'win', | ||
width = width, | ||
height = height, | ||
row = 0, | ||
col = col, | ||
}) | ||
end | ||
return winid | ||
return float_winid | ||
end | ||
|
||
--- @param winid integer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
textoff is inconsistent too. In my case it will return 4 and after next update time it will return 8, cause window position to flash(mark the wrong line number, two lines below)
@romgrk hello do you have time to review? |
lua/treesitter-context/render.lua
Outdated
if window_ctx.bufnr == bufnr then | ||
return window_ctx | ||
else | ||
-- Unserline buffer have changed, close it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I'll run the PR in my config to test it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wrapping WinEnter in a vim.schedule now to get new bufnr. It should be ready to merge, after 3 weeks of use I see no problem.
But I have not find a reliable way to get buffer information after WinEnter is triggered, the solution above is not perfect if you open many windows at the same time, since vim.schedule's execute time is uncertain, as the origin comment says. But it is still a improvement since there would not be some file buffer unrelated windows to show previous buf's context.
Yeah sometimes events are ugly. Maybe this would be better fixed in neovim directly, if it's unreliable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, I remove WinEnter since it is not reliable, and indeed there are no need for that autocmd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wdym by not needed? I'm observing a few cases where the context doesn't show up, wondering if it's connected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think BufEnter is more general than WinEnter, since there must be a loaded buffer to show context, which case context don't show up? Could you try to add WinEnter to see if it still doesn't show up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you observed similar behavior? Can you do the changes on this PR? Could you also explain why it was needed to change the events we listen to?
Also I've been using for 2 weeks and I love how much less flickering there is from the context window opening/closing on every window change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you observed similar behavior
No, but I have context window opened in none-file buffers if I just keep WinEnter unchanged as is.
I have a keymap that first enter right "reference list", then immediately move focus to the preview window, and a workaround is wrapping callback in vim.schedule to get the right buffer number(but it is not always right theoretically that's why I delete it), If you prefer keep WinEnter I'll add it back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a preference, whatever works is best, I'm just wondering if changing the events might have caused the few cases I saw where the window wasn't appearing. I'm always very confused with autocmds so I couldn't tell you which combination of BufEnter/WinEnter/BufWinEnter is right for our use-case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, have added it back.
WinEnter may mess up windows and there is no need for that I think
@romgrk @lewis6991 Hello any chance this get merged? |
Code-wise the PR looks good, but I've been running it for a while and I keep seeing cases where the context window(s) don't get opened. It doesn't bother me much personally but I don't have enough confidence in it to give it a green light, and I also haven't had time to debug the code. Have you seen any such cases? |
Hmm no problem for me so far, works seamless( I mainly use nightly), if users encounter the same problem, they may provide some information and we can fix it. I think whenever you move cursor, context will open if it didn't open before. |
@romgrk @lewis6991 Hi, could you please clarify the reason this PR was closed? I have developed my own implementation of multi-window support a couple of months ago, and I have been using it extensively since then. My experience has been very positive; it has performed flawlessly without any issues related to multiple windows or resizing. Additionally, I have conducted performance testing using flamegraphs, and I have observed that treesitter-context consumes approximately 7% of processing time, which appears to be within a reasonable range. I believe that multi-window support is a highly valuable feature, especially for working with large codebases efficiently. I think it would greatly benefit other users as well. If it would be helpful, I am more than happy to share my implementation and potentially create a new PR. |
Because I tried to rebase but there are too many commits behind 😄 I planned to open a new pr but forgot it, it will be awesome if you are happy to create a pr. |
Not enough time to review/debug the few minor issues that appeared at the time. I'd be happy to see this feature, I just don't have much time to put into FOSS right now, and @lewis6991 also needs to sign off on it as he's the more active maintainer at the moment. But please open a PR if you have one that's production ready. |
This will track a global map that map winid to {bufnr,gut_bufnr, context_bufnr,gutter_winid,context_winid} and dynamically clean up and add new one, I'm new to lua so thanks for your advice. Currently WinScroll autocmd seems don't adjust context window position and I can't figure out why.