5

I like autochdir a lot, but it breaks my tag browsing, e.g.:

main.c:

int main(){}

d/a.c:

int main(){}

vimrc:

set nocompatible
set autochdir
set tagrelative
set tags=tags;

tags:

main    d/a.c   /^int main() {}$/;"     f
main    main.c  /^int main() {}$/;"     f

generated with ctags -R.

Now:

vim -u vimrc main.c
:tag main

Then this works fine and goes to d/a.c:

:tn

However this fails as it searches for main.c:

:tp

and :ts shows relative paths.

I suppose the problem is that :pwd is d/, and the path it looks for is just main.c which is not present in d/.

Even more confusing to me, if I do:

vim -u vimrc d/a.c

then everything works, and :ts shows absolute paths.

How to solve this? Why isn't tagrelative helping?

vim 8.0, Ubuntu 17.04.

5
  • 1
    Don't know why Vim behaves like this, but at least as a workaround you might try running ctags as ctags -R $PWD, which should put absolute paths into tags file.
    – xaizek
    Oct 18, 2017 at 21:51
  • @xaizekt thanks! That works as expected. Feel free to add the comment as an answer as it provides a good workaround. Oct 19, 2017 at 2:04
  • I now think this behaviour is a bug, would you like report it or should I?
    – xaizek
    Oct 19, 2017 at 10:57
  • @xaizek go for it! Oct 19, 2017 at 12:05
  • To track progress: reported as issue #2221.
    – xaizek
    Oct 19, 2017 at 14:47

1 Answer 1

5

Workaround

Since the problem happens because of relative paths in tags file, it will go away if there are only absolute paths. ctags has --tag-relative option, which:

Indicates that the file paths recorded in the tag file should be relative to the directory containing the tag file, rather than relative to the current directory, unless the files supplied on the command line are specified with absolute paths. This option must appear before the first file name. The default is yes when running in etags mode (see the -e option), no otherwise.

An easy way of doing it is to run ctags like this:

ctags -R $PWD

Cause of the issue

After looking at the source code, I'm pretty sure that this strange behaviour is a bug related to caching of tag search results.

From what I understood Vim uses relative path to tags in current directory (can be checked via :echo tagfiles()), but absolute path otherwise. For

vim -u vimrc main.c

"tags" path is stored in the cache, but it is impossible to compose full path if all you have is "tags" and "main.c". This is why 'tagrelative' doesn't work, input data required for it to work is missing. For

vim -u vimrc d/a.c

Vim uses full path (not "../tags") and everything works as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.