如何让Vim Ctrl-P插件为git子模块中的文件建立索引

58wvjzkj  于 2022-11-11  发布在  Git
关注(0)|答案(4)|浏览(125)

如果我运行Ctrl-P,它100%像我希望的那样工作,除了我使用的代码库的大小,它需要很长的时间来索引目录。
为了使Ctrl-P科普我所处理的项目大小,我在.vimrc文件中使用了以下(相当流行的)user_command设置,以提供本机帮助实用程序,从而更快地为Ctrl-P提供可用文件列表:

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

这种方法使得索引的速度快得惊人,但是当这样配置时,Ctrl-P并不像在没有辅助程序的情况下那样了解git子模块的内容(因为'git ls-files'并不递归到子模块,而Ctrl-P的简单目录遍历却可以)。
我也尝试过使用'find'来索引git仓库,但是当我这样做的时候,我最终会索引.git目录、对象文件和所有其他Ctrl-P通常知道会自动忽略的东西;似乎提供user_command完全取代了关于忽略哪些文件的内置逻辑。我可能会编写一个反向grep来删除某些元素,但似乎有人已经找到了一个更优雅的解决方案。
除了使用缓慢的内置搜索,还有什么更聪明的方法可以让Ctrl-P索引git仓库中的所有文件,包括所有子模块中的文件吗?

hvvq6cgz

hvvq6cgz1#

您可以使用find选项来过滤掉您不想要的文件,如:

find . -type f \( -name "*.cpp" -or -name "*.h" \)

或删除.git目录:

find . -path '.git' -prune -o -print

但这不是一个“聪明”的解决方案。

gudnpqoy

gudnpqoy2#

你可以使用ack,它会跳过.git,.svn,.hg等VCS目录。
我在工作中使用了很多ack,它对于全局查找和替换非常有用。我用过find一次,用perlonelinerregex将它导入xargs。不幸的是,这完全破坏了我的.git目录中的代码。我无法提交我的更改,也无法 checkout 、重置或者在那一点上恢复。在那之后我不得不重新 checkout 代码库!当试图排除目录时,Ack比find容易得多,只需使用--ignore-dir标志(或者使用--noignore-dir在非默认目录中搜索)。

1wnzp6jl

1wnzp6jl3#

我开始使用这篇文章中其他答案的变体,但由于所有对echo的调用而出现了一些性能问题。我的索引产生了大约65k个文件,使用git ls-files -co --exclude-standard | while read i; do echo \"\$path/\$i\"; done语法生成索引花了将近3秒。转换为使用sed节省了我所有的时间。

let g:ctrlp_user_command = {
  \ 'types': {
    \ 1: ['.git', 'cd %s && git ls-files -co --exclude-standard && git submodule foreach "git ls-files -co --exclude-standard | sed \"s#^#\$path/#\""'],
    \ 2: ['.hg', 'hg --cwd %s locate -I .'],
    \ },
  \ 'fallback': 'find %s -type f'
  \ }
t3psigkw

t3psigkw4#

我使用git-submodule-foreach向下进入子模块并在那里运行ls-files(在这些文件名中添加子模块路径):

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"']

相关问题