GnikDroy / projections.nvim

A map to your filesystem
GNU General Public License v3.0
233 stars 8 forks source link

Strange behavior of `restore_hooks` with neo-tree.nvim #11

Closed nyngwang closed 1 year ago

nyngwang commented 1 year ago

Problem

An issue related to neo-tree.nvim again. I think this is not a bug, but the behavior is strange:

Given this function:

my_hook = function ()
  vim.cmd('tabd Neotree close')
  vim.cmd('tabn')
end,

If I pass it only to store_hooks.pre, i.e.:

store_hooks = {
  pre = my_hook,
  post = function () end,
},
restore_hooks = {
  pre = function () end,
  post = function () end,
},

then the neo-tree window will be closed:

https://user-images.githubusercontent.com/24765272/206856576-148983a3-22f6-438f-bd48-12137fe0a50d.mov

However, If I pass it two both store_hooks.pre and restore_hooks.post, i.e.:

store_hooks = {
  pre = my_hook,
  post = function () end,
},
restore_hooks = {
  pre = function () end,
  post = my_hook,
},

then the neo-tree window will be kept:

https://user-images.githubusercontent.com/24765272/206856473-a66f337f-cf5f-461e-baab-f6191662d97c.mov

Expected Result

I expect to set store_hooks.pre only and achieve the result of the second demo.

GnikDroy commented 1 year ago

Hmm. I cannot reproduce this with my current setup. Can you give me the full projections.nvim config as well (including the autocmds and stuff)?

I assume it is DirChangedPre related. Since you are switching to projects with that autocmd, and not using fzf or telescope. Does it work with if you remove that autocmd? Or if you switch project with fzf/telescope instead?

nyngwang commented 1 year ago

To @GnikDroy:

[...] Can you give me the full projections.nvim config as well (including the autocmds and stuff)?

require('projections').setup {
  workspaces = require('project.projects'), -- you will need to change this line
  patterns = {
    'init.lua',
    '.git',
  },
  store_hooks = {
    pre = function ()
      vim.cmd('tabd Neotree close')
      vim.cmd('tabn')
    end,
    post = function () end,
  },
  restore_hooks = {
    pre = function () end,
    post = function ()
      vim.cmd('tabd Neotree close')
      vim.cmd('tabn')
    end,
  },
}
-- auto-store on any leave/quit.
vim.api.nvim_create_autocmd({ 'VimLeavePre', 'DirChangedPre' }, {
  pattern = '*',
  callback = function ()
    require('projections.session').store(vim.loop.cwd())
  end
})
-- auto-restore on start excluding `gm` and `nvim ...`.
vim.api.nvim_create_autocmd({ 'VimEnter', 'DirChanged' }, {
  pattern = '*',
  callback = function ()
    if vim.fn.argc() == 0 then
      require('projections.switcher').switch(vim.loop.cwd())
    end
  end
})
GnikDroy commented 1 year ago

Also I think you are opening nvim in a non-project directory. And then navigating to the project directory.. Is this correct? Want to follow the steps to reproduce this correctly.

nyngwang commented 1 year ago

Also I think you are opening nvim in a non-project directory. And then navigating to the project directory.. Is this correct?

