refactor(nvim): streamline Neovim configuration and plugin management
This commit is contained in:
1 parent
06e0bab7dd
commit
bdf8ad1bb0
27 files changed
+1797
-476
No files matched your search
@@ -0,0 +1,161 @@
|
||||
--- Template.nvim integration for quick file scaffolding
|
||||
--- Provides templates for Cosmos SDK, Protobuf, and Vite+Cloudflare development
|
||||
--- @module plugins.template
|
||||
|
||||
---@type LazySpec
|
||||
return {
|
||||
"glepnir/template.nvim",
|
||||
cmd = { "Template", "TemProject" },
|
||||
dependencies = { "folke/snacks.nvim" },
|
||||
config = function()
|
||||
local template = require "template"
|
||||
|
||||
-- Setup template.nvim
|
||||
template.setup {
|
||||
temp_dir = vim.fn.stdpath "config" .. "/templates",
|
||||
author = "Prad",
|
||||
email = "prad@sonr.io",
|
||||
}
|
||||
|
||||
-- Custom template picker using Snacks
|
||||
vim.api.nvim_create_user_command("TemplateSnacks", function(opts)
|
||||
local temp_dir = vim.fn.stdpath "config" .. "/templates"
|
||||
local current_ft = vim.bo.filetype
|
||||
|
||||
-- Find all template files
|
||||
local template_files = vim.fn.globpath(temp_dir, "**/*", false, true)
|
||||
|
||||
-- Filter and format templates
|
||||
local templates = {}
|
||||
for _, file in ipairs(template_files) do
|
||||
if vim.fn.isdirectory(file) == 0 then
|
||||
local filename = vim.fn.fnamemodify(file, ":t")
|
||||
local relative_path = vim.fn.fnamemodify(file, ":~:.")
|
||||
local category = vim.fn.fnamemodify(file, ":h:t")
|
||||
|
||||
-- Extract filetype from template
|
||||
local ext = vim.fn.fnamemodify(file, ":e")
|
||||
if ext == "tpl" then
|
||||
-- Read first line to get filetype marker
|
||||
local first_line = vim.fn.readfile(file, "", 1)[1] or ""
|
||||
ext = first_line:match "^;; (%w+)" or ext
|
||||
end
|
||||
|
||||
-- Filter by current filetype if specified
|
||||
local should_include = true
|
||||
if opts.args == "" and current_ft ~= "" then
|
||||
-- Only filter if we have a current filetype and no args
|
||||
should_include = ext == current_ft or ext == "tpl"
|
||||
end
|
||||
|
||||
if should_include then
|
||||
table.insert(templates, {
|
||||
text = string.format("[%s] %s", category, filename),
|
||||
path = file,
|
||||
filename = filename,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #templates == 0 then
|
||||
vim.notify("No templates found", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
-- Use Snacks picker
|
||||
require("snacks").picker.pick {
|
||||
items = templates,
|
||||
format = function(item) return item.text end,
|
||||
confirm = function(item)
|
||||
if not item then return end
|
||||
|
||||
-- Read template content
|
||||
local content = vim.fn.readfile(item.path)
|
||||
|
||||
-- Process template variables
|
||||
local processed = {}
|
||||
local needs_variable = false
|
||||
local variable_name = nil
|
||||
|
||||
for _, line in ipairs(content) do
|
||||
-- Skip filetype marker line
|
||||
if not line:match "^;; %w+" then
|
||||
-- Check for variable placeholder
|
||||
if line:match "{{_variable_}}" and not variable_name then
|
||||
needs_variable = true
|
||||
end
|
||||
table.insert(processed, line)
|
||||
end
|
||||
end
|
||||
|
||||
-- Prompt for variable if needed
|
||||
if needs_variable then
|
||||
require("snacks").input({ prompt = "Variable name:" }, function(input)
|
||||
if not input then return end
|
||||
variable_name = input
|
||||
|
||||
-- Replace variable in content
|
||||
for i, line in ipairs(processed) do
|
||||
processed[i] = line:gsub("{{_variable_}}", variable_name)
|
||||
end
|
||||
|
||||
-- Insert template
|
||||
insert_template(processed)
|
||||
end)
|
||||
else
|
||||
insert_template(processed)
|
||||
end
|
||||
end,
|
||||
}
|
||||
end, { nargs = "?", desc = "Open template picker" })
|
||||
|
||||
-- Helper function to insert template
|
||||
function insert_template(lines)
|
||||
local cursor_line = nil
|
||||
local processed = {}
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
-- Replace template markers
|
||||
line = line:gsub("{{_date_}}", os.date "%Y-%m-%d %H:%M:%S")
|
||||
line = line:gsub("{{_author_}}", "Prad")
|
||||
line = line:gsub("{{_email_}}", "prad@sonr.io")
|
||||
line = line:gsub("{{_file_name_}}", vim.fn.expand "%:t:r")
|
||||
line = line:gsub("{{_upper_file_}}", vim.fn.expand("%:t:r"):upper())
|
||||
|
||||
-- Convert snake_case to CamelCase
|
||||
local file_name = vim.fn.expand "%:t:r"
|
||||
local camel_case = file_name:gsub("_(%w)", function(c) return c:upper() end)
|
||||
camel_case = camel_case:gsub("^%w", string.upper)
|
||||
line = line:gsub("{{_camel_case_file_}}", camel_case)
|
||||
|
||||
-- Handle lua expressions
|
||||
line = line:gsub("{{_lua:(.-)_}}", function(expr)
|
||||
local func, err = load("return " .. expr)
|
||||
if func then
|
||||
local ok, result = pcall(func)
|
||||
if ok then return tostring(result) end
|
||||
end
|
||||
return ""
|
||||
end)
|
||||
|
||||
-- Track cursor position
|
||||
if line:match "{{_cursor_}}" then
|
||||
cursor_line = i
|
||||
line = line:gsub("{{_cursor_}}", "")
|
||||
end
|
||||
|
||||
table.insert(processed, line)
|
||||
end
|
||||
|
||||
-- Insert lines at cursor
|
||||
local row = vim.api.nvim_win_get_cursor(0)[1]
|
||||
vim.api.nvim_buf_set_lines(0, row - 1, row - 1, false, processed)
|
||||
|
||||
-- Set cursor position if marker found
|
||||
if cursor_line then
|
||||
vim.api.nvim_win_set_cursor(0, { row + cursor_line - 1, 0 })
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
Reference in new issue
Block a user