xolox / vim-easytags

Automated tag file generation and syntax highlighting of tags in Vim
http://peterodding.com/code/vim/easytags/
1.01k stars 109 forks source link

easytags_dynamic_files=2 doesn't work as stated (or very confusing) #92

Open oryband opened 9 years ago

oryband commented 9 years ago

This is my easytags-related .vimrc:

set tags=./.vimtags;
  1 let g:easytags_file = '~/.vimtags'
  2 let g:easytags_dynamic_files = 2
  3 let g:easytags_by_filetype = 1
  4 let g:easytags_updatetime_warn = 0
  5 let g:easytags_events = ['BufReadPost', 'BufWritePost']
  6
  7 let g:easytags_languages = {
  8             \   'javascript': {
  9             \       'cmd': 'jsctags',
 10             \       'args': [],
 11             \       'fileoutput_opt': '-f',
 12             \       'stdout_opt': '-f-',
 13             \       'recurse_flag': '-R'
 14             \   }
 15             \}

Whenever I open a Python file, save the buffer once, then save it the second time, I get the following error:

easytags.vim 3.6.6: Vim(let):E716: Key not present in Dictionary: tagsfile (at function xolox#easytags#autoload..xolox#easytags#update..xolox#easytags#update#with_vim, line 12)

Any idea what I'm doing wrong? Easytags docs aren't clear about how to use dynamic_files=2 option.

oryband commented 9 years ago

I just found out this happens on every filetype, not just python. It doesn't even help if I change dynamic_files=1

oryband commented 9 years ago

I fixed the problem by commenting out let g:easytags_by_filetype = 1. I couldn't understand from the docs what caused this.

In addition, I changed my settings to be:

  0 set tags=.vimtags;,~/.vim/tags
  1 let g:easytags_file = '~/.vim/tags'
  2 let g:easytags_dynamic_files = 2

But even though I stated I want a working-directory (not current buffer) .vimtags file, easytags still creates a buffer-directory tags file, not even a .vimtags one. How can I make it like I want?

rvega commented 9 years ago

I'm also trying to set up per-project tag files but easytags keeps creating the tag files in buffer directories instead of the working directory (:pwd). Did you get this working somehow?

oryband commented 9 years ago

@rvega unfortunately as you can see no comment has been made for help :\ @xolox any help please?

rvega commented 9 years ago

This is how it's working for me:

  1. The name of the project tags file is always "tags", not whatever you set for the "tags" option.
  2. Setting "g:easytags_dynamic_files" to 2 creates new tags files in the directories of the open buffers (subdirectories of the project dir).
  3. If I manually create the project's tag file "touch ./tags", and then do ":UpdateTags -R ./", everything works fine from there (modified and new files are indexed and jumps work as expected).

Here are the relevant lines in my .vimrc:

    " Easytags plugin. Use tag files for each project (not a global one).
    " Run tag generator in background. Do not use highlighting (too slow).
    " For a new project, go to the root directory of the project,
    " open vim and do :UpdateTags -R ./ 
    set tags=./tags;
    let g:easytags_dynamic_files = 2
    let g:easytags_async = 1
    let g:easytags_auto_highlight = 0
    let g:easytags_include_members = 1
    let g:easytags_events = ['BufWritePost']

For what it's worth, the Ctrl-P plugin does a good job of figuring out where is the root of the current project. Maybe it's possible to adapt what they are doing so the "let g:easytags_dynamic_files = 2" option works as documented ?

Garonenur commented 9 years ago

I have the same issue with the files being generated in the directories of the current buffer and not in the projects root. Where they should be created. It did not help to create an empty tags file in the root of my project.

oryband commented 9 years ago

@xolox any news on this?

xolox commented 9 years ago

Hi all and sorry for the lack of feedback on this issue until now.

Next to my personal life and work I try to find the time to properly maintain my 30+ open source projects, but the interest in my projects is overwhelming and even if I spend my full weekends I still won't be able to keep up with the stream of incoming questions, bug reports and feature requests. This unfortunately means that the more feedback an issue receives, the more likely it is to be resolved. And of course pull requests help more than bug reports, but don't take that as a complaint :-).

