From 0f542d56ef5ba90cc4e7b16348b3ca4e63855d7f Mon Sep 17 00:00:00 2001 From: Andrew Haynes Date: Mon, 19 Oct 2026 20:24:45 -0400 Subject: [PATCH] PYTHON: Project setup fixed and working, just need to add providers --- lua/vern/actions/init.lua | 58 ++++++------- lua/vern/actions/python.lua | 106 ++++++++---------------- lua/vern/attach/python.lua | 25 +++--- lua/vern/templates/extras/gitignore.lua | 10 +-- lua/vern/templates/init.lua | 13 ++- lua/vern/templates/python.lua | 32 +++++-- lua/vern/utils.lua | 54 +++++------- stylua.toml | 2 +- 8 files changed, 140 insertions(+), 160 deletions(-) diff --git a/lua/vern/actions/init.lua b/lua/vern/actions/init.lua index 8bc0739..bf1bded 100644 --- a/lua/vern/actions/init.lua +++ b/lua/vern/actions/init.lua @@ -7,21 +7,19 @@ M.create_project = function(opts) default = "", completion = "filetype", }, function(ft) - if ft ~= nil and vim.trim(ft) ~= "" then - local ok, actions = pcall(require, "vern.actions." .. ft) - local configs = require("vern.configs." .. ft) - local args = vim.tbl_deep_extend("force", {}, configs, opts or {}) - if - ok - and actions - and type(actions.create_project) == "function" - then - actions.create_project(args) - else - vim.notify("Unknown Filetype: " .. ft, vim.log.levels.WARN, { - title = "Vern Project", - }) - end + ft = ft and vim.trim(ft) + if not ft or vim.trim(ft) == "" then + return + end + local ok, actions = pcall(require, "vern.actions." .. ft) + local configs = require("vern.configs." .. ft) + local args = vim.tbl_deep_extend("force", {}, configs, opts or {}) + if ok and actions and type(actions.create_project) == "function" then + actions.create_project(args) + else + vim.notify("Unknown Filetype: " .. ft, vim.log.levels.WARN, { + title = "Vern Project", + }) end end) end @@ -33,20 +31,22 @@ M.create_file = function(opts) default = "", completion = "filetype", }, function(ft) - if ft ~= nil and vim.trim(ft) ~= "" then - local ok, actions = pcall(require, "vern.actions." .. ft) - local configs = require("vern.configs." .. ft) - local args = vim.tbl_deep_extend("force", {}, configs, opts or {}) - if ok and actions and type(actions.create_file) == "function" then - actions.create_file(args) - else - vim.notify("Unknown Filetype: " .. ft, vim.log.levels.WARN, { - title = "Vern File", - }) - vim.notify("Error: " .. actions, vim.log.levels.ERROR, { - title = "Vern File", - }) - end + ft = ft and vim.trim(ft) + if not ft or vim.trim(ft) == "" then + return + end + local ok, actions = pcall(require, "vern.actions." .. ft) + local configs = require("vern.configs." .. ft) + local args = vim.tbl_deep_extend("force", {}, configs, opts or {}) + if ok and actions and type(actions.create_file) == "function" then + actions.create_file(args) + else + vim.notify("Unknown Filetype: " .. ft, vim.log.levels.WARN, { + title = "Vern File", + }) + vim.notify("Error: " .. actions, vim.log.levels.ERROR, { + title = "Vern File", + }) end end) end diff --git a/lua/vern/actions/python.lua b/lua/vern/actions/python.lua index 15e257b..5b0822b 100644 --- a/lua/vern/actions/python.lua +++ b/lua/vern/actions/python.lua @@ -1,84 +1,53 @@ local M = {} local utils = require("vern.utils") -local render = require("vern.templates") -local templates = require("vern.templates.python") +local templates = require("vern.templates") +local join, get = vim.fs.joinpath, vim.tbl_get function M.create_project(opts) - opts = opts or {} - vim.ui.input({ - prompt = "Enter project name: ", - default = "", - }, function(pname) - if not pname or vim.trim(pname) == "" then + vim.ui.input({ prompt = "Enter project name: " }, function(pname) + pname = pname and vim.trim(pname) + if not pname or pname == "" then return end - pname = vim.trim(pname) - local configs = require("vern.configs") local pconfigs = require("vern.configs.python") - local cfg = - vim.tbl_deep_extend("force", {}, configs, pconfigs, opts or {}) - local project_root = vim.fs.joinpath( - vim.fn.expand(cfg.workspace_root), - cfg.python.root, - pname - ) - local ctx = { - project_name = pname, - } + local cfg = vim.tbl_deep_extend("force", {}, configs, pconfigs, opts or {}) + local ctx = { project_name = pname } + local py = cfg.python - local dest = vim.tbl_get(cfg, "python", "templates", "project") or {} + local root = join(vim.fn.expand(cfg.workspace_root), py.root, pname) + vim.fn.mkdir(join(root, utils.fmt(py.source_root, ctx)), "p") - vim.fn.mkdir( - vim.fs.joinpath( - project_root, - utils.fmt(cfg.python.source_root, ctx) - ), - "p" - ) - local function dump(dst, alt, tmpl) - local full_path = vim.fs.joinpath( - project_root, - utils.fmt(vim.tbl_get(dest, dst, "target") or alt, ctx) - ) - utils.dump(full_path, tmpl) - return full_path + local tmpl = get(py, "templates", "project") or {} + local function dump(k, alt, id) + local path = join(root, utils.fmt(get(tmpl, k, "target") or alt, ctx)) + utils.dump(path, templates.fetch("python", id, pname)) + return path end - local bin = - dump("bin", "src/{project_name}/main.py", templates.main(pname)) - dump("pkg", "src/{project_name}/__init__.py", templates.__init__(pname)) - dump("spec", "pyproject.toml", templates.pyproject(pname)) + + local bin = dump("bin", "src/{project_name}/main.py", "main") + dump("pkg", "src/{project_name}/__init__.py", "__init__") + dump("spec", "pyproject.toml", "pyproject") + utils.init_git(root, "python") vim.cmd.edit(vim.fn.fnameescape(bin)) end) end function M.create_file(opts) - opts = opts or {} - vim.ui.input({ - prompt = "Enter file name: ", - default = "", - }, function(fname) - if fname ~= nil and vim.trim(fname) ~= "" then - local loc = vim.tbl_get( - opts, - "python", - "templates", - "file", - "module" - ).target or {} - local context = { - project_name = utils.get_project_name(), - name = fname, - } - local rel_path = utils.fmt(loc, context) - local path = vim.fs.joinpath(utils.get_project_root(), rel_path) - utils.dump(path, templates.) - vim.cmd("edit " .. utils.get_project_root() .. "/" .. rel_path) + vim.ui.input({ prompt = "Enter file name: " }, function(fname) + fname = fname and vim.trim(fname) + if not fname or fname == "" then + return end + local root = get(opts, "python", "templates", "file", "module").target or {} + local context = { project_name = utils.proj_name(), name = fname } + local path = join(utils.proj_root(), utils.fmt(root, context)) + utils.dump(path, templates.fetch("python", "module", fname)) + vim.cmd.edit(vim.fn.expand(path)) end) end @@ -86,21 +55,19 @@ end ---@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 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 rel_path = exe:find("%%s") and string.format(exe, project_name) or exe - local rel_path = utils.fmt(exe, { project_name = project_name }) - local full_path = root .. "/" .. rel_path - utils.terminal({ "python3 " .. full_path }, opts.terminal or {}) + local full_path = vim.fn.expand(root, utils.fmt(exe, { project_name = pname })) + utils.term({ "python3 " .. full_path }, opts.terminal or {}) end ---@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.terminal({ "pip install " .. args }, opts.terminal or {}) + utils.term({ "pip install " .. args }, opts.terminal or {}) return end vim.ui.input({ prompt = "Enter pip module: " }, function(pip_module) @@ -108,10 +75,7 @@ function M.pip_install(opts, cmd_args) vim.notify("Pip Cancelled", vim.log.levels.WARN) return end - utils.terminal( - { "pip install " .. vim.trim(pip_module) }, - opts.terminal or {} - ) + utils.term({ "pip install " .. vim.trim(pip_module) }, opts.terminal or {}) end) end diff --git a/lua/vern/attach/python.lua b/lua/vern/attach/python.lua index e76fe31..6fa739e 100644 --- a/lua/vern/attach/python.lua +++ b/lua/vern/attach/python.lua @@ -27,17 +27,18 @@ return function(bufnr, user_opts) 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 + local root = require("vern.utils").proj_root() + if not root then + return + end + 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 diff --git a/lua/vern/templates/extras/gitignore.lua b/lua/vern/templates/extras/gitignore.lua index e1bd85f..ae48d5f 100644 --- a/lua/vern/templates/extras/gitignore.lua +++ b/lua/vern/templates/extras/gitignore.lua @@ -1,7 +1,7 @@ local M = {} ----@param opts table -M.template = function(opts) +---@param lang string +M.template = function(lang) local base = [=[ .DS_Store @@ -13,7 +13,7 @@ M.template = function(opts) ]=] local lang_block = { - python = [=[ + python = vim.trim([=[ __pycache__/ build/ dist/ @@ -21,10 +21,10 @@ dist/ env/ venv/ .pytest_cache/ - ]=], + ]=]), } - local extra = (opts and opts and lang_block[opts.lang]) or "" + local extra = (lang and lang_block[lang]) or "" return base .. extra end diff --git a/lua/vern/templates/init.lua b/lua/vern/templates/init.lua index 0592432..9afb7b4 100644 --- a/lua/vern/templates/init.lua +++ b/lua/vern/templates/init.lua @@ -1,14 +1,19 @@ local M = {} -function M.imp(ft, template, name) +---@param ft string Filetype of template +---@param template string Template in language table +---@param name string A string to replace temp values in template +---@return string +function M.fetch(ft, template, name) ft, template, name = ft or "", template or "", name or "" if ft == "" or template == "" or name == "" then - return + return "" end local ok, mod = pcall(require, "vern.templates." .. ft) - if ok and type(mod) ~= "table" then - return string.gsub(mod[template], "%%s", name) + if ok and type(mod) == "table" then + return (string.gsub(mod[template], "%%s", name)) end + return "" end return M diff --git a/lua/vern/templates/python.lua b/lua/vern/templates/python.lua index 6ae19f6..a4bdec0 100644 --- a/lua/vern/templates/python.lua +++ b/lua/vern/templates/python.lua @@ -1,4 +1,9 @@ return { + --[[ ===================================================================== + TEMPLATE: MAIN (Entrypoint) + File: main.py + Target: src/{project_name}/main.py + ===================================================================== --]] main = vim.trim([=[ def main() -> None: print("Hello from %s!") @@ -6,12 +11,24 @@ def main() -> None: if __name__ == "__main__": main() -]=]), +]=]) .. "\n", + + --[[ ===================================================================== + TEMPLATE: INIT (Package Anchor) + File: __init__.py + Target: src/{project_name}/__init__.py + ===================================================================== --]] __init__ = vim.trim([=[ # %s init __all__: list[str] = [] -]=]), +]=]) .. "\n", + + --[[ ===================================================================== + TEMPLATE: PYPROJECT (Spec / Build Manifest) + File: pyproject.toml + Target: pyproject.toml + ===================================================================== --]] pyproject = vim.trim([=[ [build-system] requires = ["hatchling"] @@ -27,11 +44,16 @@ dependencies = [] [project.scripts] %s = "%s.main:main" -]=]), +]=]) .. "\n", + + --[[ ===================================================================== + TEMPLATE: MODULE (Standalone File) + File: {name}.py + Target: src/{project_name}/{name}.py + ===================================================================== --]] module = vim.trim([=[ """ Module: %s """ - -]=]), +]=]) .. "\n", } diff --git a/lua/vern/utils.lua b/lua/vern/utils.lua index abe6267..5779fad 100644 --- a/lua/vern/utils.lua +++ b/lua/vern/utils.lua @@ -13,7 +13,7 @@ function M.fmt(str, ctx) end ---@param bufnr? integer Default is 0 (current buffer) -function M.get_project_root(bufnr) +function M.proj_root(bufnr) bufnr = bufnr or 0 local root_markers = { ".git", @@ -25,15 +25,28 @@ function M.get_project_root(bufnr) } return vim.fs.root(bufnr, root_markers) or vim.uv.cwd() end ---- + ---@return string -function M.get_project_name() - return vim.fn.fnamemodify(M.get_project_root(), ":t") +function M.proj_name() + return vim.fn.fnamemodify(M.proj_root(), ":t") end ---- + +---@param path string +---@param ft string +function M.init_git(path, ft) + ft = ft and vim.trim(ft) + if not ft or ft == "" then + return + end + + local gitignore = require("vern.templates.extras.gitignore").template(ft) + vim.fn.system({ "git", "-C", path, "init" }) + M.dump(vim.fs.joinpath(path, ".gitignore"), gitignore) +end + ---@param cmd table ---@return integer, integer? -function M.terminal(cmd, opts) +function M.term(cmd, opts) opts = opts or {} local buf, win if opts.mode.type == "float" then @@ -56,12 +69,7 @@ function M.terminal(cmd, opts) local pos = { row = math.floor( - ( - ui.height - - (vim.o.laststatus == 3 and 1 or 0) - - vim.o.cmdheight - - dim.height - ) / 2 + (ui.height - (vim.o.laststatus == 3 and 1 or 0) - vim.o.cmdheight - dim.height) / 2 ), col = math.floor((ui.width - dim.width) / 2), } @@ -74,9 +82,7 @@ function M.terminal(cmd, opts) row = pos.row, col = pos.col, style = "minimal", - border = opts.mode.win.float.border.enabled - and opts.mode.win.float.border.type - or nil, + border = opts.mode.win.float.border.enabled and opts.mode.win.float.border.type or nil, }) end if opts.mode.type == "split" then @@ -111,12 +117,6 @@ 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 @@ -124,16 +124,4 @@ return M -- -- -- --- ---@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/stylua.toml b/stylua.toml index 13bf097..cf3739d 100644 --- a/stylua.toml +++ b/stylua.toml @@ -1,7 +1,7 @@ # stylua.toml # How many characters per line before wrapping -column_width = 80 +column_width = 100 # Indentation style: "Tabs" or "Spaces" line_endings = "Unix"