Comments (21)
hey @zhimsel i no longer use this plugin, so i'm not as incentivized to go through with the change. plus, i'm not a huge fan of adding options to fix behavior. imo the uses case that inspired the change is a bug, but maybe the way i attempted to fix it was wrong and broke other things, and should be done the right way, not with an option that would further complicate code and confuse users.
from vim-stay.
@fent would you assist me in finding out what happens exactly, bearing with me if I ask stupid questions? When you speak of a “window”, what do you mean, exactly:
- a Vim window as defined in the Vim help, i.e. what is known colloquially as a split;
- or a Vim window from a window manager POV, i.e. a GUI or terminal muxer window?
from vim-stay.
When I speak of a window, I mean a vim spit window.
from vim-stay.
OK, thanks for that. Hmm, last time I looked, BufWinEnter
did not trigger on simply entering a split. The Vim 8.1 help concurs (for what that is worth), stating that it fires:
when the buffer is loaded (after processing the modelines) or when a hidden buffer is displayed in a window (and is no longer hidden).
My point is that though stay creates a view whenever leaving a window (through WinLeave
), it cannot by rights load one when you simply switch to an already open window (because BufWinEnter
does not fire); I tested for that at the time, more than once, so either Vim’s event handling changed dramatically and without warning, or there is something in your usage scenario and / or configuration triggering an unwanted load event.
Could you give me a detailed, step by step scenario of how the issue is reproducibly triggered for you? Starting with how you start (Neo)Vim and including what exact version and patch level you are using on what OS. Please make a note on how exactly you execute each step (what Vim commands you use, or if you use custom mappings to do so, the mapping code).
Also, once you did that, could you please try to reproduce using a minimal configuration, i.e. a vimrc
set up to just run stay and nothing else?
from vim-stay.
so either Vim’s event handling changed dramatically and without warning, or there is something in your usage scenario and / or configuration triggering an unwanted load event.
Could be that the commands I'm using to switch back to the buffer are causing BufWinEnter
to fire, even if the buffer is already loaded, and shown in another split.
These following 3 methods I used to switch back all reproduce the issue
:e#
:b [name]
:e [name]
The docs for BufWinEnter
do say that it's fired when a name is provided to the :split
command, maybe this also applies to the commands I'm using. And maybe the only time this doesn't fire is if you're splitting the currently opened file.
Also, once you did that, could you please try to reproduce using a minimal configuration, i.e. a
vimrc
set up to just run stay and nothing else?
I'm able to reproduce it when I disable all other plugins except vim-stay :/. I also disabled all of mappings and autocmds.
Could you give me a detailed, step by step scenario of how the issue is reproducibly triggered for you? Starting with how you start (Neo)Vim and including what exact version and patch level you are using on what OS.
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled May 17 2018 15:09:32)
macOS version
Included patches: 1-1850
Steps to reproduce
- Open a file with vim
vim file1.txt
- Scroll halfway through file by pressing
ctrl+D
or searching for text I know is halfway - Create a split
:split
- Scroll to top of file to note different position, still on first split
gg
- Open a different file
:e file2.txt
- Switch back to first file
:e#
(or:b file1.txt
or:e file1.txt
) - Note that the position of this split when switching back matches the other split, instead of being at the top of file
from vim-stay.
Hm. So I was able to reproduce the behavior with neovim 0.3.4
using a minimal vimrc (blank, except for loading vim-stay
). I'm not sure what the best course of solution here is, but I'll dig into the code here to see if I can come up with anything.
from vim-stay.
So, thinking about this more, I'm not sure that this isn't desired behavior. Let's think about it this way: when you split the open buffer into 2 windows, it's creating a view port into that file for each window. However, there's still only one buffer. When you then switch one of those two windows to another buffer (by opening another file with :e
), you're destroying it's view port.
As far as I know, vim doesn't keep track of view ports (except for the ones open and visible), only buffers. After opening the second buffer, the first window is no longer viewing the first buffer. When you switch that window back to viewing the first buffer, vim-stay does its job and scrolls to the same place where the second window is. In other words: the most recently-scrolled-to place in that buffer (because the other window is still open and scrolled to that point).
from vim-stay.
So, thinking about this more, I'm not sure that this isn't desired behavior.
If I start vim without vim-stay, this behavior isn't reproduced. And I think it would be more expected from users that vim-stay persist state across windows, even multiple windows of the same buffer.
from vim-stay.
If I start vim without vim-stay, this behavior isn't reproduced.
Well, the whole point of stay is to add behaviour not present in Vim without it, so that is only natural.
And I think it would be more expected from users that vim-stay persist state across windows, even multiple windows of the same buffer.
Actually persisting different states for different windows is both impossible while using Vim view sessions (these map to the file loaded in a buffer, not to a window) and conceptually unsound (what window state do you want when you re-open a file in a fresh editing session; don’t say “the last” – what if there were more than one window open when you last quit?).
@zhimsel is right insofar as this is, technically speaking, expected behaviour, because the usage pattern above is not to switch to a window, but to re-edit a loaded buffer when wanting to switch. Vim recycles the existing window when one does so, so it feels equivalent, but it is not (see the :e
help, which is quite clear about the fact that using it on an open file triggers a fresh edit). Real window switching using Ctrl-W
commands or (heresy) the mouse should not trigger a re-edit.
This being said, I agree with @fent that what happens to them, technically correct or not, feels wrong, thus violating the software design principle of least surprise. An obvious out would be to get rid of theWinLeave
event to save view state (as stated before, replacing BufWinEnter
for view loading is not an option unless we want to strip the plug-in of most of its functionality). However, I am pretty sure I originally put it there for a reason, i.e. BufWinLeave
not firing in all desirable situations.
Could you both try to exercise stay with the lines 85 and 86 of plugin/stay
commented out, trying different split and quit situations (with none, one or more windows on the same buffer open at different positions, for instance) to see if the results are still satisfactory?
If this doesn’t pan out, the aternative solution I can think of ATM would be to check for the number of windows a buffer is shown in, and only save the view when that number is one. The problem with that is that we would need to shim EDIT: turns out I already did that when creating the whole window ID shim autoload module.win_findbuf()
on older Vim versions, or up compatibility requirements …
from vim-stay.
Could you both try to exercise stay with the lines 85 and 86 of
plugin/stay
commented out, trying different split and quit situations (with none, one or more windows on the same buffer open at different positions, for instance) to see if the results are still satisfactory?
After removing this autocmd, I'm still able to reproduce a slightly different error. Now, the view that was previously saved on the buffer is restored when switching back to it.
So for example
- I open
text1.txt
and vim-stay restores the cursor at the middle of the file - Split
- Move to the end of the file
- Open another file
- Switch back to first file
- The cursor is restored to the middle of the file
from vim-stay.
Well, I guess we all know why WinLeave
was there in the first place now. I’ll go ahead and declare this line of thinking abortive.
I am currently tending towards agreeing with Zach and declaring these “errors” expected behaviour: stay is behaving both consistently with Vim’s (convoluted and not altogether intuitive) file handling model and in a technically correct way.
I still am with @fent insofar as that technically correct behaviour runs against superficial expectations, and I‘ll ponder possibilities to alleviate the problem, but I don’t think a poor fit between a certain usage pattern and the plug-in warrants gutting its feature set. Of course, that decision is ultimately @zhimsel’s, not mine …
from vim-stay.
@fent I don’t want to give the impression I am dismissing your concerns lightly, but your usage pattern for buffer activation really is orthogonal to the plug-in’s declared intent, i.e. reliably restoring the last view state whenever a buffer is displayed in a buffer: on startup in any combination of splits and tabs, on unhiding, on cycling through with :xdo
commands. Unluckily, there is no way to differentiate between “this buffer has been loaded into a window and needs its view state reloaded” and “this buffer has been loaded into a window but should not have its view state restored” without knowing user intent.
One way to declare this intent would be to load your reference split into a preview window instead of a regular one, as stay ignores the former. This would at least provide a workaround to your problem until we can think of a better way…
from vim-stay.
I might have an idea how to handle this, thanks to an insomniac night. Because it is thanks to an insomniac night, I ’d like to run this by you both, @fent and @zhimsel.
It seems to me the issue of recognising when there is no need for a saved view state load can be reduced to 1. a buffer does not really enter a window, just technically, firing a misleading BufWinEnter
, 2. the view state of that window consequently does not change.
How about we add a window view state heuristic where, if 1. the window contains the same buffer as before BufWinEnter
fired and 2. other observable view state elements (essentially what winsaveview()
returns, I guess) are unchanged after it fired, we skip view session loading? To my admittedly sleep deprived brain, this sounds like it should resolve the issue while maintaining all of the current feature set, and that without introducing major new corner cases (except maybe a scenario where a real reload is triggered on a buffer with the cursor positioned at the beginning of the file … that one will lose fold state through the reload, as heuristics will fail to detect the change).
Please mull this over and point out the failings in my reasoning; it sounds too good to be entirely true, and I don’t trust the part of my brain that is awake right now …
from vim-stay.
if 1. the window contains the same buffer as before
BufWinEnter
fired
How is this checked? "before" as in, before switching to a different buffer and then switching back?
from vim-stay.
How is this checked?
My current thinking is to do that by setting a window scoped dictionary variable (w:_stay
) whenever we write a view session file storing the buffer name and the window state at this point. We then compare the current values to that before we load a view session.
In your scenario, what would happen would be that:
- You open file A in window 1. stay loads its view session.
- You open file A again in window 2, switching to it in the process. stay writes a view session for file A based on the state of window 1 and loads that in window 2. The status variable for window 1 is set, storing cursor position and the fact it shows file A.
- You change the view state of window 2.
- You switch back to window 1. stay repeats the above steps for window 2; your saved view session for file A now reflects the state of window 2. However, the window status variable for window 1 tells stay neither the buffer nor the cursor position have changed since we were last there. View session loading is skipped.
Any logical errors you can see?
from vim-stay.
Any logical errors you can see?
And by that I mean not just in the scenario I laid out above, but also for alternative usage patterns, e.g. switching via window commands, switching via closing windows, hiding / unhiding buffers, loading from arglist, :xdo
commands, loading multiple copies of a file on Vim start etc.
from vim-stay.
Hm. I'm not opposed to the method @kopischke described above. That seems like a reasonable way of handling this behavior change without overtly affecting "normal" usage.
@fent I can't guarantee I'll be able to implement this any time soon (my work schedule is insane right now), so I'll happily review a PR if you wanted to write one. Otherwise, I'll do my best to write this up when I have time.
from vim-stay.
@fent is this still an issue for you? Sorry it took so long for me to get back around to this, but it's possible I'll have some time very soon to work on this, if it's still relevant.
from vim-stay.
hi @zhimsel , thanks for looking into this again. i am still able to reproduce the steps from this comment above, with the latest version of this plugin, and without making the changes mentioned in the comment.
meanwhile, i've been using the version from this PR and it doesn't have the issue. although i understand that the way it's fixed in the PR may not be the best way to fix it.
from vim-stay.
Got it, thanks. I'll hopefully have some time to hack on this in the next couple weeks.
from vim-stay.
@fent now that it's well past a "couple of weeks" later
As long as there's a clear explanation of what the setting does (and why it may be necessary to use), I'd be happy to merge that.
I'm not saying we can't/shouldn't modify the plugin as @kopischke; I just know I won't have the time necessary to fully test and implement it.
If you're up for creating a PR, I'd be happy to review and merge it. If not, I can make the changes myself fairly soon.
from vim-stay.
Related Issues (20)
- Avoid doubling on Session Load HOT 21
- getbufvar signature incompatible with vim < v7.4 HOT 6
- View session state intermittently gets out of sync with view HOT 15
- Check for sourcing of view session files is too naive HOT 5
- Activates wrong window of multiple buffer windows HOT 24
- View session files override modelines
- Focus gets confused, ends up with no split focused HOT 12
- Error when opening a file (v1.4.0) HOT 2
- vim-stay in neovim produces E484 error when opening new file HOT 11
- view files for files in &backupskip HOT 2
- Error when using BufStayLoadPost autocmd HOT 7
- Slight incompatibility with Vimwiki plugin HOT 8
- Can't create view folder in C:\Program Files\Vim/vimfiles/view HOT 1
- Add command or option to `:CleanViewdir`'s only nonexisting files. HOT 2
- Does this plugin automatically clear out views beyond a certain date HOT 4
- "vim-stay could not read the view session file" for new files HOT 21
- vim-stay error E867: (NFA) Unknown operator '\zh' HOT 21
- Should this plugin save the arglist?
- vim-stay breaks vim-fetch HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vim-stay.