如何从项目根目录运行vim命令/脚本?

时间:2015-01-16 06:18:30

标签: vim ctags

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

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

我如何获得这条路?我找到的唯一近距离指示是:set tags =。/ tags;〜/ Projects 但这只是将字符串保存到标签中。为所描述的用例分配类似的东西,逐字地获取字符串。

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

3 个答案:

答案 0 :(得分:2)

避免“更改工作目录”或区分“工作目录和项目根目录”的想法,因为几乎没有工具准备好正确处理这些概念。

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

否则,尝试让一切正常运转而没有不良副作用是疯狂的。 “工作目录”是一个过于基本的概念,甚至无法尝试在正在运行的程序中进行更改。

最好的方法是在你希望做“本地”事情的目录中打开一个新的Vim会话 - 然后切换回“项目”会话来运行项目命令。 Vim将保护您免于意外覆盖另一个会话中的更改。

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

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

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

或:

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

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

所以你可能更喜欢这样做:

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

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

或者,您可能更喜欢相反(假设Vim在项目根目录中运行):

:!cd $(dirname %); vim

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

因此,不是“更改”目录,而是“改变vim会话”(通过两次会话或者像上面那样“嵌套”一个)。

答案 1 :(得分:1)

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

关于ctags生成,正在使用lh-tags,需要few variables to be set

关于grepping,与其他一样,我通常从当前目录开始,该目录通常是我项目的根目录。但是你也可以轻松地拥有一个类似于:

的插件/命令
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不支持通过其配置变量的函数。如果需要,可以很容易地添加 但是,我没有看到从&tags配置.vimrc一次的简单方法,以便在每个项目的基础上配置此设置。

答案 2 :(得分:1)

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

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

以下是我的建议:

  • 通过git hooks更新您的标签。请参阅Effortless Ctags with Git
  • 如果您的代码位于.git/tags fugitive.vim,则会自动为您设置这些代码。
  • 使用:Ggrep使用git grep,因此它已经知道您的项目根目录,并且奖励比:vimgrep快得多。
  • 从root运行任意命令比较棘手。我使用projectionist来管理我的项目。 Projectionist提供了命令:ProjectDo,它完全符合您的要求。

现在提醒:Vim不了解"项目"。最接近的是'exrc'选项(见:h 'exrc'),这是非常蹩脚的。