如何从项目根目录 运行 vim commands/scripts?

How to run vim commands/scripts from project root?

我有很多命令想 运行 不在当前目录中,而是在项目根目录中。即向上目录直到我到达根的一些指示,例如 .git 目录。

例如 运行ning vimgrep -r(递归)在我的所有项目上,或者 运行ning 标签生成在整个项目上递归。

我如何获得该路径?我发现的唯一接近指示是 this:set tags=./tags;~/Projects 但这只是将字符串原样保存到标签中。为描述的用例分配类似的东西,让我逐字逐句地得到字符串。

非常感谢任何帮助! 谢谢!

我使用 local_vimrc 插件来设置项目相关变量。然后,我使用 (/write) 依赖于 (buffer/project)-local 变量的插件来做事。 (不幸的是,大多数插件都依赖全局变量,这不是在多项目会话中将其行为专门用于当前项目的最佳选择)

关于ctags生成,正在使用lh-tags that requires a few variables to be set

关于grepping,和其他一样,我通常从当前目录开始,这通常是我项目的根目录。但是你也可以很容易地得到一个 plugin/command 这样 运行 类似的东西:

exe "vimgrep -r ".pattern." ".
  \ map(file_extensions, 
  \     string(lh#option#get('project_root_directory').'/**').'v:val')

编辑:

如果你不想要其他的配置文件,而.git/目录足以标识你的项目根目录,那么,你可以有这样的函数来获取你的项目根目录:

function! ProjectRootDirectory()
   return fnamemodify(finddir('.git', '.;'), ':h')
endfunction

然后当你运行 ctags 时,你必须从这个vim 函数的结果执行ctags。目前我不知道你使用哪个插件来 运行 ctags。我的 lh-tags 不通过其配置变量支持函数。如果需要,可以轻松添加。
但是,我没有看到从 .vimrc 配置一次 &tags 以便在每个项目的基础上配置此设置的简单方法。

避免使用 "changing the working directory" 或区分 "working directory and project root" 的想法,因为几乎没有工具可以正确处理这些概念。

唯一的工具(例如 git)是那些不关心当前目录的工具。

否则,试图让一切都正常工作而没有不良副作用是疯狂的。 "Working directory" 是一个太基础的概念,甚至无法尝试在 运行ning 程序中进行更改。

最好的方法是在您想要做 "local" 事情的目录中打开一个新的 Vim 会话 - 然后切换回 "project" 会话到 运行 项目命令。 Vim 将防止您意外覆盖另一个会话中的更改。

另一种方法是将命令包装在 shell 中,这样它们就可以拥有自己的 "own" 工作目录,例如:

:!cd ../../..; ctags -R

(这将允许您为项目重新生成标签文件,而不仅仅是当前目录)

或:

:!cd ../../..; grep -r foo **/*

但是任何带有文件名的输出都是相对于根目录的,而不是当前目录。

因此您可能更愿意这样做:

:!cd ../../..; vim

它在当前会话中创建一个新的 Vim 会话,但在根目录的上下文中。

或者,您可能更喜欢相反的情况(假设 Vim 是 运行ning 项目根目录中:

:!cd $(dirname %); vim

这让您可以在当前文件的目录中工作 - 您必须退出到主会话以再次使用 运行 项目范围的工具。

因此,您是 "changing vim sessions" 而不是 "changing" 目录(通过有 2 个会话或 "nesting" 像上面那样一个在另一个中)。

我个人喜欢保持简单,让我的当前目录成为我的项目根目录。我可以使用 % 来表示命令中的当前文件,例如:!git add %。除了 % 之外,您还可以使用文件名修饰符,例如:e %:h/foo.txt。参见 :h filename-modifiers

但是您提到您使用 CtrlP 并且您喜欢它更改当前目录的方式。这意味着您需要更有创意。

以下是我的推荐:

  • 通过 git 挂钩更新您的标签。参见 Effortless Ctags with Git
  • 如果您的标签在 .git/tags 中,fugitive.vim 将自动为您设置这些标签。
  • 使用 :Ggrep,它使用 git grep,因此它已经知道您的项目根目录,而且比 :vimgrep.
  • 快得多
  • 运行 来自 root 的任意命令比较棘手。我使用 projectionist 来管理我的项目。 Projectionist 提供命令 :ProjectDo,它完全符合您的要求。

现在提醒一句:Vim对"project"一窍不通。最接近的是 'exrc' 选项(参见 :h 'exrc'),它非常蹩脚。