Компиляция файла 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
в пути.