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

refactor(change): do API changes to buffer without curbuf switch #24824

Merged
merged 1 commit into from
Aug 26, 2023

Conversation

bfredl
Copy link
Member

@bfredl bfredl commented Aug 21, 2023

warning: early working-on-the-train-stream-of-conciousness draft.

Most of the messy things when changing a non-current buffer is not about the buffer, it is about windows. In particular, it is about curwin.

When editing a non-current buffer which is displayed in some other window in the current tabpage, one such window will be "borrowed" as the curwin.
But this means if two or more non-current windows displayed the buffer, one of them will be arbitrarily selected to be treated differently. this is not desirable.

This branch currently disables all such borrowed-curwin logic, but this likely breaks some useful expectations which should be fixed instead by applying these window checks to all non-current windows (I am looking at you, fix_cursor() ) Done and added tests

@github-actions github-actions bot added the refactor changes that are not features or bugfixes label Aug 21, 2023
@bfredl bfredl force-pushed the nocurbuf branch 8 times, most recently from 5a58c7e to 469eac4 Compare August 25, 2023 09:32
@bfredl bfredl marked this pull request as ready for review August 25, 2023 09:55
@bfredl bfredl force-pushed the nocurbuf branch 2 times, most recently from d487c08 to 4ebff85 Compare August 26, 2023 08:48
src/nvim/api/buffer.c Outdated Show resolved Hide resolved
@bfredl bfredl force-pushed the nocurbuf branch 3 times, most recently from e6eeb46 to 0081549 Compare August 26, 2023 09:58
Most of the messy things when changing a non-current buffer is
not about the buffer, it is about windows. In particular, it is about
`curwin`.

When editing a non-current buffer which is displayed in some other
window in the current tabpage, one such window will be "borrowed" as the
curwin. But this means if two or more non-current windows displayed the buffers,
one of them will be treated differenty. this is not desirable.

In particular, with nvim_buf_set_text, cursor _column_ position was only
corrected for one single window. Two new tests are added: the test
with just one non-current window passes, but the one with two didn't.

Two corresponding such tests were also added for nvim_buf_set_lines.
This already worked correctly on master, but make sure this is
well-tested for future refactors.

Also, nvim_create_buf no longer invokes autocmds just because you happened
to use `scratch=true`. No option value was changed, therefore OptionSet
must not be fired.
@bfredl bfredl merged commit 1bdcb9a into neovim:master Aug 26, 2023
14 checks passed
@sandersantema
Copy link

sandersantema commented Aug 26, 2023

Fyi this commit seems to break telescope, the list of results is not always shown and only reappears after selecting another entry in the list. I really don't understand enough about either this commit or telescope to say whether this is a new bug caused by this commit or something which should be fixed by telescope, which might rely on old behavior from before this commit. But with the ol' reliable git bisect I could confirm the problem with telescope started with this commit. Is this the right place for a message like this or would it be better fit as a separate issue? Good to know for the future :)

If my explanation of the problem in text wasn't clear enough here are some screenshots; in the neovim repo require('telescope.builtin').find_files() for instance shows the following for the search afad:
image
As you can see by the counter 25 results should be displayed but aren't.
And only shows the following after selecting result:
image

@bfredl
Copy link
Member Author

bfredl commented Aug 26, 2023

Hmm it seems to behave correctly but there are some missing redraws, leading to the glitches you describe. it seems to depend on the picker type, like find_files is borked but live_grep seems to look just fine.

@petobens
Copy link

I reported the same thing in the telescope repo nvim-telescope/telescope.nvim#2667

Also cmp completion seems broken now since we cannot move across the list of candidates in the popup window:

cmp

@rhcher
Copy link
Contributor

rhcher commented Aug 26, 2023

Meet strange thing with this PR, when I save a buffer, the first line will disappear. I also can't see this change in undo tree.

@bfredl
Copy link
Member Author

bfredl commented Aug 26, 2023

The cmp issue is likely the same redraw issue. the actual item is navigated in curbuf, but the popup menu (re-implemented as a float) is not redrawn.

@bfredl
Copy link
Member Author

bfredl commented Aug 26, 2023

@rhcher can this also be reproduced with --clean ? if not, I need minimal config to reproduce.

@bfredl
Copy link
Member Author

bfredl commented Aug 26, 2023

Locally reverting just this part seems to fix the telescope issue for me:

diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index b278a21d8e..4179ae40b8 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -912,17 +912,14 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
     goto fail;
   }
 
-  // Only strictly needed for scratch, but could just as well be consistent
-  // and do this now. buffer is created NOW, not when it latter first happen
-  // to reach a window or aucmd_prepbuf() ..
-  buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
-
   if (scratch) {
-    set_string_option_direct_in_buf(buf, "bufhidden", -1, "hide", OPT_LOCAL, 0);
-    set_string_option_direct_in_buf(buf, "buftype", -1, "nofile", OPT_LOCAL, 0);
-    assert(buf->b_ml.ml_mfp->mf_fd < 0);  // ml_open() should not have opened swapfile already
-    buf->b_p_swf = false;
-    buf->b_p_ml = false;
+    aco_save_T aco;
+    aucmd_prepbuf(&aco, buf);
+    set_option_value("bufhidden", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL);
+    set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL);
+    set_option_value("swapfile", BOOLEAN_OPTVAL(false), OPT_LOCAL);
+    set_option_value("modeline", BOOLEAN_OPTVAL(false), OPT_LOCAL);  // 'nomodeline'
+    aucmd_restbuf(&aco);
   }
   return buf->b_fnum;