Yes. I started from ~ and gradually navigated to ~/.config/nvim which is a project directory specified in the require('project.projects'). (notice that the autocmd's if vim.fn.argc() == 0 then ... means you have to start neovim without any argument.)

GnikDroy commented 1 year ago

Ok. This seems to be reproducible when using neo-tree from main. But this goes away when I use v2.x. Can you confirm?

nyngwang commented 1 year ago

@GnikDroy It has a more serious problem if I changed it to v2.x. Let me record it.

In the demo, I used the following two keymaps for toggling neotree open/close:

local NOREF_NOERR_TRUNC = { noremap = true, silent = true, nowait = true }
vim.keymap.set('n', '`', function () vim.cmd('Neotree toggle focus') end, NOREF_NOERR_TRUNC)
vim.keymap.set('n', ';', function ()
  if vim.bo.filetype ~= 'neo-tree' then vim.cmd('Neotree focus')
  else vim.cmd('wincmd p') end
end, NOREF_NOERR_TRUNC)

regarding the error message I posted a detailed issue yesterday on neo-tree side: https://github.com/nvim-neo-tree/neo-tree.nvim/issues/651

https://user-images.githubusercontent.com/24765272/206898261-c8b41d2c-b17a-4fd9-a06d-0c366f3144c6.mov

GnikDroy commented 1 year ago

Can you attach the neo-tree config as well? With the barebone config. This doesn't seem to happen.

    -- Unless you are still migrating, remove the deprecated commands from v1.x
    vim.cmd([[ let g:neo_tree_remove_legacy_commands = 1 ]])

    use {
        "nvim-neo-tree/neo-tree.nvim",
        branch = "v2.x",
        requires = {
            "nvim-lua/plenary.nvim",
            "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended
            "MunifTanjim/nui.nvim",
        }
    }

Additionally also attach the full error message produced nui: neo-tree-follow. ......

You can use :Notifications iirc to view these.

At the very least the earlier problem did go away I think, even though a new one popped up. So that's a good start.

nyngwang commented 1 year ago

The error message:

debounce  neo-tree-follow  error:  ...im/site/pack/packer/start/nui.nvim/lua/nui/tree/init.lua:254: Expected Lua number

Since now I'm considering not using neo-tree anymore, here it is:

use {
  'nvim-neo-tree/neo-tree.nvim', disable = false,
  branch = 'main',
  requires = {
    'nvim-lua/plenary.nvim',
    'kyazdani42/nvim-web-devicons',
    'MunifTanjim/nui.nvim',
    {
      's1n7ax/nvim-window-picker', -- "open_window_picker"
      tag = '1.*',
      config = function()
        require'window-picker'.setup({
          autoselect_one = true,
          include_current = false,
          filter_rules = { -- ignore these windows
            bo = {
              filetype = { 'neo-tree', 'notify', 'quickfix' },
              buftype = { 'terminal' },
            },
          },
          other_win_hl_color = '#240046',
        })
      end,
    },
  },
  config = function ()
    vim.g.neo_tree_remove_legacy_commands = 1
    require('neo-tree').setup {
      use_default_mappings = false,
      use_popups_for_input = false, -- more convenient on renaming files.
      close_if_last_window = false,
      enable_git_status = true,
      enable_modified_markers = true,
      git_status_async = true,
      sources = {
        'filesystem',
        'buffers',
        'git_status',
      },
      window = {
        position = 'right',
        auto_expand_width = false, -- use the toggle `toggle_auto_expand_width` instead.
      },
      filesystem = {
        hijack_netrw_behavior = 'open_default',
        follow_current_file = true,
        use_libuv_file_watcher = true, -- no need to refresh the filetree
        async_directory_scan = 'always',
        bind_to_cwd = true, -- sync neo-tree and vim's cwd.
        filtered_items = {
          -- general rules.
          visible = true, -- when true, use grey color and visible.
          force_visible_in_empty_folder = true,
          hide_dotfiles = false,
          hide_gitignored = true,
          show_hidden_count = true,
          -- pattern rules.
          hide_by_pattern = { 'node_modules', '*.meta' }, -- uses glob style patterns
          never_show_by_pattern = { '.DS_Store', '.null-ls_*' },
        },
      },
      event_handlers = {
        {
          event = 'neo_tree_window_after_open',
          handler = function (args)
            if args.position == 'left' or args.position == 'right' then
              vim.cmd('wincmd =')
            end
          end
        },
        {
          event = 'neo_tree_window_after_close',
          handler = function (args)
            if args.position == 'left' or args.position == 'right' then
              vim.cmd('wincmd =')
            end
          end
        },
      },
    }
    vim.keymap.set('n', '`', function () vim.cmd('Neotree toggle focus') end, NOREF_NOERR_TRUNC)
    vim.keymap.set('n', ';', function ()
      if vim.bo.filetype ~= 'neo-tree' then vim.cmd('Neotree focus')
      else vim.cmd('wincmd p') end
    end, NOREF_NOERR_TRUNC)
    vim.api.nvim_create_autocmd({ 'ColorScheme' }, {
      group = 'nvim_ide.lua',
      pattern = "*",
      callback = function ()
        vim.cmd([[
          hi NeoTreeNormal guibg=NONE
          hi NeoTreeNormalNC guibg=NONE
          hi NeoTreeCursorLine guibg=#2b323b
          hi NeoTreeTitleBar guibg=#240046
        ]])
      end,
    })
  end
}
GnikDroy commented 1 year ago

To be fair, you can just remove the function from restore hook, and everything should work normally right?

I just can't seem to be able to reproduce this. So maybe I will give you a complete minimal init.lua so that we are both on the same page.

Different problems from neo-tree with main and v2.x leads me to believe this is not a problem with projections. The only thing that can cause conflict between projections and neo-tree is the DirChangedPre autocmd.

nyngwang commented 1 year ago

To be fair, you can just remove the function from restore hook, and everything should work normally right?

To make it work as I expected, I have to keep this to make neo-tree to not be closed. Kinda counterintuitive:

store_hooks = {
  pre = function ()
    vim.cmd('tabd Neotree close')
    vim.cmd('tabn')
  end,
  post = function () end,
},
restore_hooks = {
  pre = function () end,
  post = function ()
    vim.cmd('tabd Neotree close')
    vim.cmd('tabn')
  end,
},
GnikDroy commented 1 year ago

No worries. It is your choice.

If you want to test this though. This is the most minimal config I could come up with.

Replace your init.lua with this. And

mv ~/.local/share/nvim/site/pack/packer ~/packer.bak Then you can run nvim. And it will setup everything. (Ignore the errors during startup at the very first time.)

After you have completed testing. You can restore you init.lua and the packer folder

vim.g.mapleader = " "

local ensure_packer = function()
    local fn = vim.fn
    local install_path = fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim'
    if fn.empty(fn.glob(install_path)) > 0 then
        print("Packer not found. Installing packer...")
        fn.system({ 'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path })
        if vim.v.shell_error == 0 then
            print("Sucessfully installed packer.")
            vim.cmd([[packadd packer.nvim]])
            return true
        else
            vim.api.nvim_err_writeln("Cannot install packer.")
            vim.api.nvim_err_writeln("Make sure git is installed, and internet connection is stable.")
            return nil
        end
    end
    return false
end

local packer_bootstrapped = ensure_packer()
if packer_bootstrapped == nil then return nil end

require("packer").startup(function(use)
    use("wbthomason/packer.nvim")

    -- SETS UP PROJECTIONS *******************************
    use({
      'gnikdroy/projections.nvim',
      requires = {
          'ibhagwan/fzf-lua',
          'nyngwang/fzf-lua-projections.nvim',
      },
      config = function()
          require("projections").setup({
                -- CHANGE YOUR WORKSPACES ******************************
                workspaces = { { '~/Documents/dev', { ".git" } } },
                patterns = {
                    'init.lua',
                    '.git',
                },
                store_hooks = {
                    pre = function()
                        vim.cmd('tabd Neotree action=close')
                        vim.cmd('tabn')
                    end,
                    post = function() end,
                },
                restore_hooks = {
                    pre = function() end,
                    post = function()
                        vim.cmd('tabd Neotree action=close')
                        vim.cmd('tabn')
                    end,
                },
          })

          -- auto-store on any leave/quit.
          vim.api.nvim_create_autocmd({ 'VimLeavePre', 'DirChangedPre' }, {
              pattern = '*',
              callback = function()
                  require('projections.session').store(vim.loop.cwd())
              end
          })
          -- auto-restore on start excluding `gm` and `nvim ...`.
          vim.api.nvim_create_autocmd({ 'VimEnter', 'DirChanged' }, {
              pattern = '*',
              callback = function()
                  if vim.fn.argc() == 0 then
                      require('projections.switcher').switch(vim.loop.cwd())
                  end
              end
          })

          -- change with fzf_lua
          -- local NOREF_NOERR_TRUNC = { noremap = true, silent = true, nowait = true }
          vim.keymap.set('n', '<Leader>cp', function() require('fzf-lua-p').projects() end,
              { silent = true, nowait = true })
      end
    })

    -- ********* SETS UP NEO-TREE *************
    -- Unless you are still migrating, remove the deprecated commands from v1.x
    vim.cmd([[ let g:neo_tree_remove_legacy_commands = 1 ]])

    use({
        "nvim-neo-tree/neo-tree.nvim",
        branch = "v2.x",
        requires = {
            "nvim-lua/plenary.nvim",
            "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended
            "MunifTanjim/nui.nvim",
        }
    })

    if packer_bootstrapped then require("packer").sync() end
end)
nyngwang commented 1 year ago

@GnikDroy May I ask you which filetree plugin you're using? Or do you recommend one that is stable and easy to config?

GnikDroy commented 1 year ago

I'm using nvim-tree, although I don't use it very often.