To get back to the topics of this issue:

  1. I believe the error reported by @oryband in his initial message (Key not present in Dictionary: tagsfile) has since been fixed. If you still get that error please let me know and I'll look into that further.
  2. That leaves the confusion about the working directory vs. the directory containing the current file. The Vim documentation of the tags option states:

    When a file name starts with "./", the '.' is replaced with the path of the current file.

    The emphasis is mine. The vim-easytags plug-in tries to follow the Vim documentation and behavior where possible so that's what it does here: The leading dot is replaced (as documented) with the directory containing the current file. So far, this issue sounds like a misunderstanding.

    However the Vim documentation continues:

    But only when the 'd' flag is not included in 'cpoptions'.

    Is this the behavior you are all expecting? And did you change the 'cpoptions' default? If so, then why not explain that in this issue? That would have saved me quite a bit of time ;-). The vim-easytags plug-in currently doesn't check whether 'cpoptions' includes 'd' or not, it unconditionally resolves ./ into the directory of the current buffer.

    I can change vim-easytags to check 'cpoptions' for the 'd' character and make it switch from buffer relative pathnames to working directory relative pathnames. I assume this will resolve the issue reported here, given that you make sure you've changed 'cpoptions' accordingly?

xolox commented 9 years ago

I just published a change to the vim-misc plug-in which should make vim-easytags respect 'cpoptions' when creating dynamic tags files. Can one of you update to the latest version of vim-misc and let me know whether this resolves the issue reported here? (make sure you added 'd' to 'cpoptions', without that nothing changes).

PS. I accidentally closed this issue with my commit message in the vim-misc repository :-), didn't mean to do that, I wanted to wait until I got a confirmation that the issue is resolved and I'd updated the vim-easytags documentation.

oryband commented 9 years ago

Well, I got it working after updating. Thanks! Here is my easytags configuration:

" i have to set tags like this. Not using autocmd only appends them to ./tags for some reason,
" and doesn't overwrite the option.
autocmd FileType * set tags=./.tags;,~/.vim/.vimtags
set cpoptions+=d  " i had to add this, it wasn't on until now.
let g:easytags_file = '~/.vim/.vimtags'
let g:easytags_events = ['BufReadPost', 'BufWritePost']
let g:easytags_dynamic_files = 2
let g:easytags_async = 1
" let g:easytags_auto_update = 0  " check the question below
" let g:easytags_auto_highlight = 0
let g:easytags_resolve_links = 1
let g:easytags_suppress_report = 1

A few issues:

  1. However, I had to comment out the auto_update/highlight lines in order for easytags to create the local .tags file. I thought that these options were meant only for on_cursorhold. The documentation regarding this is quite ambiguous: If on_cursorhold is off, why does auto_update/highlight also apply to events? Events aren't auto - I set them manually.
  2. In addition, the .tags file poped up in the local directory only a few seconds after writing the buffer, and not immediately. Is something still happening in the background? I don't want it to.
  3. Any idea why I'm forced to autocmd FileType * set tags in order for set tags to actually set the tags? I've grepped all my plugins for set tags and setl tags and nobody is setting it.
oryband commented 9 years ago

I've also noticed that when opening my .vimrc, a .vimtags file is created and a .tags file. Any idea why?

xolox commented 9 years ago

However, I had to comment out the auto_update/highlight lines in order for easytags to create the local .tags file. I thought that these options were meant only for on_cursorhold. The documentation regarding this is quite ambiguous: If on_cursorhold is off, why does auto_update/highlight also apply to events? Events aren't auto - I set them manually.

I've tried to clarify the documentation of these two options with the following additions:

I hope this explanation clarifies what "auto" means in the name of those options :-)

xolox commented 9 years ago

In addition, the .tags file poped up in the local directory only a few seconds after writing the buffer, and not immediately. Is something still happening in the background? I don't want it to.

Did you not read the documentation or am I misunderstanding you? In the same post you say you've enabled the following setting:

let g:easytags_async = 1

That would explain the tags file being created after a moment, no?

xolox commented 9 years ago

