diff --git a/README.md b/README.md
index b14bcf6..7e747cf 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
Polydev
+Vern.nvim
-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.
+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
@@ -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. 🙏
diff --git a/lua/Polydev/configs.lua b/lua/Polydev/configs.lua
deleted file mode 100644
index c313e23..0000000
--- a/lua/Polydev/configs.lua
+++ /dev/null
@@ -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 = {
- ["pr"] = "RustRun",
- },
- },
- javascript = {
- project_root = project_root .. "/Javascript",
- keybinds = {
- ["pr"] = "JavascriptRun",
- },
- },
- java = {
- project_root = project_root .. "/Java",
- keybinds = {
- ["pr"] = "JavaRun",
- },
- },
- lua = {
- project_root = project_root .. "/Lua",
- keybinds = {
- ["pr"] = "LuaRun",
- },
- },
- c = {
- project_root = project_root .. "/C",
- keybinds = {
- ["pr"] = "CRun",
- },
- },
- cpp = {
- project_root = project_root .. "/CPP",
- keybinds = {
- ["pr"] = "CppRun",
- },
- },
- python = {
- project_root = project_root .. "/Python",
- keybinds = {
- ["pr"] = "PythonRun",
- ["pb"] = "PythonPip",
- },
- },
- html = {
- project_root = project_root .. "/Html",
- },
- globals = {
- project_root = project_root,
- keybinds = {
- ["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
diff --git a/lua/Polydev/init.lua b/lua/Polydev/init.lua
deleted file mode 100644
index ebd8bc9..0000000
--- a/lua/Polydev/init.lua
+++ /dev/null
@@ -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")
- 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
diff --git a/lua/Polydev/languages.lua b/lua/Polydev/languages.lua
deleted file mode 100644
index b770acd..0000000
--- a/lua/Polydev/languages.lua
+++ /dev/null
@@ -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", { 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", { 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", { 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", { 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", { 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", { silent = true })
- end
- if command == "PythonPip" then
- vim.keymap.set("n", key, ":PythonPip", { 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", { 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
diff --git a/lua/Polydev/utils.lua b/lua/Polydev/utils.lua
deleted file mode 100644
index 793b11d..0000000
--- a/lua/Polydev/utils.lua
+++ /dev/null
@@ -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", "", "i:q", { 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", "", "i:q", { noremap = true, silent = true })
- return buf, win
- end
- return 0
-end
-
-return M
diff --git a/lua/vern/actions/python.lua b/lua/vern/actions/python.lua
new file mode 100644
index 0000000..33bc89d
--- /dev/null
+++ b/lua/vern/actions/python.lua
@@ -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
diff --git a/lua/vern/attach/init.lua b/lua/vern/attach/init.lua
new file mode 100644
index 0000000..a6bdcd6
--- /dev/null
+++ b/lua/vern/attach/init.lua
@@ -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
diff --git a/lua/vern/attach/python.lua b/lua/vern/attach/python.lua
new file mode 100644
index 0000000..b1a1f08
--- /dev/null
+++ b/lua/vern/attach/python.lua
@@ -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
diff --git a/lua/vern/configs/default.lua b/lua/vern/configs/default.lua
new file mode 100644
index 0000000..8bd048c
--- /dev/null
+++ b/lua/vern/configs/default.lua
@@ -0,0 +1,15 @@
+return {
+ workspace_root = "~/personal/Projects",
+ terminal = {
+ mode = "split",
+ win = {
+ type = "horizontal",
+ anchor = "bottom",
+ size = "20",
+ },
+ border = {
+ enabled = true,
+ type = "rounded",
+ },
+ },
+}
diff --git a/lua/vern/configs/python.lua b/lua/vern/configs/python.lua
new file mode 100644
index 0000000..1d64bc9
--- /dev/null
+++ b/lua/vern/configs/python.lua
@@ -0,0 +1,43 @@
+local actions = require("vern.actions.python")
+
+return {
+ root = "Python", --- later will concat the project_root to the front
+ keybinds = {
+ ["pr"] = {
+ desc = "Executes python code",
+ action = actions.run,
+ },
+ ["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",
+ },
+ },
+ },
+}
diff --git a/lua/Polydev/health.lua b/lua/vern/health.lua
similarity index 100%
rename from lua/Polydev/health.lua
rename to lua/vern/health.lua
diff --git a/lua/vern/init.lua b/lua/vern/init.lua
new file mode 100644
index 0000000..6614192
--- /dev/null
+++ b/lua/vern/init.lua
@@ -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
diff --git a/lua/vern/languages.lua b/lua/vern/languages.lua
new file mode 100644
index 0000000..6f6b24f
--- /dev/null
+++ b/lua/vern/languages.lua
@@ -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",
+ { 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", { 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", { 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", { 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", { 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",
+ { silent = true }
+ )
+ end
+ if command == "PythonPip" then
+ vim.keymap.set(
+ "n",
+ key,
+ ":PythonPip",
+ { 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", { 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
diff --git a/lua/Polydev/presets.lua b/lua/vern/presets.lua
similarity index 100%
rename from lua/Polydev/presets.lua
rename to lua/vern/presets.lua
diff --git a/lua/vern/providers/python/uv.lua b/lua/vern/providers/python/uv.lua
new file mode 100644
index 0000000..5044d6f
--- /dev/null
+++ b/lua/vern/providers/python/uv.lua
@@ -0,0 +1,3 @@
+local M = {}
+
+return M
diff --git a/lua/vern/scratchpad b/lua/vern/scratchpad
new file mode 100644
index 0000000..64f1556
--- /dev/null
+++ b/lua/vern/scratchpad
@@ -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
+
diff --git a/lua/Polydev/templates.lua b/lua/vern/templates.lua
similarity index 100%
rename from lua/Polydev/templates.lua
rename to lua/vern/templates.lua
diff --git a/lua/vern/templates/extras/gitignore.lua b/lua/vern/templates/extras/gitignore.lua
new file mode 100644
index 0000000..c71d152
--- /dev/null
+++ b/lua/vern/templates/extras/gitignore.lua
@@ -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
diff --git a/lua/vern/templates/python/__init__.lua b/lua/vern/templates/python/__init__.lua
new file mode 100644
index 0000000..b9eac27
--- /dev/null
+++ b/lua/vern/templates/python/__init__.lua
@@ -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
diff --git a/lua/vern/templates/python/main.lua b/lua/vern/templates/python/main.lua
new file mode 100644
index 0000000..41c2d19
--- /dev/null
+++ b/lua/vern/templates/python/main.lua
@@ -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
diff --git a/lua/vern/templates/python/module.lua b/lua/vern/templates/python/module.lua
new file mode 100644
index 0000000..752af9c
--- /dev/null
+++ b/lua/vern/templates/python/module.lua
@@ -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
diff --git a/lua/vern/templates/python/pyproject.lua b/lua/vern/templates/python/pyproject.lua
new file mode 100644
index 0000000..20a3f44
--- /dev/null
+++ b/lua/vern/templates/python/pyproject.lua
@@ -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
diff --git a/lua/Polydev/ui.lua b/lua/vern/ui.lua
similarity index 100%
rename from lua/Polydev/ui.lua
rename to lua/vern/ui.lua
diff --git a/lua/vern/utils.lua b/lua/vern/utils.lua
new file mode 100644
index 0000000..97d47c3
--- /dev/null
+++ b/lua/vern/utils.lua
@@ -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",
+ "",
+ "i:q",
+ { 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",
+ "",
+ "i:q",
+ { 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
diff --git a/plugin/Polydev.lua b/plugin/Polydev.lua
deleted file mode 100644
index d9ee380..0000000
--- a/plugin/Polydev.lua
+++ /dev/null
@@ -1 +0,0 @@
-require("Polydev").setup()
diff --git a/plugin/vern.lua b/plugin/vern.lua
new file mode 100644
index 0000000..c4f770e
--- /dev/null
+++ b/plugin/vern.lua
@@ -0,0 +1 @@
+require("vern").setup()
diff --git a/stylua.toml b/stylua.toml
new file mode 100644
index 0000000..13bf097
--- /dev/null
+++ b/stylua.toml
@@ -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"