airblade / vim-rooter

Changes Vim working directory to project root.
MIT License
1.23k stars 72 forks source link

Changing directory from netrw does not call Rooter #134

Closed ckangnz closed 1 year ago

ckangnz commented 1 year ago

I'm pretty sure this used to work previously as it has been my favourite way of navigating one project to another.

Say you have project folders like this and both Project_A and Project_B has .git so Rooter can find the root of the project.

~/code/Project_A/index.html ~/code/Project_B/index.html

When you are on index.html file on Project_A, and hit :pwd, I can confirm that it will returns ~/code/Project_A.

When I :Explore to go to netrw file view, and navigate to ~/code/Project_B without opening index.html, it used to pick up the root as it lands inside the directory. So even without having to open a file in Project_B, when I'm in the directory I could open fzf or telescope and navigate to my desired file from the new project.

TLDR;

./code
   |- Project_A
      |-.git
      |-index.html <----- 1. You're here. :pwd will say (~/Project_A)
   |- Project_B <-------2. Move to here via netrw then run :pwd. It still says (~/Project_A)
      |-.git
      |-index.html
  1. Open Project_A/index.html. Hit :pwd. Confirm ~/code/Project_A
  2. :Explore -> - to go to parent folder -> Enter Project_B

Actual : :pwd says ~/code/Project_A Expected : :pwd says ~/code/Project_B

airblade commented 1 year ago

I'm pretty sure this used to work previously

Any idea roughly how long ago?

ckangnz commented 1 year ago

@airblade i think at least a few weeks ago it used to work..? Back in August at least? I've been migrating vim->neovim and have been updating my plugins a bit often recently so can't exactly tell when it used to work

ckangnz commented 1 year ago

Also i have my .vimrc symlinked from .vim.

.vim/.vimrc symlinked to ~/.vimrc

When I open .vimrc, it used to pick up the git root of ~/.vim This isn't working anymore as well

airblade commented 1 year ago

When I open .vimrc, it used to pick up the git root of ~/.vim This isn't working anymore as well

Works for me. The test passes too.

Can you reproduce this when vim-rooter is your only plugin?

Also do you have any vim-rooter configuration?

airblade commented 1 year ago

i think at least a few weeks ago it used to work..? Back in August at least?

The last change to the plugin was in January. So something else has changed for you.

ckangnz commented 1 year ago

I just tested without any plugins but it still behaves the same.

My newest plugins i installed were telescope/ treesitter/ lualine as I was migrating from vim -> nvim. But funny enough, my vim is behaving exactly the same as nvim. I tried disabling all of the new plugins and it still doesn't fix the issue.

I might have added a few general settings but commenting them out still doesn't resolve the issue.

it's as if the Rooter() is not called automatically when i navigate to the folder. When I call it manually, it works fine. Either Rooter() is not called automatically, or something else is being called after to override it.

ckangnz commented 1 year ago

here's my rooter config

"---------VIM-ROOTER: airblade/vim-rooter
let g:rooter_silent_chdir = 1
let g:rooter_patterns = ['.git', 'package.json', '*.sln', 'appsettings.json']
let g:rooter_change_directory_for_non_project_files = 'current'
ckangnz commented 1 year ago

and here's an additional change i added in my autogroup

augroup LuaPath
  au!
  au BufRead,BufEnter * setlocal suffixesadd^=.lua
  au BufRead,BufEnter * setlocal suffixesadd^=init.lua
  au BufRead * let &l:path .= ','.stdpath('config').'/lua'
augroup END

This was added so that i could navigate to the lua file I wanted in require somefile.lua by gf

augroup autosourcing
  au!
  if exists('g:neovide') || has('nvim')
    au BufWritePost $HOME/.vimrc source $MYVIMRC
  endif
  au BufWritePost $MYVIMRC source $MYVIMRC
  au BufWritePost $HOME/.vim/.config/nvim/* source $MYVIMRC

  au BufNewFile,BufRead *.ejs set filetype=js
  au BufNewFile,BufRead *.vue,*.hbs set filetype=html
  au BufNewFile,BufRead *.jsx set filetype=javascriptreact
  au BufNewFile,BufRead *.tsx set filetype=typescriptreact

  au BufRead,InsertEnter * setlocal cursorline
  au VimEnter,InsertLeave * setlocal cursorline

  au BufRead * setlocal includeexpr=substitute(v:fname,'\\.','/','g') <--- This was added recently
augroup END
airblade commented 1 year ago

Maybe it's a change in Netrw. What vim and nvim versions are you using?

airblade commented 1 year ago

it's as if the Rooter() is not called automatically when i navigate to the folder. When I call it manually, it works fine. Either Rooter() is not called automatically, or ....

Rooter is called automatically on BufEnter:

https://github.com/airblade/vim-rooter/blob/4f52ca556a0b9e257bf920658714470ea0320b7a/plugin/rooter.vim#L67

The first thing it does is determine whether it should try to change the directory (or "activate"). When you are looking at a directory, with the default configuration, it will activate when the expanded filename is empty or ends in a /:

https://github.com/airblade/vim-rooter/blob/4f52ca556a0b9e257bf920658714470ea0320b7a/plugin/rooter.vim#L100

If it does, the code sets the buffer variable b:rootDir and then changes directory.

The next time Rooter runs in that buffer, it sees b:rootDir and just changes to that directory.

In your case my guesses are:

I had a look at what changed in Netrw between 1 January 2023 and now. Unfortunately it was a lot; and Netrw is large and complicated; so I gave up trying to figure out whether a Netrw change is the culprit.

ckangnz commented 1 year ago

I currently use vim-vinegar (which i believe is same as Netrw). I've updated all vim/nvim all plugins to the latest version so something may have been updated.

My vim version is :

VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Sep 02 2023 19:52:05)

and my neovim version is :

NVIM v0.9.2
Build type: Release
LuaJIT 2.1.0-beta3

I tried everything, restoring my git history as well but no luck. Whenever I change directory, I either have to hit ':Rooter' or ':Gcd' (tpope's fugitive command to cd into root directory).

At this point, I have to run ':Rooter' manually whenever I enter a directory via netrw. Otherwise I can just open any file in the project, which triggers :Rooter.

It would be nice to have this working again :(

airblade commented 1 year ago

I have done some digging and the problem occurs when the code determines the directory of the current buffer, in this case a netrw directory listing.

https://github.com/airblade/vim-rooter/blob/4f52ca556a0b9e257bf920658714470ea0320b7a/plugin/rooter.vim#L213

Surpisingly fn, the current filename / path, is empty. I would expect it to be the full path of the directory being listed by netrw.

Given that the buffer name is annoyingly empty, I thought instead that I could detect that we're in a netrw directory listing and then simply call getcwd(). But I can't figure out how to determine it's a netrw directory listing: the filetype has not been set – I would expect it to be "netrw" – and there are no netrw-related buffer variables.

I have asked on vi.stackexchange so hopefully a kind soul will help!

ckangnz commented 1 year ago

Thanks for looking into this @airblade . I'm assuming this isn't the edge case just for me because I just set up my environment completely new on another pc and i still have this issue. I mean.. i'm still using the same zsh/vim configuration though.

Is this also an issue after updating on your machine as well?

Thanks :)

airblade commented 1 year ago

It's not just you, netrw doesn't work with vim-rooter for me either. I don't use netrw so I never noticed before.

I use vim-dirvish which works perfectly with vim-rooter.

airblade commented 1 year ago

This fixes it for me:

let g:netrw_keepdir=0

From netrw's help:

  *g:netrw_keepdir*     =1 (default) keep current directory immune from
                   the browsing directory.
                =0 keep the current directory the same as the
                   browsing directory.
                The current browsing directory is contained in
                b:netrw_curdir (also see |netrw-cd|)

It seems that netrw always wants to control the working directory, regardless of what vim-rooter does. Once the directory listing has displayed, and after vim-rooter has run, netrw sets the working directory to either the original working directory (g:netrw_keepdir == 1) or the directory being listed (g:netrw_keepdir == 0).

Neither is quite right for us but the latter is better than the former. However it means that if you browse with netrw to a subdirectory of a root directory, netrw will set the working directory to that subdirectory.

Personally I find netrw annoying and much prefer other directory browsing plugins, none of which has this problem.

ckangnz commented 1 year ago

That's awesome!! It won't matter if netrw change directory to the subdirectory because when you open a file within the subdirectory, rooter will change the root. Thank you so much!!