feat: add per-language template file support
Problem: new solution files were always created empty, requiring users to manually paste boilerplate or rely on editor snippets that fire outside cp.nvim's control. Solution: add an optional template field to the language config. When set to a file path, its contents are written into every newly created solution buffer before the setup_code hook runs. Existing files are never overwritten.
This commit is contained in:
parent
ce5648f9cf
commit
2c25ec616a
2 changed files with 46 additions and 12 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
---@class CpLanguage
|
---@class CpLanguage
|
||||||
---@field extension string
|
---@field extension string
|
||||||
---@field commands CpLangCommands
|
---@field commands CpLangCommands
|
||||||
|
---@field template? string
|
||||||
|
|
||||||
---@class CpPlatformOverrides
|
---@class CpPlatformOverrides
|
||||||
---@field extension? string
|
---@field extension? string
|
||||||
|
|
@ -215,6 +216,10 @@ local function validate_language(id, lang)
|
||||||
commands = { lang.commands, { 'table' } },
|
commands = { lang.commands, { 'table' } },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if lang.template ~= nil then
|
||||||
|
vim.validate({ template = { lang.template, 'string' } })
|
||||||
|
end
|
||||||
|
|
||||||
if not lang.commands.run then
|
if not lang.commands.run then
|
||||||
error(('[cp.nvim] languages.%s.commands.run is required'):format(id))
|
error(('[cp.nvim] languages.%s.commands.run is required'):format(id))
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,25 @@ local logger = require('cp.log')
|
||||||
local scraper = require('cp.scraper')
|
local scraper = require('cp.scraper')
|
||||||
local state = require('cp.state')
|
local state = require('cp.state')
|
||||||
|
|
||||||
|
local function apply_template(bufnr, lang_id, platform)
|
||||||
|
local config = config_module.get_config()
|
||||||
|
local eff = config.runtime.effective[platform]
|
||||||
|
and config.runtime.effective[platform][lang_id]
|
||||||
|
if not eff or not eff.template then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local path = vim.fn.expand(eff.template)
|
||||||
|
if vim.fn.filereadable(path) ~= 1 then
|
||||||
|
logger.log(
|
||||||
|
('[cp.nvim] template not readable: %s'):format(path),
|
||||||
|
vim.log.levels.WARN
|
||||||
|
)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local lines = vim.fn.readfile(path)
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
|
||||||
|
end
|
||||||
|
|
||||||
---Get the language of the current file from cache
|
---Get the language of the current file from cache
|
||||||
---@return string?
|
---@return string?
|
||||||
local function get_current_file_language()
|
local function get_current_file_language()
|
||||||
|
|
@ -270,14 +289,17 @@ function M.setup_problem(problem_id, language)
|
||||||
mods = { silent = true, noautocmd = true, keepalt = true },
|
mods = { silent = true, noautocmd = true, keepalt = true },
|
||||||
})
|
})
|
||||||
state.set_solution_win(vim.api.nvim_get_current_win())
|
state.set_solution_win(vim.api.nvim_get_current_win())
|
||||||
if config.hooks and config.hooks.setup_code and not vim.b[prov.bufnr].cp_setup_done then
|
if not vim.b[prov.bufnr].cp_setup_done then
|
||||||
local ok = pcall(config.hooks.setup_code, state)
|
apply_template(prov.bufnr, lang, platform)
|
||||||
if ok then
|
if config.hooks and config.hooks.setup_code then
|
||||||
|
local ok = pcall(config.hooks.setup_code, state)
|
||||||
|
if ok then
|
||||||
|
vim.b[prov.bufnr].cp_setup_done = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
helpers.clearcol(prov.bufnr)
|
||||||
vim.b[prov.bufnr].cp_setup_done = true
|
vim.b[prov.bufnr].cp_setup_done = true
|
||||||
end
|
end
|
||||||
elseif not vim.b[prov.bufnr].cp_setup_done then
|
|
||||||
helpers.clearcol(prov.bufnr)
|
|
||||||
vim.b[prov.bufnr].cp_setup_done = true
|
|
||||||
end
|
end
|
||||||
cache.set_file_state(
|
cache.set_file_state(
|
||||||
vim.fn.fnamemodify(source_file, ':p'),
|
vim.fn.fnamemodify(source_file, ':p'),
|
||||||
|
|
@ -300,14 +322,21 @@ function M.setup_problem(problem_id, language)
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
state.set_solution_win(vim.api.nvim_get_current_win())
|
state.set_solution_win(vim.api.nvim_get_current_win())
|
||||||
require('cp.ui.views').ensure_io_view()
|
require('cp.ui.views').ensure_io_view()
|
||||||
if config.hooks and config.hooks.setup_code and not vim.b[bufnr].cp_setup_done then
|
if not vim.b[bufnr].cp_setup_done then
|
||||||
local ok = pcall(config.hooks.setup_code, state)
|
local is_new = vim.api.nvim_buf_line_count(bufnr) == 1
|
||||||
if ok then
|
and vim.api.nvim_buf_get_lines(bufnr, 0, 1, false)[1] == ''
|
||||||
|
if is_new then
|
||||||
|
apply_template(bufnr, lang, platform)
|
||||||
|
end
|
||||||
|
if config.hooks and config.hooks.setup_code then
|
||||||
|
local ok = pcall(config.hooks.setup_code, state)
|
||||||
|
if ok then
|
||||||
|
vim.b[bufnr].cp_setup_done = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
helpers.clearcol(bufnr)
|
||||||
vim.b[bufnr].cp_setup_done = true
|
vim.b[bufnr].cp_setup_done = true
|
||||||
end
|
end
|
||||||
elseif not vim.b[bufnr].cp_setup_done then
|
|
||||||
helpers.clearcol(bufnr)
|
|
||||||
vim.b[bufnr].cp_setup_done = true
|
|
||||||
end
|
end
|
||||||
cache.set_file_state(
|
cache.set_file_state(
|
||||||
vim.fn.expand('%:p'),
|
vim.fn.expand('%:p'),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue