tomtom/quickfixsigns_vim

Feature Request: parameter to set VCS directory crawl depth

fourjay opened this issue · 4 comments

When using this on a slow NFS network directory (home NAS) with VCS enabled, the crawl up the directory tree makes the plugin unusable (lot's of files in some of those directories). Disabling QF of turning off VCS support and things are snappy again. (by the way I really like the plugin, among other things it seems to take adding RCS to g:quickfixsigns#vcsdiff#vcs works without issue, something I haven't seen elsewhere)

When using this on a slow NFS network directory (home NAS) with VCS
enabled, the crawl up the directory tree makes the plugin unusable
(lot's of files in some of those directories).

Which VCS do you use? How long does it take to run the VCS's diff
command for a single file on the command line? Does it help to set
b:vcs_type by means of some autocommand so that the vcs type is known in
advance? (And maybe set g:quickfixsigns#vcsdiff#guess_type = 0.)

I normally use git. I have old CVS repositories. I also use RCS for ad-hoc control (I've altered g:quickfixsigns#vcsdiff#vcs to add {let g:quickfixsigns#vcsdiff#vcs = {'rcs': {'cmd': 'rcsdiff -U0 %s', 'dir'): 'RCS' } ) but I've disabled it for testing.

I've tried setting b:vcs_type, that doesn't seem to make much difference.

That said, I'd run strace on the "stuck" vim session, which is how I realized what was going on. Further investigation, and I think I see the core problem,

lstat("/net/.git", 0x7fffa026e260) = -1 ENOENT (No such file or directory)
stat("/net/objects ....

I've mounted the NFS home NAS share via autofs. The VCS code appears to be walking up the tree to root along the /net tree, and trying each supported VCS. At the /net level it seems to take a long time (this is likely in part my issue, a slow DNS server, as it's also running on the NAS). Limiting VCS would limit the number of directory walks, but it will still take significant time with even one.

Are you sure, this doesn't help (in your vimrc file):

let g:quickfixsigns#vcsdiff#guess_type = 0
au BufNewFile,BufRead /net/* let b:vcs_type = "rcs"

I assume the upward search happens in quickfixsigns#vcsdiff#GuessType() unless the above mentioned variables are set.

Thanks for your plugin.
I took another look at my issue and found a workaround.
In my vim (a fairly recent 7.4) there is a "feature" of finddir(). It honors &suffixesadd like findfile() even though file suffixes make little sense in terms of directory searches...
Looking at the strace output again, I can see it appending all my suffixesadd extensions for each directory (though I didn't get the connection at first).

....
stat("/net/.hg.php", 0x7fffeca904a0)    = -1 ENOENT (No such file or directory)
stat("/net/.hg.phpt", 0x7fffeca904a0)   = -1 ENOENT (No such file or directory)
stat("/net/.hg.pl", 0x7fffeca904a0)     = -1 ENOENT (No such file or directory)
stat("/net/.hg.py", 0x7fffeca904a0)     = -1 ENOENT (No such file or directory)
stat("/net/.hg.sh", 0x7fffeca904a0)     = -1 ENOENT (No such file or directory)
stat("/net/.hg.js", 0x7fffeca904a0)     = -1 ENOENT (No such file or directory)
stat("/net/.hg.css", 0x7fffeca904a0)    = -1 ENOENT (No such file or directory)
.....

The workaround is fairly simple, wrap the findir call in quickfixsigns#vcsdiff#GuessType() with a copy, unset and restore of suffixesadd. After this GuessType() complete a little slowly on the slow filesystem, but acceptably. Makes some sense, as it's doing 1/10th the work.

I can do the full blown fork and pull request. But I suspect you would not even need this little snippet of diff:

--- a/autoload/quickfixsigns/vcsdiff.vim
+++ b/autoload/quickfixsigns/vcsdiff.vim
@@ -157,6 +157,8 @@ function! quickfixsigns#vcsdiff#GuessType() "{{{3
             let depth = -1
             for vcs in keys(g:quickfixsigns#vcsdiff#vcs)
                 let dir = g:quickfixsigns#vcsdiff#vcs[vcs].dir
+                let l:suffixes_add = &suffixesadd
+                setlocal suffixesadd=''
                 " TLogVAR dir
                 let vcsdir = finddir(dir, path)
                 if !empty(vcsdir)
@@ -167,6 +169,7 @@ function! quickfixsigns#vcsdiff#GuessType() "{{{3
                         " TLogVAR type, depth
                     endif
                 endif
+                setlocal suffixesadd=l:suffixes_add
             endfor
         endif
         let b:vcs_type = type