tpope/vim-projectionist

Detect on `VimEnter`

Closed this issue · 2 comments

I was looking for a way to have projectionist do its thing, at startup, and found the following in the repo (taken from: plugin/projectionist.vim):

  autocmd VimEnter *
        \ if get(g:, 'projectionist_vim_enter', 1) && empty(expand('<afile>')) |
        \   call ProjectionistDetect(getcwd()) |
        \ endif

With let g:projectionist_vim_enter = 1 in my .vimrc, I can now just vim into a project, and get my projections loaded just fine. Great!

However, what's the reason behind the second condition in the if statement, i.e. empty(expand('<afile>'))? I am asking because I have got into the habit of starting up vim like: vim ., but that causes the second condition to return false, and skip the projection detection altogether.

I know I can just create a new autocommand of my own, and call ProjectionistDetect() from there; I was just curious about it had been written that way.

Thanks,
M.

tpope commented

It already detects on netrw buffers. You're forcing a second redundant detection. Except you're hard coding getcwd(), which means if you do vim some/dir/, you'll detect for the wrong directory.

Also, g:projectionist_vim_enter = 1 is already the default. That's what that 1 argument to get() is doing.

Turns out I was using an older version of the plugin, i.e. 37f6867; after I updated my clone (so that it included da5847c), detection is now working just fine.

Also, I am not exactly sure what was I on, when I posted this, but clearly something was not quite adding up; so let me try again.

It already detects on netrw buffers.

Right. I did see the following being defined inside the projectionist autogroup:

  autocmd FileType *
        \ if &filetype ==# 'netrw' ? !exists('b:projectionist') :
        \     &buftype !~# 'nofile\|quickfix' |
        \   call ProjectionistDetect(@%) |
        \ endif

However, at least in my case, it did not seem to get past the !exists('b:projectionist') condition: something was setting b:projectionist to {}.

There is a let b:projectionist = {} at the top of ProjectionistDetect, but when I added a debug echom right before it, I could not see anything inside :messages. So I fired vim in verbose mode, i.e. vim -V20vimlog ., and was finally able to see what was going on:

[...]
continuing in FileType Autocommands for "netrw"

Executing FileType Autocommands for "*"
autocommand if &filetype ==# 'netrw' ? !exists('b:projectionist') :     &buftype !~# 'nofile\|quickfix' |   call ProjectionistDetect(@%) | endif

Executing: if &filetype ==# 'netrw' ? !exists('b:projectionist') :     &buftype !~# 'nofile\|quickfix' |   call ProjectionistDetect(@%) | endif
Executing:    call ProjectionistDetect(@%) | endif
calling ProjectionistDetect('')

line 1:   echom "Detect" a:path get(b:, 'projectionist', 'nope')
Detect  nope
line 2:   let b:projectionist = {}
line 3:   unlet! b:projectionist_file
line 4:   if empty(a:path) || &l:buftype !~# '^\%(nowrite\|acwrite\)\=$'
line 5:     return
ProjectionistDetect returning #0
[...]

The plugin was invoking ProjectionistDetect with @%, but since that is '', the function would early return, leaving {} inside b:projectionist.

Note: I am not sure why the message was not getting logged; maybe plugins are not allowed to call echom that early during vim start up? Don't know.

You're forcing a second redundant detection.

Right: I did not realize that a detection had already happened! That's why I was desperately trying to trigegr a new one, but clearly I had no idea what I was doing.

Except you're hard coding getcwd(), which means if you do vim some/dir/, you'll detect for the wrong directory.

I see! Now I think I also understand what the empty(expand('<afile>')) condition inside the VimEnter autocommand is for: is to prevent both the netrw autocommand, and the VimEnter one, from accidentally triggering a detection for the same buffer.

Also, g:projectionist_vim_enter = 1 is already the default. That's what that 1 argument to get() is doing.

I am not exactly sure what was I on, when I posted this

Anyways, thanks a lot!