How to get Vim plugin Ctrl-P to index files inside git submodule
If I run Ctrl-P initially, it works 100% as I wish, except with the size of the codebase I'm working with it takes a very long time to index directories.
To get Ctrl-P to cope with the project sizes I'm running into, I use the following (rather popular) user_command parameter in my .vimrc file to provide built-in helper utilities to provide Ctrl-P with a list of available files more quickly:
if has("unix")
let g:ctrlp_user_command = {
\ 'types': {
\ 1: ['.git/', 'cd %s && git ls-files']
\ },
\ 'fallback': 'find %s -type f | head -' . g:ctrlp_max_files
\ }
endif
This approach makes indexing incredibly fast, but when configured this way, Ctrl-P will not know about the contents of git submodules as it did when run without helper programs (since "git ls-files" does not recurse into submodules, and Ctrl-P is a naive way to the catalog).
I tried using 'find' to index git repos, but when I do, I end up indexing .git directories, object files and all other things that Ctrl-P usually knows to ignore automatically; it looks like providing a user_command completely replaces the built-in logic about which files to ignore. Perhaps I could hack a reverse grep to remove some elements, but it seemed like someone must have figured out a more elegant solution to this.
Is there another, possibly smarter way to get Ctrl-P to index all files in the git repository, including files in all of its submodules, other than using slow inline search?
source to share
You can use ack which skips VCS drives like .git, .svn, .hg, etc.
I use ack a lot at work, it's great for global find and replace. I've used it once, pumping this into xargs with a perl one liner regex. Unfortunately, this completely broken code is in my .git directory. I was unable to commit my changes and was unable to check, reset, or revert to this point. After that I had to check the codebase again! Ack is considerably easier to use than finding when trying to exclude directories, just use the --ignore-dir flag (or --noignore-dir to search in non-standard ones).
source to share
I use git-submodule-foreach to go down in the submodules and run ls-files
there (adding the submodule path to these filenames):
let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files -co --exclude-standard && git submodule foreach "git ls-files -co --exclude-standard | while read i; do echo \"\$path/\$i\"; done"']
source to share