143 lines
4.0 KiB
Lua
143 lines
4.0 KiB
Lua
local M = {}
|
|
|
|
---@param path string
|
|
---@param content string
|
|
function M.dump(path, content)
|
|
local file = assert(io.open(path, "w"), "Error creating file: " .. path)
|
|
file:write(content)
|
|
file:close()
|
|
end
|
|
|
|
function M.fmt(str, ctx)
|
|
return (str:gsub("{([^}]+)}", ctx))
|
|
end
|
|
|
|
---@param bufnr? integer Default is 0 (current buffer)
|
|
function M.proj_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 raw_path string Combination of tbl.path and tbl.name to override
|
|
---@param dir_tbl table<string, string> Strings to replace raw directories in {dirs.<>} with
|
|
---@param ctx table<string, string> Strings to replace raw names like {project_name} with
|
|
---@return string path Fully replaced path
|
|
function M.resolve_path(raw_path, dir_tbl, ctx)
|
|
--- Replace the {dirs.<key>}
|
|
raw_path = raw_path:gsub("{dirs%.([%w_]+)}", function(dir_key)
|
|
return dir_tbl and dir_tbl[dir_key] or dir_key
|
|
end)
|
|
|
|
--- Replace the {<key>}
|
|
local path = raw_path:gsub("{([%w_]+)}", function(key)
|
|
return ctx and ctx[key] or ("{" .. key .. "}")
|
|
end)
|
|
|
|
return path
|
|
end
|
|
|
|
---@return string
|
|
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 path string
|
|
function M.init_readme(path)
|
|
local readme = require("vern.templates.extras.readme")
|
|
M.dump(vim.fs.joinpath(path, "README.md"), readme)
|
|
end
|
|
|
|
---@param cmd table
|
|
---@return integer, integer?
|
|
function M.term(cmd, opts)
|
|
opts = opts or {}
|
|
local buf, win
|
|
if opts.mode.type == "float" then
|
|
local ui = vim.api.nvim_list_uis()[1]
|
|
|
|
local dim = {
|
|
width = math.max(
|
|
1,
|
|
math.floor(ui.width * 0.9)
|
|
- opts.mode.win.float.padding.left
|
|
- opts.mode.win.float.padding.right
|
|
),
|
|
height = math.max(
|
|
1,
|
|
math.floor(ui.height * 0.9)
|
|
- opts.mode.win.float.padding.top
|
|
- opts.mode.win.float.padding.bottom
|
|
),
|
|
}
|
|
|
|
local pos = {
|
|
row = math.floor(
|
|
(ui.height - (vim.o.laststatus == 3 and 1 or 0) - vim.o.cmdheight - dim.height) / 2
|
|
),
|
|
col = math.floor((ui.width - dim.width) / 2),
|
|
}
|
|
|
|
buf = vim.api.nvim_create_buf(false, true)
|
|
win = vim.api.nvim_open_win(buf, true, {
|
|
relative = "editor",
|
|
width = dim.width,
|
|
height = dim.height,
|
|
row = pos.row,
|
|
col = pos.col,
|
|
style = "minimal",
|
|
border = opts.mode.win.float.border.enabled and opts.mode.win.float.border.type or nil,
|
|
})
|
|
end
|
|
if opts.mode.type == "split" then
|
|
if opts.mode.win.split.type == "vertical" then
|
|
if opts.mode.win.split.anchor == "right" then
|
|
vim.cmd("set splitright")
|
|
end
|
|
vim.cmd(opts.mode.win.split.size .. " vsplit")
|
|
end
|
|
if opts.mode.win.split.type == "horizontal" then
|
|
if opts.mode.win.split.anchor == "bottom" then
|
|
vim.cmd("set splitbelow")
|
|
end
|
|
vim.cmd(opts.mode.win.split.size .. " split")
|
|
end
|
|
|
|
buf = vim.api.nvim_create_buf(false, true)
|
|
win = vim.api.nvim_get_current_win()
|
|
|
|
vim.api.nvim_win_set_buf(0, buf)
|
|
end
|
|
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 M
|