以 "path agnostic" 的方式从 vim 编译 C 文件

Compiling C file from vim in a "path agnostic" way

假设我从一个大型项目根文件夹启动 vim 并想编译一个特定示例(我将使用 zephyr RTOS 作为示例)。此根文件夹位于 /home/<user>/zephyr/

假设我 运行 vim samples/basic/blinky/src/main.c。 现在,如果我想编译它,我会从另一个终端转到 samples/basic/blinky/build/ 和 运行 make

如果我想在不离开 vim 的情况下构建它,我可以 运行 :make -C samples/basic/blinky/build/

我想自动执行此过程,按任意键,比如说 f5。

例如,如果我有两个垂直拆分,v1 和 v2。

在 v1 中,我有 samples/basic/blinky/src/main.c,在 v2 中,我有 samples/drivers/rtc/src/main.c

从 v1 按 f5 将导致 运行 相当于 :make -C samples/basic/blinky/build/,从 v2 将导致 运行 相当于 :make -C samples/drivers/rtc/build/

常见的模式是构建文件夹位于当前 c 文件目录的 ../build/ 中。

我不想 "permanently" 使用 :cd:lcd 更改工作目录,即使对于当前的 split/window 因为:

我目前的解决方案是在我的 ~/.vimrc 中有一个函数,它暂时将工作目录更改为当前文件等效构建文件夹,这样我就可以 运行 :make 然后将工作目录改回根文件夹。

看起来像这样:

nnoremap <F5> :call MakeTst()<CR> function! MakeTst(...) :cd %:p:h :cd ../build/ :make :cd /home/<user>/zephyr/ endfunction

虽然这可行,但缺点是根文件夹在 ~/.vimrc.

中被硬编码

如何在不对根文件夹路径进行硬编码的情况下获得相同的结果?

你自己给出了答案:在你的函数中。只要你的档案 结构保持该模式,您可以使用文件名修饰符来制作它 通用:

:nnoremap <F5> :make -C %:p:h/../build

这将始终构建在目录 build 的同一级别 当前文件所在的目录。就像你的例子:

a/b/c/src/file.c
a/b/c/build

它在这样的情况下中断:

a/b/c/src/include/features.h

因为它会尝试构建:

a/b/c/src/build

虽然有一个解决方法。如果你的 build 总是在同一个 src 级别,那么您可以使用 :s 执行文本替换 修饰符:

:nnoremap <F5> :make -C %:p:s!.*\zssrc.*!build!

这个简单的模式 .*\zssrc.* 搜索您的 src 路径并将其(及其后的任何内容)替换为 build。它确实 如果路径中没有 src,则什么都没有。