Компиляция файла C из vim способом, независимым от пути

Предположим, я запускаю 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,

Нажатие f5 из v1 приведет к запуску эквивалента :make -C samples/basic/blinky/build/и из v2 приведет к запуску эквивалента :make -C samples/drivers/rtc/build/

Общий шаблон - папка сборки находится в ../build/ из текущей директории c файлом.

Я не хочу "навсегда" использовать :cd или же :lcd изменить рабочий каталог, даже для текущего split/window, потому что:

  • Мой файл тегов ctags находится в корневой папке, поэтому я хочу иметь возможность перейти к любой функции, которая samples/basic/blinky/src/main.c использует, но не обязательно определяется в том же файле.
    • Если я хочу открыть новый файл, я хочу получить к нему доступ, используя его путь из корневой папки, а не текущий путь к файлу

Мое текущее решение состоит в том, чтобы иметь функцию в моем ~/.vimrc который временно меняет рабочий каталог на текущий файл, эквивалентный папке сборки, так что я могу запустить :make а затем вернет рабочий каталог в корневую папку.

Это выглядит так:

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

Хотя это работает, недостатком является то, что корневая папка жестко ~/.vimrc,

Как я могу достичь того же результата без жесткого определения пути к корневой папке?

1 ответ

Решение

Вы сами дали ответ: в своей функции. Пока ваша файловая структура сохраняет этот шаблон, вы можете использовать модификаторы имени файла, чтобы сделать его общим:

: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 в пути.

Другие вопросы по тегам