Исполнение команд при сохранении файлов
Зачем? — Для экономии времени за счёт:
- Автоформатирования кода (GDScript, C#, C++, Python, JSON, YAML, Markdown, lua, и любого другого, для которого есть форматтер)
- Автоисправления простых ошибок файлов (python-овый linter «ruff» может исправлять ошибки/рекомендации, если ему дать аргумент
--fix) - Автозапуска тестов
- И автоматизации пр. рутинных действий
В VSCode есть встроенный функционал Format on Save, что прогоняет форматтер
Но то, что я опишу далее, позволяет прогонять набор команд, не обязательно связанных с форматированием
VSCode Расширение Run on Save
Простой пример:
// .vscode/settings.json
{
// ...
"runOnSave.commands": [
{
"match": ".json$",
"command": "prettier -w ${file}"
}
]
// ...
}
При сохранении файлов, название которых оканчивается на .json (это regex matching), будет прогоняться по ним prettier -w
Этого можно было бы добиться и с помощью Format on Save. Но что-то посложнее — нет
Например:
{
"runOnSave.commands": [
{
"match": ".pyi?$",
"command": "uv run cog -n utf-8 -U -r -P --markers=\"{{{cog cog}}} {{{end}}}\" ${file} && uv run ruff format ${file} && uv run ruff check --select I ${file} --fix"
}
]
}
В этом случае при сохранении python файла последовательно бы отрабатывали 3 экономящие моё время команды:
uv run cog -n utf-8 -U -r -P --markers="{{{cog cog}}} {{{end}}}" ${file}(для кодогенерации внутри файла через использование python cogapp)uv run ruff format ${file}(для форматирования)uv run ruff check --select I ${file} --fix(для сортировки импортов)
На самом деле в cog я использую не {{{, а [[[. Заменил в примере, чтобы он не прогонялся
Specifically для Godot GDScript разработяг, что используют VSCode
Среди форматтеров я остановился на gdscript-formatter
{
"runOnSave.commands": [
{
"match": ".gd$",
// Если не нравится, можно убрать `--reorder-code`
"command": "uv run gdscript-formatter --reorder-code ${file}"
},
]
}
Specifically для Unity C# разработяг, что используют VSCode
Можно было бы установить CSharpier и так же навесить его на сохранение файлов
Прикладной Пример — Protobuf + proto-renumber + buf format — Big Brain Giga Chad Комбинация
Пока я прототипирую схемы данных в protobuf файлах, у меня номера полей идут вразнобой. Пока работаю, я их туда-сюда перетаскиваю внутри message / файла
message Lib {
repeated GRoom a = 4;
float b = 2;
float c = 8;
float d = 7;
}
Рандомная последовательность слегка триггерит ОКР — появляется желание их последовательно пронумеровать для сохранения порядка
Но больше всего моя ж*па взрывается, когда я, не заметив, добавляю поле с ранее забитым номером и падаю с ошибкой:
message Lib {
float e = 2; // Ошибка!
repeated GRoom a = 4;
float b = 2; // <- уже есть поле с номером 2
float c = 8;
float d = 7;
}
Это не просто так в protobuf сделано.
Но когда я использую protobuf для, в сущности, просто типизации json-ов, мне не нужно опираться на сохранение последовательности номеров полей в proto файлах игровых данных
И однажды я нашёл proto-renumber. Он автоматом везде последовательно пронумеровывает поля
message Lib {
float e = 1;
repeated GRoom a = 2;
float b = 3;
float c = 4;
float d = 5;
}
Кукуха сохранена. Я больше ни секунды не трачу на бесполезные думы о нумерации полей + изменения номеров
{
"runOnSave.commands": [
{
"match": ".proto$",
"command": "proto-renumber -replace ${file} && buf format -w ${file}"
}
]
}
Ссылки
Расширение для VSCode — Run on Save by pucelle
В IDE от JetBrains аналогичные штуки делать через File Watchers
Раньше я использовал Neovim и прописывал ряд обработчиков с помощью плагина conform