Any idea why I'm forced to autocmd FileType * set tags in order for set tags to actually set the tags? I've grepped all my plugins for set tags and setl tags and nobody is setting it.

It could be that the vim-easytags plug-in causes this. One way for you to find out is to (temporarily) remove your autocmd FileType hack, restart Vim, get it to set your 'tags' option the wrong way (I'm not sure if it's already set wrong once Vim starts up) and then execute the following Vim command:

:verbose set tags?

This should print the name / location of the last script that changed the value of the 'tags' option.

xolox commented 9 years ago

One more clarification about the following point, to clear up some more confusion:

However, I had to comment out the auto_update/highlight lines in order for easytags to create the local .tags file. I thought that these options were meant only for on_cursorhold. The documentation regarding this is quite ambiguous: If on_cursorhold is off, why does auto_update/highlight also apply to events? Events aren't auto - I set them manually.

The documentation for the g:easytags_events option states:

This option can be used to customize the events that trigger the automatic updating and highlighting performed by the easytags plug-in. The g:easytags_always_enabled and g:easytags_on_cursorhold options are more user friendly but limited ways to accomplish the same thing.

Here's an example: Say you want the easytags plug-in to automatically update & highlight tags for the current file right after you save the file. You can accomplish this by adding the following line to your vimrc script:

:let g:easytags_events = ['BufWritePost']

Note that if you set g:easytags_events in your vimrc script, the values of the options g:easytags_always_enabled and g:easytags_on_cursorhold will be ignored completely.

oryband commented 9 years ago

Hey. Thanks for the all the help.

g:easytags_auto_update - This disables all automatic tags file updates (regardless of how they were enabled) where automatic means initiated by a Vim automatic command. g:easytags_auto_highlight - This disables all automatic tags highlighting (regardless of how it was enabled) where automatic means initiated by a Vim automatic command.

BufWritePost and similar events are called autocmd events in :help, so are they considered automatic commands? I mean, will setting auto_update = 0 ignore the autocmd events i set in g:easytags_events?

Did you not read the documentation or am I misunderstanding you? In the same post you say you've enabled the following setting:

let g:easytags_async = 1

That would explain the tags file being created after a moment, no?

I know I set the update as async, but just because it's async doesn't explicitly mean the async update should happen several seconds later - I thought it should still happen immediately.

I have read through the docs multiple times - but I wanted to make sure that I really did disable on_cursorhold events, and that the update did really occur because of me saving the buffer. Having the .tags file appear several seconds later made me think I did something wrong. So - As I understand now - the update did trigger because of me saving the buffer, right?

:verbose set tags?

This should print the name / location of the last script that changed the value of the 'tags' option.

A ha! I did what you asked, and this was the result:

tags=./tags;,./.tags;,~/.vim/.vimtags
        Last set from ~/documents/dotfiles/.vim/bundle/vim-sensible/plugin/sensible.vim

I've opened an issue in tpope/vim-sensible#94 . Thanks for helping figuring this out. Do you perhaps have any idea how to override vim-sensible?

oryband commented 9 years ago

Also, any idea why .vimtags is still popping up? (see my short post about it above)

leyyinad commented 9 years ago

Having had trouble with this for a very long time now, but never really taking the time to track it down, I finally found the reason why this didn't work for me: I was having .tags in my wildignorefor some strange reason. Because easytags uses expand() to find the tags file, it won't find it if it's part of wildignore. After removing my wildignore definition, everything works as expected – very well. I hope this helps anybody. Thanks a lot for this beautiful plugin, end especially for this important option.

oryband commented 9 years ago

@leyyinad wow, that's a very important tip. I too had .tags in my wildignore. After removing it, I stopped seeing ~/.vim/.vimtags pop up. , but I also don't see $PWD/.tags pop up instead (which should be according to my configuration above. Any idea why? Update: This now works. Thanks! :)

@xolox in any case, I guess this should be added in bold to docs. I've been battling this bug for a year now.

oryband commented 8 years ago

@xolox ping

obxhdx commented 8 years ago

Just a call out, since no one mentioned it, g:easytags_by_filetype should actually point to an existing directory. The documentation says:

...you can set g:easytags_by_filetype to the path of an existing directory.