CHORE: Fixed bug #4 by looping dirs and creating directories before

other loops in creation.
LANG: Added CPP and bugfixed c to use c code and not python
This commit is contained in:
2026-10-23 08:25:21 -04:00
parent b6d46a0cef
commit 1c4a61ce7f
10 changed files with 382 additions and 33 deletions
+24 -17
View File
@@ -19,7 +19,9 @@ function M.create_project(opts)
---@type VernCConfig
local cfg = vim.tbl_deep_extend("force", {}, configs, configs, opts or {})
local root = join(vim.fn.expand(cfg.workspace_root), cfg.c.root, pname)
local build_cmd = "cd " .. root .. " && cmake -S . -B build"
local bin = action_utils.create(cfg.c, pname, root)
local _ = vim.system({ "sh", "-c", build_cmd }):wait()
utils.init_git(root, "c")
vim.cmd.edit(vim.fn.fnameescape(bin))
@@ -66,31 +68,36 @@ function M.create_file(opts)
end)
end
--- Goal is to add providers for uv and venv so its available to more users
---@param opts? table Takes a table for the runtime
---@param opts? VernCConfig Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.proj_root() or "."
local pname = vim.fs.basename(root)
local exe = opts.python.templates.project.bin.target or "src/%s/main.py"
local full_path = join(vim.fn.expand(root), utils.fmt(exe, { project_name = pname }))
utils.term({ "python3 " .. full_path }, opts.terminal or {})
end
local build_dir = root .. "/build"
local build_cmd = "cd " .. build_dir .. " && cmake --build ."
---@param cmd_args? table Takes a table for the runtime
function M.pip_install(opts, cmd_args)
local args = cmd_args and cmd_args.args and vim.trim(cmd_args.args) or ""
if args ~= "" then
utils.term({ "pip install " .. args }, opts.terminal or {})
return
vim.system({ "sh", "-c", build_cmd }, { text = true }, function(obj)
if obj.code ~= 0 then
vim.schedule(function()
local error_obj = (obj.stderr ~= "" and obj.stderr) or obj.stdout or ""
local error_lines = vim.list_extend(
{ "Error During compilation" },
vim.split(error_obj, "\n", { trimempty = true })
)
local buf, _ = utils.term({ "echo 'compilation failed'" }, opts.terminal, true)
if buf and vim.api.nvim_buf_is_valid(buf) then
vim.api.nvim_set_option_value("modifiable", true, { buf = buf })
vim.api.nvim_buf_set_lines(buf, 0, -1, false, error_lines)
vim.api.nvim_set_option_value("modifiable", false, { buf = buf })
end
vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module)
if not pip_module or vim.trim(pip_module) == "" then
vim.notify("Pip Cancelled", vim.log.levels.WARN)
return
end)
else
vim.schedule(function()
local run_cmd = "cd '" .. build_dir .. "' && ./" .. pname
utils.term({ run_cmd }, opts.terminal, false)
end)
end
utils.term({ "pip install " .. vim.trim(pip_module) }, opts.terminal or {})
end)
end
+102
View File
@@ -0,0 +1,102 @@
local M = {}
local utils = require("vern.utils")
local templates = require("vern.templates")
local action_utils = require("vern.actions.utils")
local join = vim.fs.joinpath
---@param opts VernCPPConfig
function M.create_project(opts)
vim.ui.input({ prompt = "Enter project name: " }, function(pname)
pname = pname and vim.trim(pname)
if not pname or pname == "" then
return
end
local configs = require("vern.configs.cpp")
---@type VernCPPConfig
local cfg = vim.tbl_deep_extend("force", {}, configs, configs, opts or {})
local root = join(vim.fn.expand(cfg.workspace_root), cfg.cpp.root, pname)
local bin = action_utils.create(cfg.cpp, pname, root)
utils.init_git(root, "c")
vim.cmd.edit(vim.fn.fnameescape(bin))
end)
end
function M.create_file(opts)
vim.ui.input({ prompt = "Enter type (c/h): " }, function(ft)
ft = ft and vim.trim(ft)
if not ft or ft == "" then
return
end
local configs = require("vern.configs.c")
---@type VernCPPConfig
local cfg = vim.tbl_deep_extend("force", {}, configs, opts or {})
vim.ui.input({ prompt = "Enter file name: " }, function(fname)
local root = join(vim.fn.expand(cfg.workspace_root), cfg.cpp.root, utils.proj_name())
local input_txt = fname
ft = ft and vim.trim(ft)
if not ft or ft == "" then
return
end
local mod
if ft == "c" then
mod = cfg.cpp.templates.file.source or {}
end
if ft == "h" then
mod = cfg.cpp.templates.file.header or {}
input_txt = fname:upper()
end
local raw_path = join(mod.path, mod.name)
local context = { project_name = utils.proj_name(), name = fname }
local path = utils.resolve_path(raw_path, cfg.cpp.dirs or {}, context)
local abs_file_path = vim.fs.normalize(join(root, path))
if ft == "h" then
local abs_dir_path = vim.fs.dirname(abs_file_path)
if abs_dir_path ~= root and not vim.startswith(root, abs_dir_path) then
vim.fn.mkdir(abs_dir_path, "p")
end
end
utils.dump(abs_file_path, templates.fetch(mod.kind_path, mod.kind, input_txt))
vim.cmd.edit(vim.fn.expand(abs_file_path))
end)
end)
end
---@param opts? VernCPPConfig Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.proj_root() or "."
local pname = vim.fs.basename(root)
local build_dir = root .. "/build"
local build_cmd = "cd " .. build_dir .. " && cmake --build ."
vim.system({ "sh", "-c", build_cmd }, { text = true }, function(obj)
if obj.code ~= 0 then
vim.schedule(function()
local error_obj = (obj.stderr ~= "" and obj.stderr) or obj.stdout or ""
local error_lines = vim.list_extend(
{ "Error During compilation" },
vim.split(error_obj, "\n", { trimempty = true })
)
local buf, _ = utils.term({ "echo 'compilation failed'" }, opts.terminal, true)
if buf and vim.api.nvim_buf_is_valid(buf) then
vim.api.nvim_set_option_value("modifiable", true, { buf = buf })
vim.api.nvim_buf_set_lines(buf, 0, -1, false, error_lines)
vim.api.nvim_set_option_value("modifiable", false, { buf = buf })
end
end)
else
vim.schedule(function()
local run_cmd = "cd '" .. build_dir .. "' && ./" .. pname
utils.term({ run_cmd }, opts.terminal, false)
end)
end
end)
end
return M
+6
View File
@@ -14,6 +14,12 @@ function M.create(cfg, pname, root)
vim.fn.mkdir(root, "p")
local bin
for _, dir in pairs(cfg.dirs) do
local path = vim.fs.normalize(join(root, utils.fmt(dir, ctx)))
vim.fn.mkdir(path, "p")
end
for tbl_name, tbl in pairs(cfg.templates.project) do
local raw_path = join(tbl.path, tbl.name)
local path = utils.resolve_path(raw_path, cfg.dirs, ctx)
+5 -5
View File
@@ -1,10 +1,10 @@
local actions = require("vern.actions.python")
local config = require("vern.configs.python")
local actions = require("vern.actions.c")
local config = require("vern.configs.c")
---@param bufnr integer Buffer to activate on : defaults to 0
---@param user_opts? VernPythonConfig
---@param user_opts? VernCConfig
return function(bufnr, user_opts)
---@type VernPythonConfig
---@type VernCConfig
local opts = vim.tbl_deep_extend("force", {}, config, user_opts or {})
vim.api.nvim_buf_create_user_command(bufnr, "CRun", function()
if type(actions.run) == "function" then
@@ -12,7 +12,7 @@ return function(bufnr, user_opts)
end
end, { desc = "Run c project" })
for key, def in pairs(opts.python.keybinds or {}) do
for key, def in pairs(opts.c.keybinds or {}) do
if type(def.action) == "function" then
vim.keymap.set("n", key, function()
def.action(opts)
+26
View File
@@ -0,0 +1,26 @@
local actions = require("vern.actions.cpp")
local config = require("vern.configs.cpp")
---@param bufnr integer Buffer to activate on : defaults to 0
---@param user_opts? VernCPPConfig
return function(bufnr, user_opts)
---@type VernCPPConfig
local opts = vim.tbl_deep_extend("force", {}, config, user_opts or {})
vim.api.nvim_buf_create_user_command(bufnr, "CPPRun", function()
if type(actions.run) == "function" then
actions.run(opts)
end
end, { desc = "Run cpp project" })
for key, def in pairs(opts.cpp.keybinds or {}) do
if type(def.action) == "function" then
vim.keymap.set("n", key, function()
def.action(opts)
end, {
buffer = bufnr,
silent = true,
desc = def.desc,
})
end
end
end
+67
View File
@@ -0,0 +1,67 @@
local M = {}
---@type VernLanguageConfig
M.cpp = {
root = "CPP",
dirs = {
src = "src",
include = "include/{project_name}",
},
keybinds = {
["<leader>pr"] = {
desc = "Executes cpp code",
action = require("vern.actions.cpp").run,
},
["<leader>pf"] = {
desc = "Creates source/header files",
action = require("vern.actions.cpp").create_file,
},
},
templates = {
project = {
primary = {
path = "{dirs.src}",
name = "main.cpp",
kind = "main",
kind_path = "vern.templates.cpp",
},
manifest = {
path = ".",
name = "CMakeLists.txt",
kind = "CmakeLists",
kind_path = "vern.templates.cpp",
},
style = {
path = ".",
name = ".clang-format",
kind = "format",
kind_path = "vern.templates.cpp",
},
},
file = {
header = {
path = "{dirs.include}",
name = "{name}.hpp",
kind = "header",
kind_path = "vern.templates.cpp",
},
source = {
path = "{dirs.src}",
name = "{name}.c",
kind = "source",
kind_path = "vern.templates.cpp",
},
},
extras = {
linter = {
path = ".",
name = ".clang-tidy",
kind = "linter",
kind_path = "vern.templates.c",
enabled = false,
},
},
},
}
return M
+7 -2
View File
@@ -59,21 +59,26 @@ set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_library(__PROJECT_NAME__ STATIC
set(LIB_SOURCES
# Add your other types here as you implement them:
# src/example1.c
# src/example2.c
)
target_include_directories(__PROJECT_NAME__
if(LIB_SOURCES)
add_library(__PROJECT_NAME__ STATIC ${LIB_SOURCES})
target_include_directories(%s
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
endif()
add_executable(__PROJECT_NAME___bin src/main.c)
set_target_properties(__PROJECT_NAME___bin PROPERTIES OUTPUT_NAME "__PROJECT_NAME__")
if(TARGET __PROJECT_NAME__)
target_link_libraries(__PROJECT_NAME___bin PRIVATE __PROJECT_NAME__)
endif()
]=]) .. "\n",
--[[ =====================================================================
+122
View File
@@ -0,0 +1,122 @@
return {
--[[ =====================================================================
TEMPLATE: MAIN (Entrypoint)
File: main.c
Target: src/{project_name}/main.py
===================================================================== --]]
main = vim.trim([=[
#include <stdio.h>
int
main()
{
char* str = "Hello World";
printf("%s\n", str);
return 0;
}
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: INIT (Package Anchor)
File: __init__.py
Target: src/{project_name}/__init__.py
===================================================================== --]]
format = vim.trim([=[
---
BasedOnStyle: Google
Standard: Latest
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBraces: Allman
SpaceBeforeCpp11BracedList: true
SeparateDefinitionBlocks: Always
Cpp11BracedListStyle: false
BreakAfterReturnType: TopLevel
ReflowComments: Always
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
IndentAccessModifiers: false # Indent access specifiers by one level
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
IndentGotoLabels: InnerIndent
DerivePointerAlignment: false
PointerAlignment: Left
IndentPPDirectives: AfterHash
SortIncludes: CaseSensitive
IncludeBlocks: Preserve
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: PYPROJECT (Spec / Build Manifest)
File: pyproject.toml
Target: pyproject.toml
===================================================================== --]]
CmakeLists = vim.trim([=[
cmake_minimum_required(VERSION 3.16)
project(__PROJECT_NAME__ LANGUAGES C)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_library(__PROJECT_NAME__ STATIC
# Add your other types here as you implement them:
# src/example1.c
# src/example2.c
)
target_include_directories(__PROJECT_NAME__
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
add_executable(__PROJECT_NAME___bin src/main.c)
set_target_properties(__PROJECT_NAME___bin PROPERTIES OUTPUT_NAME "__PROJECT_NAME__")
target_link_libraries(__PROJECT_NAME___bin PRIVATE __PROJECT_NAME__)
]=]) .. "\n",
--[[ =====================================================================
TEMPLATE: MODULE (Standalone File)
File: {name}.py
Target: src/{project_name}/{name}.py
===================================================================== --]]
header = vim.trim([=[
#ifndef __PROJECT_NAME___H
#define __PROJECT_NAME___H
// Code
#endif /* __PROJECT_NAME___H */
]=]) .. "\n",
source = vim.trim([=[
]=]) .. "\n",
linter = vim.trim([=[
Checks: >
-*,
clang-analyzer-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
-bugprone-reserved-identifier,
performance-*,
security-*
readability-redundant-declaration
readability-misleading-indentation
readability-implicit-bool-conversion
misc-misplaced-const,
misc-include-cleaner
-bugprone-narrowing-conversions,
-readability-identifier-length
CheckOptions:
readability-identifier-naming.VariableCase: lower_case
readability-identifier-naming.FunctionCase: lower_case
readability-identifier-naming.StructCase: lower_case
readability-identifier-naming.EnumCase: CamelCase
readability-identifier-naming.EnumConstantCase: UPPER_CASE
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
]=]) .. "\n",
}
+5 -2
View File
@@ -52,7 +52,10 @@
---@field templates VernLanguageTemplates
---@class VernPythonConfig : VernCoreConfig
---@field python VernLanguageConfig
---@field python? VernLanguageConfig
---@class VernCConfig : VernCoreConfig
---@field c VernLanguageConfig
---@field c? VernLanguageConfig
---
---@class VernCPPConfig : VernCoreConfig
---@field cpp? VernLanguageConfig
+13 -2
View File
@@ -8,6 +8,9 @@ function M.dump(path, content)
file:close()
end
---@param str string String to replace
---@param ctx table<string, string> Replacment characters
---@return string
function M.fmt(str, ctx)
return (str:gsub("{([^}]+)}", ctx))
end
@@ -70,8 +73,9 @@ end
---@param cmd table
---@param opts VernTerminalConfig
---@param scratch boolean
---@return integer, integer?
function M.term(cmd, opts)
function M.term(cmd, opts, scratch)
opts = opts or {}
local buf, win
if opts.mode.type == "float" then
@@ -109,6 +113,9 @@ function M.term(cmd, opts)
style = "minimal",
border = opts.mode.win.float.border.enabled and opts.mode.win.float.border.type or nil,
})
if scratch then
return buf, win
end
end
if opts.mode.type == "split" then
if opts.mode.win.split.direction == "vertical" then
@@ -128,8 +135,12 @@ function M.term(cmd, opts)
win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(0, buf)
if scratch then
return buf, win
end
vim.fn.jobstart(table.concat(cmd, "/"), { term = true })
end
local full_cmd = type(cmd) == "table" and table.concat(cmd, " ") or cmd
vim.fn.jobstart(full_cmd, { term = true })
vim.api.nvim_buf_set_keymap(
buf,
"n",