Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use tags file as primary marker / allow to limit markers #74

Closed
blueyed opened this issue Apr 6, 2016 · 11 comments
Closed

Use tags file as primary marker / allow to limit markers #74

blueyed opened this issue Apr 6, 2016 · 11 comments

Comments

@blueyed
Copy link
Contributor

blueyed commented Apr 6, 2016

When in some Git submodule, I would rather use the existing tags file from the main repo (up in the directory) tree, than create a new tags file for this project.

A naive approach for this is the following, but will cause many more disk accesses.

Therefore a separate option (enabled by default) might make sense.

Also, having a fixed list of markers really causes unnecessary disk accesses, even if you only want to use ['tags', '.git']! (see #75)

index 4c859b2..04da0e0 100644
--- i/autoload/gutentags.vim
+++ w/autoload/gutentags.vim
@@ -81,14 +81,14 @@ endfunction
 " Finds the first directory with a project marker by walking up from the given
 " file path.
 function! gutentags#get_project_root(path) abort
-    let l:path = gutentags#stripslash(a:path)
-    let l:previous_path = ""
     let l:markers = g:gutentags_project_root[:]
     if exists('g:ctrlp_root_markers')
         let l:markers += g:ctrlp_root_markers
     endif
-    while l:path != l:previous_path
-        for root in l:markers
+    for root in l:markers
+        let l:path = gutentags#stripslash(a:path)
+        let l:previous_path = ""
+        while l:path != l:previous_path
             if getftype(l:path . '/' . root) != ""
                 let l:proj_dir = simplify(fnamemodify(l:path, ':p'))
                 let l:proj_dir = gutentags#stripslash(l:proj_dir)
@@ -102,10 +102,10 @@ function! gutentags#get_project_root(path) abort
                 endif
                 return l:proj_dir
             endif
-        endfor
-        let l:previous_path = l:path
-        let l:path = fnamemodify(l:path, ':h')
-    endwhile
+            let l:previous_path = l:path
+            let l:path = fnamemodify(l:path, ':h')
+        endwhile
+    endfor
     call gutentags#throw("Can't figure out what tag file to use for: " . a:path)
 endfunction

diff --git i/plugin/gutentags.vim w/plugin/gutentags.vim
index 3f756b9..d29cfcf 100644
--- i/plugin/gutentags.vim
+++ w/plugin/gutentags.vim
@@ -50,7 +50,7 @@ if !exists('g:gutentags_modules')
 endif

 if !exists('g:gutentags_project_root')
-    let g:gutentags_project_root = []
+    let g:gutentags_project_root = ['tags']
 endif
 let g:gutentags_project_root += ['.git', '.hg', '.svn', '.bzr', '_darcs', '_FOSSIL_', '.fslckout']

What do you think?

@justinmk
Copy link
Contributor

justinmk commented Apr 6, 2016

Using tags file as the primary marker makes a ton of sense. 👍

In fact, it could be used to eliminate the "project root" crap (yes, it's crap) completely.

@blueyed
Copy link
Contributor Author

blueyed commented Apr 6, 2016

In fact, it could be used to eliminate the "project root" crap completely.

Yeah.

So looking for a tags file should get done first, and only if none is found (and new tags files are meant to be created), and project root is looked up?

We could make the project root lookup optional altogether, only if https://github.com/dbakker/vim-projectroot is installed, which provides a good interface already (ProjectRootGuess()).

blueyed added a commit to blueyed/vim-gutentags that referenced this issue Apr 6, 2016
With g:gutentags_use_generated_file_marker (TODO: document) it will look
for e.g. `tags` first to find the "project" root.

Ref: ludovicchabant#74
@blueyed
Copy link
Contributor Author

blueyed commented Apr 9, 2016

@justinmk
What do you think about #77?

@justinmk
Copy link
Contributor

justinmk commented Apr 9, 2016

@blueyed Seems fine to me. To eliminate "project root" completely, a different approach is needed, which gutentags isn't going to adopt:

  • make :Gutentags {dir} opt-in
    • :Gutentags (without {dir}) builds from the current working-directory
  • only auto-rebuild tags if a tags file (or equivalent) is found

In general, Vim's "working directory" concept should be the authority on the "project root". The various attempts to automatically detect project roots is a waste of time IMO, because sometimes it makes the wrong decision, which means the user must spend time configuring blacklists anyway. This could be avoided by simply making tags generation opt-in (once per project) as described above, then auto-rebuilding when tags file is found.

gutentags has too many options, functions, and commands. It could be greatly simplified using the above approach.

@blueyed
Copy link
Contributor Author

blueyed commented Apr 9, 2016

@justinmk
Looks like a plan!

@ludovicchabant
What's your opinion on that?
And have you had the time to look at my other PRs already?

@ludovicchabant
Copy link
Owner

My turnaround for checking out bugs and PRs is usually in measured in weeks so you'll have to be patient, especially since there's a lot to process here.

Regarding the "project root crap" thing:

  • I originally made Gutentags because I don't want tags files around (I have Gutentags maintain them in the cache folder). I don't want to see them ever, they're useless to me, they just clutter up my folders (dare I say that they're crap? :) ). So root markers are needed for that.
  • Gutentags re-uses the CtrlP markers and has a similar lookup algorithm (if you're using CtrlP) so you don't need to define things twice (again, if you use CtrlP).

Last, re-using an existing tags file poses the problem of how did that file get there in the first place. Having to manually run GutentagsUpdate with a path goes against the original spirit of Gutentags which is to not have to think about it at all.

@blueyed
Copy link
Contributor Author

blueyed commented Apr 10, 2016

Thanks for elaborating on this - I can see your points.

CtrlP

Then we could also add support for https://github.com/dbakker/vim-projectroot probably, if ProjectRootGuess() is available?

@ludovicchabant
Copy link
Owner

Supporting vim-projectroot seems reasonable as an opt-in thing.

Note however that if you use root markers like, say, ['.hg', '.git'], it will currently (and that's the same in CtrlP I believe) check for both markers each step of the way while going up the directory chain. This is so that the "inner most" project is detected.
(I understand that some people may want a different behaviour, but I guess that's where we can delegate this logic to vim-projectroot, which is good)

@JohnLyman
Copy link

JohnLyman commented May 4, 2016

This works for me:

diff --git a/autoload/gutentags.vim b/autoload/gutentags.vim
index 4c859b2..8237e04 100644
--- a/autoload/gutentags.vim
+++ b/autoload/gutentags.vim
@@ -157,7 +157,11 @@ function! gutentags#setup_gutentags() abort
         if g:gutentags_resolve_symlinks
             let l:buf_dir = fnamemodify(resolve(expand('%:p', 1)), ':p:h')
         endif
-        let b:gutentags_root = gutentags#get_project_root(l:buf_dir)
+        if exists("g:gutentags_set_project_root") && g:gutentags_set_project_root != ''
+            let b:gutentags_root = g:gutentags_set_project_root
+        else
+            let b:gutentags_root = gutentags#get_project_root(l:buf_dir)
+        endif
         if filereadable(b:gutentags_root . '/.notags')
             call gutentags#trace("'notags' file found... no gutentags support.")
             return

... and in my vimrc:

let g:gutentags_set_project_root = FindRootDirectory()

That's using vim-rooter, but the same could be accomplished with vim-projectroot:

let g:gutentags_set_project_root = ProjectRootGuess()

@ludovicchabant
Copy link
Owner

Well, you can change my "measured in weeks" comment to "measured in months" :)

If we were to make it possible to not use gutentags#get_project_root and instead use some custom root lookup function (vim-rooter, vim-projectroot, something custom, etc.), would this make everybody happy, or do we still also want the option to use the output tags file as a root marker too?
(which I don't really like because of the chicken-and-egg problem of the first run, as I said, but I'm fine making it available as an option)

@ludovicchabant
Copy link
Owner

ludovicchabant commented Jul 20, 2016

I added support for custom root lookups with df8756a.

For those of you who want to use tags as the root marker, I believe setting g:gutentags_add_default_project_roots to 0 and making tags the only root marker already worked.

To @justinmk's comment about Gutentags having too many options/commands/functions, I'm not sure how to address that though. Gutentags has exactly 2 commands (GutentagsUnlock and GutentagsUpdate), both of which I almost never need to use. It has no real public API so I don't know what functions you're talking about? Last, it's possible it has too many options, yes -- I'm open to ideas to reduce that, but on the other hand IIRC most of the people in this conversation are the reason Gutentags got many new options in the first place :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants