In MacVim, why can't I goto a file with the gf command when having "filetype plugin indent on"?

Viewed 62

I am using MacVim Version 8.2.3455 (172)

I have a ruby file vim_test.rb with one line of code.

require 'vim_test/core'

The vim_test/core.rb file exists and has a single comment.

I do the following:

  1. I navigate to the directory containing the vim_test.rb file and start MacVim with mvim vim_test.rb

  2. I run the :set suffixesadd+=.rb command.

  3. I put my cursor on the file specified by the require directive (vim_test/core) and press gf.

I get this error E345: Can't find file "vim_test/core.rb" in path.

To fix this, I have to comment out the following line in my .vimrc, save it and restart MacVim:

" filetype plugin indent on

Now when I follow the exact same steps as before, I can jump to the vim_test/core.rb file.

Is there any way I can have filetype plugin indent on in my .vimrc and also use gf to goto a file specified by the require directive?

Thank You.

1 Answers

:help gf works by searching for the filename under the cursor in the directories listed in the :help 'path'.

By default, the value of path is .,/usr/include,,, which means that Vim is going to search in:

  • the directory of the current file, that's the .,
  • /usr/include, which is of no use to you,
  • the working directory, that's the ,,.

Which works perfectly well with your sample.

Now, filetype plugin indent on tells Vim to enable filetype detection, filetype plugins, and filetype-specific indenting. The problem, here, is that the Ruby filetype plugin tries hard to locate all the places on your system that might hide Ruby libs and then sets the path option to that list. For example, this is what I get on my machine (YMMV):

/Library/Ruby/Site/2.3.0,/Library/Ruby/Site/2.3.0/x86_64-darwin18,/Library/Ruby/Site/2.3.0/universal-darwin18,/Library/Ruby/Site,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby/2.3.0,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby/2.3.0/x86_64-darwin18,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby/2.3.0/universal-darwin18,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/x86_64-darwin18,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/universal-darwin18

This is probably useful but it lacks the . that allows searching in the directory of the current file and the ,, that allows searching in the working directory.

In fact, the function that returns the value to be used for path does something very weird: if the current global value of path isn't the default value, it appends the list of directories above but, if the global value is the default value, it simply returns the list above. I can't quite wrap my head around that reasoning.

Moreover, the same ftplugin maps gf to some clever function that makes it even more complicated and unintuitive.

The only workaround I can see is to change your global path in your vimrc in such a way that the Ruby ftplugin appends the list above to the existing path value instead of overriding it with that list.

The following snippet:

set path+=,,

gets me the following path in a Ruby buffer:

.,/usr/include/,,,,,/Library/Ruby/Site/2.3.0,/Library/Ruby/Site/2.3.0/x86_64-darwin18,/Library/Ruby/Site/2.3.0/universal-darwin18,/Library/Ruby/Site,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby/2.3.0,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby/2.3.0/x86_64-darwin18,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby/2.3.0/universal-darwin18,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/vendor_ruby,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/x86_64-darwin18,/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/universal-darwin18

which makes gf work as expected.

But such a hack shouldn't be needed in the first place. I think an issue is in order.

Related