I'll debug a bit more, but if I don't find something we can revert just that while keep the bulk of the changes, for now.

@rhcher
Copy link
Contributor

rhcher commented Aug 26, 2023

@rhcher can this also be reproduced with --clean ? if not, I need minimal config to reproduce.

That can not be reproduced with --clean, and it related to noice.nvim
I reproduced with this minimal config:

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  "folke/tokyonight.nvim",
  {
    "folke/noice.nvim",
    event = "VeryLazy",
    opts = {},
    dependencies  = {
      "MunifTanjim/nui.nvim",
    },
  },
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")

Steps To Reproduce

  1. touch test.c
  2. add something in test.c file
  3. open test.c nvim -u repro.lua
  4. the first line disappear
  5. If I add first line back, when I save buffer, it also disppear.

I don't know if its an nvim issue or a noice.nvim issue, all I can determine is that it comes after this pr. If you're sure it's an nvim related issue, then I'd be happy to create an issue to track this down.

@bfredl
Copy link
Member Author

bfredl commented Aug 26, 2023

correction: the telescope issue was rather about topline. for some reason it is being adjusted differently for a non-current window.

@sandersantema @petobens if you like you could test this branch #24889

@catgoose

This comment was marked as resolved.

@sandersantema
Copy link

@bfredl #24889 did the trick! Thanks.

@gegoune
Copy link
Sponsor

gegoune commented Aug 27, 2023

correction: the telescope issue was rather about topline. for some reason it is being adjusted differently for a non-current window.

if you like you could test this branch #24889

Tested it with telescope and cmp. Telescope issue is fixed, but cmp remains broken.

@SleepySwords
Copy link
Contributor

SleepySwords commented Aug 27, 2023

This seems to make nvim crash for me on line 3220 of undo.c.

This patch seems to fix it for me, idk if this is actually right tho

diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 552120d4a..52bab2d2a 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -3211,12 +3211,12 @@ u_header_T *u_force_get_undo_header(buf_T *buf)
     // Undo is normally invoked in change code, which already has swapped
     // curbuf.
     // Args are tricky: this means replace empty range by empty range..
-    u_savecommon(curbuf, 0, 1, 1, true);
+    u_savecommon(buf, 0, 1, 1, true);
 
     uhp = buf->b_u_curhead;
     if (!uhp) {
       uhp = buf->b_u_newhead;
-      if (get_undolevel(curbuf) > 0 && !uhp) {
+      if (get_undolevel(buf) > 0 && !uhp) {
         abort();
       }
     }

bfredl added a commit to bfredl/neovim that referenced this pull request Aug 27, 2023
…ctor

The change in neovim#24824 HASH was not a regression, however it was an
incomplete change. Unfortunately some common plugins come to depend on
this exising self-inconsistent behavior. These plugins are going to need
to update for 0.10

nvim_buf_set_lines used to NOT adjust the topline correctly if a buffer
was displayed in just one window. However, if displayed in multiple
windows, it was correctly adjusted for any window not deemed the
current window for the buffer (which could be an arbitrary choice if the
buffer was not already current, as noted in the last rafactor)

This fixes so that all windows have their topline adjusted. The added
tests show this behavior, which should be the reasonable one.
@bfredl
Copy link
Member Author

bfredl commented Aug 27, 2023

@SleepySwords the fix is indeed correct. added to the same PR.

@bfredl
Copy link
Member Author

bfredl commented Aug 27, 2023

Unfortunately the first "regression fix" in #24889 was not correct. The (old master) behavior of topline adjustment was invalid and self-inconsistent, but unfortunately some plugins like telescope has come to depend on this incorrect behavior. The added test cases show what I think should be the correct behavior, i e topline is kept on the same line (i e the one with the same contents), even if its number changed. The fix was yet incomplete tho, and there is thus another change now in the PR which might help regressions in other plugins.

Regardless, the behavior currently in 0.9 (and master two days ago) is self-inconsistent (the third added test case, which multiple split windows into the same buffer, already did the "new" correct behavior), and has to be changed.

bfredl added a commit to bfredl/neovim that referenced this pull request Aug 27, 2023
…ctor

The change in neovim#24824 0081549 was not a regression, however it was an
incomplete change. Unfortunately some common plugins come to depend on
this exising self-inconsistent behavior. These plugins are going to need
to update for 0.10

nvim_buf_set_lines used to NOT adjust the topline correctly if a buffer
was displayed in just one window. However, if displayed in multiple
windows, it was correctly adjusted for any window not deemed the
current window for the buffer (which could be an arbitrary choice if the
buffer was not already current, as noted in the last rafactor)

This fixes so that all windows have their topline adjusted. The added
tests show this behavior, which should be the reasonable one.
willothy added a commit to willothy/which-key.nvim that referenced this pull request Sep 11, 2023
problem: as of neovim/neovim#24824 buf_set_lines adjusts topline differently, which breaks scrolling in the which-key menu.
solution: save and restore view when rendering to ensure that the render does not change scroll position.

fixes folke#515
willothy added a commit to willothy/which-key.nvim that referenced this pull request Sep 11, 2023
problem: as of neovim/neovim#24824 buf_set_lines adjusts topline differently, which breaks scrolling in the which-key menu.
solution: save and restore view when rendering to ensure that the render does not change scroll position.

fixes folke#515
folke pushed a commit to folke/which-key.nvim that referenced this pull request Jun 6, 2024
problem: as of neovim/neovim#24824 buf_set_lines adjusts topline differently, which breaks scrolling in the which-key menu.
solution: save and restore view when rendering to ensure that the render does not change scroll position.

fixes #515
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor changes that are not features or bugfixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants