echasnovski / mini.nvim

Library of 40+ independent Lua modules improving overall Neovim (version 0.8 and higher) experience with minimal effort
MIT License
4.54k stars 175 forks source link

mini.map: bad interactions with sessions #851

Closed dimhatz closed 2 months ago

dimhatz commented 2 months ago

Contributing guidelines

Module(s)

mini.map

Description

Two issues regarding mini.map's interactions with sessions (possibly related).

Neovim version

0.9.5 (windows 10, alacritty)

Steps to reproduce

First issue

mini.map is not shown with VimEnter autocmd:

  1. Have a session manager (e.g. mini.sessions or persisted.nvim) configured to auto-read the previous session at nvim's start
  2. Set require('mini.map').open() to be called inside VimEnter autocmd (as per documentation)

Expected behavior: the scrollbar is shown Actual behavior: the scrollbar is missing.

Once nvim has started, the subsequent manual calls to require('mini.map').open() result in scrollbar showing. Also, the scrollbar is shown, when we configure it to be called from UIEnter, SessionLoadPost or mini.sessions's post-read hook.


Second issue

mini.map's start causes incorrect saving of resized split windows in the session.

  1. Start without loading any sessions
  2. Open a file
  3. <C-w>v to vertically split (no need to open a second file)
  4. Using a mouse, resize the left window to be visibly smaller than the right (or use vim.cmd('vertical resize 40'))
  5. require('mini.map').open()
  6. Save the session
  7. Quit with :qa
  8. Open nvim and restore session

Expected behavior: the session is restored with split windows resized just like before quitting Actual behavior: the session is restored with windows split evenly.

In the above steps, when opening minimap is skipped, we have the expected behavior.

After diffing the 2 saved session files, the correctly saved session has

exe 'vert 1resize ' . ((&columns * 144 + 115) / 230)
exe 'vert 2resize ' . ((&columns * 85 + 115) / 230)

at 2 points in the session file. Meanwhile in the buggy session file, those 2 points are replaced with

wincmd =

Attaching the session files, just in case.

nvim_session_ok.txt nvim_session_bug.txt

All of the above were produced with minimal init.lua, containing only lazy and mini.nvim,:

  {
    'echasnovski/mini.nvim',
    lazy = false,
    priority = 1000,
    config = function()
      require('mini.ai').setup({ n_lines = 500 })

      local mini_map = require('mini.map')
      mini_map.setup({})

      local session_file = '.nvim_session'
      require('mini.sessions').setup({
        autoread = false,
        autowrite = true,
        file = session_file, -- local session file
        directory = '', -- directory for global sessions, we disable it
      })

    end,
  },

Expected behavior

See above

Actual behavior

See above

echasnovski commented 2 months ago

Thanks for the detailed issue!


Issue 1

Once nvim has started, the subsequent manual calls to require('mini.map').open() result in scrollbar showing. Also, the scrollbar is shown, when we configure it to be called from UIEnter, SessionLoadPost or mini.sessions's post-read hook.

It is the suggested approach to handle this situation. Most of session plugins (at least 'mini.sessions') ensure that session is loaded with a clean buffer list. This results into 'mini.map' window being removed during session loading.

So it is more up to the user to set it up so that 'mini.map' window is not closed. This can be done either by using other events as you describe. Another approach is to set up VimEnter autocommand of 'mini.map' after the 'mini.sessions' one. So something like this works:

require('mini.sessions').setup({ autoread = true })
require('mini.map').setup()
vim.api.nvim_create_autocmd('VimEnter', { callback = function() require('mini.map').open() end })

Issue 2

This doesn't look like a 'mini.map' issue, but how built-in sessions work. This can be verified by reproducing without 'mini.map' but a general floating window: instead step 5 require('mini.map').open() execute the (scary looking but pretty straightforward) command:

vim.api.nvim_open_win(vim.api.nvim_create_buf(false, true), false, { relative = 'editor', row = 10, col = 10, height = 10, width = 10 })

This will have the same effect as you describe. If this bothers you too much, I'd suggest creating an issue in neovim/neovim which does not use any plugins (so :mksession and :source instead of 'mini.sessions' functions).


Closing as both issues are for expected behavior.

dimhatz commented 2 months ago

Excellent! Thank you very much, Evgeni, for the detailed explanation!

Indeed, it was the order of setups that caused VimEnter not to work. Regarding the other issue, I will research some more and will likely open an issue in neovim, if it does not already exist. Thanks for pointing me in the right direction!

Keep up the good work!

dimhatz commented 2 months ago

Posting a workaround, until the neovim issue is properly investigated and fixed:

      vim.api.nvim_create_autocmd('ExitPre', {
        group = vim.api.nvim_create_augroup('minimap-exit-before-session-save', {}),
        desc = 'Exit minimap before session save',
        callback = function()
          mini_map.close()
        end,
      })

This makes neovim create correct sessions, with the resized splits preserved