REFACTOR: I spent all day on it but I am heavily refactoring the API and

organization because it was terrible before and hard to maintain. Now it
should be much easier and there is still of a design decisions to figure
out
This commit is contained in:
2026-10-15 02:07:14 -04:00
parent 2b30e36fad
commit 4bcac5d09b
27 changed files with 875 additions and 480 deletions
+5 -5
View File
@@ -1,6 +1,6 @@
<h1 align="center">Polydev</h1>
<h1 align="center">Vern.nvim</h1>
<p align="center"><em>A multi-language project managing plugin for file creation, building, and running code—all within neovim. Whether you're coding in C/C++ Java, Python, Lua, Rust, and more, Polydev provides seamless integration to boost your productivity inside Neovim.</em></p>
<p align="center"><em>Vern.nvim or Vernacular.nvim is a multi lingual project manager. It creates new projects and files from templates, builds and runs code and can run language specific functions within Neovim</em></p>
<p align="center">
<img src="https://img.shields.io/badge/Lua-1e90ff?style=for-the-badge&logo=lua&logoColor=white" />
@@ -19,13 +19,13 @@
* Integrated terminal for flexible command execution
* Lightweight, fast project manager UI
* Minimal configuration with extensibility in mind
* Built-in diagnostics with `:checkhealth Polydev`
* Built-in diagnostics with `:checkhealth Vern.nvim`
> 📚 [View the full documentation](https://git.moomancer.xyz/DarthMooMancer/polydev/wiki/Home$0) for setup, configuration, and usage details.
## Supported Languages
Polydev currently supports the following languages:
Vern.nvim currently supports the following languages:
* Java
* Python
@@ -52,4 +52,4 @@ Contributions are welcome and appreciated.
* Submit a pull request if you'd like to contribute directly.
If you have an idea or use case you'd like to see supported, let’s discuss it.
Your feedback and contributions are key to making Polydev even better! Thank you for being part of the journey. 🙏
Your feedback and contributions are key to making Vern.nvim even better! Thank you for being part of the journey. 🙏
-83
View File
@@ -1,83 +0,0 @@
local M = {}
M.user_config = {}
---@param user_opts table
function M.setup(user_opts)
user_opts = user_opts or {}
local project_root = (user_opts.globals and user_opts.globals.project_root) or "~/personal/Projects"
local defaults = {
rust = {
project_root = project_root .. "/Rust",
keybinds = {
["<leader>pr"] = "RustRun",
},
},
javascript = {
project_root = project_root .. "/Javascript",
keybinds = {
["<leader>pr"] = "JavascriptRun",
},
},
java = {
project_root = project_root .. "/Java",
keybinds = {
["<leader>pr"] = "JavaRun",
},
},
lua = {
project_root = project_root .. "/Lua",
keybinds = {
["<leader>pr"] = "LuaRun",
},
},
c = {
project_root = project_root .. "/C",
keybinds = {
["<leader>pr"] = "CRun",
},
},
cpp = {
project_root = project_root .. "/CPP",
keybinds = {
["<leader>pr"] = "CppRun",
},
},
python = {
project_root = project_root .. "/Python",
keybinds = {
["<leader>pr"] = "PythonRun",
["<leader>pb"] = "PythonPip",
},
},
html = {
project_root = project_root .. "/Html",
},
globals = {
project_root = project_root,
keybinds = {
["<leader>po"] = "PolydevOpen",
},
},
terminal = {
mode = "split",
win = {
type = "horizontal", anchor = "bottom", size = "20"
},
border = {
enabled = true,
type = "rounded",
},
},
}
M.user_config = vim.tbl_deep_extend("force", defaults, user_opts)
end
---@param lang string
---@return table
function M.get(lang)
return M.user_config[lang] or {}
end
return M
-51
View File
@@ -1,51 +0,0 @@
local M = {}
function M.setup(opts)
opts = opts or {}
local config = require("Polydev.configs")
if config == nil then
return -1
end
config.setup(opts)
require("Polydev.utils").setup(opts)
vim.api.nvim_create_user_command("PolydevOpen", function() require("Polydev.ui").manager(config.get("globals").project_root) end, {})
local keys = vim.tbl_deep_extend("force", {}, config.get("globals").keybinds, opts.keybinds or {})
for key, _ in pairs(keys) do
vim.keymap.set("n", key, ":PolydevOpen<CR>")
end
vim.api.nvim_create_autocmd("FileType", {
pattern = "*",
callback = function()
local filetype = vim.bo.filetype
require("Polydev.languages").load_language_module(filetype, opts)
end,
})
vim.api.nvim_create_autocmd("ColorScheme", {
callback = function()
local function define(name, o)
if vim.fn.hlexists(name) == 0 then
vim.api.nvim_set_hl(0, name, o)
end
end
define("PolydevNormal", {
fg = vim.api.nvim_get_hl(0, { name = "NormalFloat", link = true }).fg,
bg = vim.api.nvim_get_hl(0, { name = "Normal", link = true }).bg,
})
define("PolydevBorder", {
fg = vim.api.nvim_get_hl(0, { name = "FloatBorder", link = true }).fg,
bg = vim.api.nvim_get_hl(0, { name = "Normal", link = true }).bg,
})
define("PolydevTitle", {
fg = vim.api.nvim_get_hl(0, { name = "FloatTitle", link = true }).fg, bold = true,
bg = vim.api.nvim_get_hl(0, { name = "Normal", link = true }).bg,
})
end,
})
end
return M
-226
View File
@@ -1,226 +0,0 @@
local utils = require("Polydev.utils")
local configs = require("Polydev.configs")
local M = {}
local loaded_languages = {}
---@param lang string
---@param opts? table
---@return boolean
function M.load_language_module(lang, opts)
if loaded_languages[lang] then return true end
local ok, mod = pcall(require, "Polydev.languages")
if not ok or type(mod.languages) ~= "table" then return false end
local lang_mod = mod.languages[lang]
if type(lang_mod) ~= "table" or type(lang_mod.setup) ~= "function" then return false end
lang_mod:setup(opts and opts[lang] or {})
loaded_languages[lang] = lang_mod
return true
end
M.languages = {
javascript = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("javascript"), user_opts or {})
vim.api.nvim_create_user_command("JavascriptRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":JavascriptRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local cmd = string.format("node " .. root .. "/main.js")
local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
else
utils.terminal({ "node " .. root .. "/main.js" })
end
end
},
java = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("java"), user_opts or {})
vim.api.nvim_create_user_command("JavaRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":JavaRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local cmd = string.format("javac -d %s %s", root .. "/build", root .. "/src/*.java")
local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
else
utils.terminal({ "java -cp " .. root, "build" .. " Main" })
end
end
},
c = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("c"), user_opts or {})
vim.api.nvim_create_user_command("CRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":CRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local build_dir = root .. "/build"
local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not success then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
end
if success then
local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name()
utils.terminal({ run_cmd })
end
end
},
cpp = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("cpp"), user_opts or {})
vim.api.nvim_create_user_command("CppRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":CppRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local build_dir = root .. "/build"
local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not success then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
end
if success then
local run_cmd = "cd '" .. build_dir .. "' && ./" .. utils.get_project_name()
utils.terminal({ run_cmd })
end
end
},
html = {
setup = function(user_opts)
vim.tbl_deep_extend("force", {}, configs.get("html"), user_opts or {})
end
},
rust = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("rust"), user_opts or {})
vim.api.nvim_create_user_command("RustRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":RustRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
if not root then return print("Error: Project root not found.") end
local cmd = { "cargo build" }
local output = vim.fn.system(table.concat(cmd))
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal(cmd)
vim.api.nvim_set_option_value("modifiable", true, { buf = term_buf })
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_set_option_value("modifiable", false, { buf = term_buf })
else
utils.terminal({ "cargo run" })
end
end
},
python = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("python"), user_opts or {})
vim.api.nvim_create_user_command("PythonPip", function() self:install_dependency() end, {})
vim.api.nvim_create_user_command("PythonRun", function() self:run() end, {})
for key, command in pairs(opts.keybinds) do
if command == "PythonRun" then
vim.keymap.set("n", key, ":PythonRun<CR>", { silent = true })
end
if command == "PythonPip" then
vim.keymap.set("n", key, ":PythonPip<CR>", { silent = true })
end
end
local root = utils.get_project_root()
if root then
local venv_path = root .. "/venv/bin/activate"
if vim.fn.filereadable(venv_path) == 1 then
vim.env.VIRTUAL_ENV = venv_path
vim.env.PATH = root .. "/venv/bin:" .. vim.env.PATH
end
end
end,
install_dependency = function()
vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module)
if not pip_module or pip_module == "" then return print("Pip canceled") end
utils.terminal({ "pip install " .. pip_module })
end)
end,
run = function()
utils.terminal({ "python3 " .. utils.get_project_root(), "main.py" })
end
},
lua = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend("force", {}, configs.get("lua"), user_opts or {})
vim.api.nvim_create_user_command("LuaRun", function() self:run() end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":LuaRun<CR>", { silent = true })
end
end,
run = function()
local init_lua_path = utils.get_project_root() ..
"/lua/" .. utils.get_project_name() .. "/init.lua"
if vim.fn.filereadable(init_lua_path) == 1 then
utils.terminal({ "lua " .. init_lua_path })
end
end
},
}
return M
-114
View File
@@ -1,114 +0,0 @@
local M = {}
M.opts = {}
function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("terminal"), opts or {})
end
function M.exists(path)
return (io.open(path, "r") ~= nil)
end
---@return string
function M.get_project_root()
local plugin_dir = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":h:h:h")
local dir = vim.fn.system(plugin_dir .. "/bash_scripts/walkup.sh"):gsub("%s+$", "")
return dir
end
---@return string
function M.get_project_name()
return vim.fn.fnamemodify(M.get_project_root(), ":t")
end
---@param path_segments table
---@param content string
function M.write_file(path_segments, content)
local path = table.concat(path_segments, "/")
local file = assert(io.open(path, "w"), "Error creating file: " .. path)
file:write(content)
file:close()
vim.cmd("edit " .. path)
end
---@param path string
---@param gitignore_lines table
function M.init_git(path, gitignore_lines)
vim.fn.mkdir(path, "p")
vim.fn.system({ "git", "-C", path, "init" })
if gitignore_lines and #gitignore_lines > 0 then
local contents = table.concat(gitignore_lines, "\n")
M.write_file({ path, ".gitignore" }, contents)
end
end
---@param cmd table
---@return integer, integer?
function M.terminal(cmd)
if M.opts.mode == "floating" then
local opts = require("Polydev.presets").getPresets(M.opts.win.anchor)
local ui = vim.api.nvim_list_uis()[1]
local width, height, row, col
if opts ~= nil then
width = math.max(1, math.floor(ui.width * 0.9) - opts.left - opts.right)
height = math.max(1, math.floor(ui.height * 0.9) - opts.top - opts.bottom)
row = math.floor((ui.height - height) / 2) + opts.top
col = math.floor((ui.width - width) / 2) + opts.left
end
if opts == nil then
width = math.max(1, math.floor(ui.width * 0.9))
height = math.max(1, math.floor(ui.height * 0.9))
row = math.floor((ui.height - height) / 2)
col = math.floor((ui.width - width) / 2)
end
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = M.opts.border.enabled and M.opts.border.type,
})
vim.api.nvim_set_option_value("winhighlight", "Normal:PolydevNormal,FloatBorder:PolydevBorder",
{ win = win })
vim.fn.jobstart(table.concat(cmd, "/"), { term = true })
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true })
return buf, win
end
if M.opts.mode == "split" then
if M.opts.win.type == "vertical" then
if M.opts.win.anchor == "right" then
vim.cmd("set splitright")
end
end
if M.opts.win.type == "horizontal" then
if M.opts.win.anchor == "bottom" then
vim.cmd("set splitbelow")
end
end
if M.opts.win.type == "vertical" then
vim.cmd(M.opts.win.size .. " vsplit")
end
if M.opts.win.type == "horizontal" then
vim.cmd(M.opts.win.size .. " split")
end
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(0, buf)
vim.fn.jobstart(table.concat(cmd, "/"), { term = true })
vim.api.nvim_buf_set_keymap(buf, "n", "<ESC>", "i<C-\\><C-n>:q<CR>", { noremap = true, silent = true })
return buf, win
end
return 0
end
return M
+42
View File
@@ -0,0 +1,42 @@
local M = {}
local utils = require("vern.utils")
M.default_target_file = "main.py"
--- Goal is to add providers for uv and venv so its available to more users
---@param opts? table Takes a table for the runtime
function M.run(opts)
opts = opts or {}
local root = utils.get_project_root() or "."
local project_name = vim.fs.basename(root)
local pattern = vim.tbl_get(
opts,
"templates",
"project",
"executable",
"target"
) or "src/%s/main.py"
local rel_path = pattern:find("%%s")
and string.format(pattern, project_name)
or pattern
local full_path = root .. "/" .. rel_path
utils.terminal({ "python3 " .. full_path }, opts)
end
---@param cmd_args? table Takes a table for the runtime
function M.pip_install(opts, cmd_args)
if cmd_args and cmd_args.args and cmd_args ~= "" then
utils.terminal({ "pip install " .. cmd_args.args })
return
end
vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module)
if not pip_module or pip_module == "" then
vim.notify("Pip Cancelled", vim.log.levels.WARN)
return
end
utils.terminal({ "pip install " .. pip_module }, opts or {})
end)
end
return M
+25
View File
@@ -0,0 +1,25 @@
local M = {}
function M.buf(bufnr, user_opts)
bufnr = (bufnr == nil or bufnr == 0) and vim.api.nvim_get_current_buf()
or bufnr
local ft = vim.bo[bufnr].filetype
if not ft or ft == "" then
return
end
user_opts = user_opts or {}
local default = require("vern.configs.default")
local lang_opts = (user_opts or {})[ft] or {}
local final_opts =
vim.tbl_deep_extend("force", {}, default, user_opts, lang_opts)
final_opts[ft] = nil
local ok, lang_attach = pcall(require, "vern.attach." .. ft) --- like a try / catch block in c++
if ok and type(lang_attach) == "function" then
lang_attach(bufnr, final_opts)
end
end
return M
+43
View File
@@ -0,0 +1,43 @@
local actions = require("vern.actions.python")
local config = require("vern.configs.python")
return function(bufnr, user_opts)
local opts = vim.tbl_deep_extend("force", {}, config, user_opts or {})
vim.api.nvim_buf_create_user_command(bufnr, "Pythonrun", function()
if actions.run then
actions.run(opts)
end
end, { desc = "Run python project" })
vim.api.nvim_buf_create_user_command(bufnr, "Pythonpip", function(cmd_args)
if actions.pip_install then
actions.pip_install(opts, cmd_args)
end
end, { nargs = "*", desc = "Install python packages" })
for key, def in pairs(opts.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
local root = require("vern.utils").get_project_root()
if root then
local venv_dir = nil
if vim.uv.fs_stat(root .. "/venv/bin/python") then
venv_dir = root .. "/venv"
elseif vim.uv.fs_stat(root .. "/.venv/bin/python") then
venv_dir = root .. "/.venv"
end
if venv_dir then
vim.env.VIRTUAL_ENV = venv_dir
vim.env.PATH = venv_dir .. "/bin:" .. vim.env.PATH
end
end
end
+15
View File
@@ -0,0 +1,15 @@
return {
workspace_root = "~/personal/Projects",
terminal = {
mode = "split",
win = {
type = "horizontal",
anchor = "bottom",
size = "20",
},
border = {
enabled = true,
type = "rounded",
},
},
}
+43
View File
@@ -0,0 +1,43 @@
local actions = require("vern.actions.python")
return {
root = "Python", --- later will concat the project_root to the front
keybinds = {
["<leader>pr"] = {
desc = "Executes python code",
action = actions.run,
},
["<leader>pb"] = {
desc = "Asks for what python package to install",
action = actions.pip_install,
},
},
templates = {
project = {
["executable"] = {
template = "vern.templates.python.main",
target = "src/%s/main.py",
},
["init"] = {
template = "vern.templates.python.__init__",
target = "src/%s/__init__.py",
},
["manifest"] = {
template = "vern.templates.python.pyproject",
target = "pyproject.toml",
},
},
file = {
["module"] = {
template = "vern.templates.python.module",
target = "src/%s.py",
},
},
extras = {
["gitignore"] = {
template = "vern.templates.extras.gitignore",
target = ".gitignore",
},
},
},
}
+20
View File
@@ -0,0 +1,20 @@
local M = {}
M.user_opts = {}
function M.setup(opts)
M.user_opts = opts or {}
local group =
vim.api.nvim_create_augroup("VernAutocommands", { clear = true })
vim.api.nvim_create_autocmd("FileType", {
group = group,
pattern = "*",
callback = function(args)
require("vern.attach").buf(args.buf, M.user_opts)
end,
desc = "Attach languages to buffer",
})
end
return M
+389
View File
@@ -0,0 +1,389 @@
local utils = require("Polydev.utils")
local configs = require("Polydev.configs")
local M = {}
local loaded_languages = {}
---@param lang string
---@param opts? table
---@return boolean
function M.load_language_module(lang, opts)
if loaded_languages[lang] then
return true
end
local ok, mod = pcall(require, "Polydev.languages")
if not ok or type(mod.languages) ~= "table" then
return false
end
local lang_mod = mod.languages[lang]
if type(lang_mod) ~= "table" or type(lang_mod.setup) ~= "function" then
return false
end
lang_mod:setup(opts and opts[lang] or {})
loaded_languages[lang] = lang_mod
return true
end
M.languages = {
javascript = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend(
"force",
{},
configs.get("javascript"),
user_opts or {}
)
vim.api.nvim_create_user_command("JavascriptRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set(
"n",
key,
":JavascriptRun<CR>",
{ silent = true }
)
end
end,
run = function()
local root = utils.get_project_root()
local cmd = string.format("node " .. root .. "/main.js")
local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value(
"modifiable",
true,
{ buf = term_buf }
)
vim.api.nvim_buf_set_lines(
term_buf,
0,
-1,
false,
vim.list_extend(
{ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true })
)
)
vim.api.nvim_set_option_value(
"modifiable",
false,
{ buf = term_buf }
)
else
utils.terminal({ "node " .. root .. "/main.js" })
end
end,
},
java = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend(
"force",
{},
configs.get("java"),
user_opts or {}
)
vim.api.nvim_create_user_command("JavaRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":JavaRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local cmd = string.format(
"javac -d %s %s",
root .. "/build",
root .. "/src/*.java"
)
local output = vim.fn.system(cmd)
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value(
"modifiable",
true,
{ buf = term_buf }
)
vim.api.nvim_buf_set_lines(
term_buf,
0,
-1,
false,
vim.list_extend(
{ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true })
)
)
vim.api.nvim_set_option_value(
"modifiable",
false,
{ buf = term_buf }
)
else
utils.terminal({ "java -cp " .. root, "build" .. " Main" })
end
end,
},
c = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend(
"force",
{},
configs.get("c"),
user_opts or {}
)
vim.api.nvim_create_user_command("CRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":CRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local build_dir = root .. "/build"
local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not success then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value(
"modifiable",
true,
{ buf = term_buf }
)
vim.api.nvim_buf_set_lines(
term_buf,
0,
-1,
false,
vim.list_extend(
{ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true })
)
)
vim.api.nvim_set_option_value(
"modifiable",
false,
{ buf = term_buf }
)
end
if success then
local run_cmd = "cd '"
.. build_dir
.. "' && ./"
.. utils.get_project_name()
utils.terminal({ run_cmd })
end
end,
},
cpp = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend(
"force",
{},
configs.get("cpp"),
user_opts or {}
)
vim.api.nvim_create_user_command("CppRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":CppRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
local build_dir = root .. "/build"
local cmd = "cd '" .. build_dir .. "' && cmake --build ."
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
if not success then
local term_buf = utils.terminal({ cmd })
vim.api.nvim_set_option_value(
"modifiable",
true,
{ buf = term_buf }
)
vim.api.nvim_buf_set_lines(
term_buf,
0,
-1,
false,
vim.list_extend(
{ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true })
)
)
vim.api.nvim_set_option_value(
"modifiable",
false,
{ buf = term_buf }
)
end
if success then
local run_cmd = "cd '"
.. build_dir
.. "' && ./"
.. utils.get_project_name()
utils.terminal({ run_cmd })
end
end,
},
html = {
setup = function(user_opts)
vim.tbl_deep_extend(
"force",
{},
configs.get("html"),
user_opts or {}
)
end,
},
rust = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend(
"force",
{},
configs.get("rust"),
user_opts or {}
)
vim.api.nvim_create_user_command("RustRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":RustRun<CR>", { silent = true })
end
end,
run = function()
local root = utils.get_project_root()
if not root then
return print("Error: Project root not found.")
end
local cmd = { "cargo build" }
local output = vim.fn.system(table.concat(cmd))
if not vim.v.shell_error == 0 then
local term_buf = utils.terminal(cmd)
vim.api.nvim_set_option_value(
"modifiable",
true,
{ buf = term_buf }
)
vim.api.nvim_buf_set_lines(
term_buf,
0,
-1,
false,
vim.list_extend(
{ "Error during compilation:" },
vim.split(output, "\n", { trimempty = true })
)
)
vim.api.nvim_set_option_value(
"modifiable",
false,
{ buf = term_buf }
)
else
utils.terminal({ "cargo run" })
end
end,
},
python = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend(
"force",
{},
configs.get("python"),
user_opts or {}
)
vim.api.nvim_create_user_command("PythonPip", function()
self:install_dependency()
end, {})
vim.api.nvim_create_user_command("PythonRun", function()
self:run()
end, {})
for key, command in pairs(opts.keybinds) do
if command == "PythonRun" then
vim.keymap.set(
"n",
key,
":PythonRun<CR>",
{ silent = true }
)
end
if command == "PythonPip" then
vim.keymap.set(
"n",
key,
":PythonPip<CR>",
{ silent = true }
)
end
end
local root = utils.get_project_root()
if root then
local venv_path = root .. "/venv/bin/activate"
if vim.fn.filereadable(venv_path) == 1 then
vim.env.VIRTUAL_ENV = venv_path
vim.env.PATH = root .. "/venv/bin:" .. vim.env.PATH
end
end
end,
install_dependency = function()
vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module)
if not pip_module or pip_module == "" then
return print("Pip canceled")
end
utils.terminal({ "pip install " .. pip_module })
end)
end,
run = function()
utils.terminal({ "python3 " .. utils.get_project_root(), "main.py" })
end,
},
lua = {
setup = function(self, user_opts)
local opts = vim.tbl_deep_extend(
"force",
{},
configs.get("lua"),
user_opts or {}
)
vim.api.nvim_create_user_command("LuaRun", function()
self:run()
end, {})
for key, _ in pairs(opts.keybinds) do
vim.keymap.set("n", key, ":LuaRun<CR>", { silent = true })
end
end,
run = function()
local init_lua_path = utils.get_project_root()
.. "/lua/"
.. utils.get_project_name()
.. "/init.lua"
if vim.fn.filereadable(init_lua_path) == 1 then
utils.terminal({ "lua " .. init_lua_path })
end
end,
},
}
return M
+3
View File
@@ -0,0 +1,3 @@
local M = {}
return M
+23
View File
@@ -0,0 +1,23 @@
Configs and setups currently for each file type
Configs:
project_root = the location on the file system for projects
keybinds = Custom keybinds for each file type
Templates:
projects:
run = creates project
files:
run = creates file
extras:
run = creates auxiliary files for specific languages like c
Languages:
file type:
setup = loads on filetype and loads functions
Run = builds if needed then executes the main file
Use a polydevrc.json or something named like that but in json for user specific
settings per project like changing where the executable for a project is like
how I have been doing manually in CMAKE for c projects to test
+31
View File
@@ -0,0 +1,31 @@
local M = {}
---@param opts table
M.template = function(opts)
local base = [=[
.DS_Store
.vscode/
.idea/
.env
.env.*
]=]
local lang_block = {
python = [=[
__pycache__/
build/
dist/
.venv/
env/
venv/
.pytest_cache/
]=],
}
local extra = (opts and opts and lang_block[opts.lang]) or ""
return base .. extra
end
return M
+13
View File
@@ -0,0 +1,13 @@
local M = {}
---@param opts table
M.template = function(opts)
local template = [=[
# %s
__all__: list[str] = []
]=]
return string.format(template, opts.project_name)
end
return M
+15
View File
@@ -0,0 +1,15 @@
local M = {}
---@param opts table
M.template = function(opts)
local template = [=[
def main() -> None:
printf("Hello from %s!")
if __name__ == "__main__":
main()
]=]
return string.format(template, opts.project_name)
end
return M
+13
View File
@@ -0,0 +1,13 @@
local M = {}
---@param opts table
M.template = function(opts)
local template = [=[
"""
%s module
"""
]=]
return string.format(template, opts.project_name)
end
return M
+25
View File
@@ -0,0 +1,25 @@
local M = {}
---@param opts table
M.template = function(opts)
local n = opts.project_name
local template = [=[
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "%s"
version = "0.1.0"
description = "Project %s"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []
[project.scripts]
%s = "%s.main:main"
]=]
return string.format(template, n, n, n, n)
end
return M
+149
View File
@@ -0,0 +1,149 @@
local M = {}
---@param bufnr? integer Default is 0 (current buffer)
---@return string|nil
function M.get_project_root(bufnr)
bufnr = bufnr or 0
local root_markers = {
".git",
"pyproject.toml",
"setup.py",
"Makefile",
"CMakeLists",
"Cargo.toml",
}
return vim.fs.root(bufnr, root_markers) or vim.uv.cwd()
end
---
---@param cmd table
---@return integer, integer?
function M.terminal(cmd, opts)
opts = opts or {}
if opts.terminal.mode == "floating" then
local ui = vim.api.nvim_list_uis()[1]
local width, height, row, col
if opts.terminal ~= nil then
width = math.max(
1,
math.floor(ui.width * 0.9)
- opts.terminal.left
- opts.terminal.right
)
height = math.max(
1,
math.floor(ui.height * 0.9)
- opts.terminal.top
- opts.terminal.bottom
)
row = math.floor((ui.height - height) / 2) + opts.terminal.top
col = math.floor((ui.width - width) / 2) + opts.terminal.left
end
if opts.terminal == nil then
width = math.max(1, math.floor(ui.width * 0.9))
height = math.max(1, math.floor(ui.height * 0.9))
row = math.floor((ui.height - height) / 2)
col = math.floor((ui.width - width) / 2)
end
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = opts.terminal.border.enabled and opts.terminal.border.type,
})
vim.api.nvim_set_option_value(
"winhighlight",
"Normal:PolydevNormal,FloatBorder:PolydevBorder",
{ win = win }
)
vim.fn.jobstart(table.concat(cmd, "/"), { term = true })
vim.api.nvim_buf_set_keymap(
buf,
"n",
"<ESC>",
"i<C-\\><C-n>:q<CR>",
{ noremap = true, silent = true }
)
return buf, win
end
if opts.terminal.mode == "split" then
if opts.terminal.win.type == "vertical" then
if opts.terminal.win.anchor == "right" then
vim.cmd("set splitright")
end
end
if opts.terminal.win.type == "horizontal" then
if opts.terminal.win.anchor == "bottom" then
vim.cmd("set splitbelow")
end
end
if opts.terminal.win.type == "vertical" then
vim.cmd(opts.terminal.win.size .. " vsplit")
end
if opts.terminal.win.type == "horizontal" then
vim.cmd(opts.terminal.win.size .. " split")
end
local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(0, buf)
vim.fn.jobstart(table.concat(cmd, "/"), { term = true })
vim.api.nvim_buf_set_keymap(
buf,
"n",
"<ESC>",
"i<C-\\><C-n>:q<CR>",
{ noremap = true, silent = true }
)
return buf, win
end
return 0
end
return M
-- M.opts = {}
--
-- function M.setup(opts)
-- M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("terminal"), opts or {})
-- end
--
-- function M.exists(path)
-- return (io.open(path, "r") ~= nil)
-- end
--
--
-- ---@return string
-- function M.get_project_name()
-- return vim.fn.fnamemodify(M.get_project_root(), ":t")
-- end
--
-- ---@param path_segments table
-- ---@param content string
-- function M.write_file(path_segments, content)
-- local path = table.concat(path_segments, "/")
-- local file = assert(io.open(path, "w"), "Error creating file: " .. path)
-- file:write(content)
-- file:close()
-- vim.cmd("edit " .. path)
-- end
--
-- ---@param path string
-- ---@param gitignore_lines table
-- function M.init_git(path, gitignore_lines)
-- vim.fn.mkdir(path, "p")
-- vim.fn.system({ "git", "-C", path, "init" })
--
-- if gitignore_lines and #gitignore_lines > 0 then
-- local contents = table.concat(gitignore_lines, "\n")
-- M.write_file({ path, ".gitignore" }, contents)
-- end
-- end
----
-- return M
-1
View File
@@ -1 +0,0 @@
require("Polydev").setup()
+1
View File
@@ -0,0 +1 @@
require("vern").setup()
+20
View File
@@ -0,0 +1,20 @@
# stylua.toml
# How many characters per line before wrapping
column_width = 80
# Indentation style: "Tabs" or "Spaces"
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 4
# Quote styling: "AutoPreferDouble", "AutoPreferSingle", "ForceDouble", "ForceSingle"
quote_style = "AutoPreferDouble"
# Call parentheses: "Always", "NoSingleString", "None", "Input"
# "None" removes parens when a single string/table literal is passed: fn "arg" / fn { ... }
# "Always" keeps them strictly standard: fn("arg") / fn({ ... })
call_parentheses = "Always"
# Sorting and formatting behavior
collapse_simple_statement = "Never"