Skip to content

File templates

dcampos edited this page Nov 6, 2023 · 6 revisions

Note: there is now a plugin that provides this functionality out of the box: karamellpelle/nvim-skeletty.


The Lua module below adds the ability to expand snippets as file templates. Save it as lua/template.lua, put your snippets named <filetype>.snippet or <filetype>/<template-name>.snippet in ~/.config/nvim/templates/ and create a BufNewFile autocmd to expand them.

local function list_templates()
    local ft = vim.bo.ft
    if not ft or ft == '' then
        return {}
    end
    local templates = {}
    for _, expr in ipairs({
        'templates/' .. ft .. '.snippet',
        'templates/' .. ft .. '/*.snippet'
    }) do
        vim.list_extend(templates, vim.fn.globpath(vim.o.rtp, expr, false, true))
    end
    return templates
end

local function expand_template(tpl_file)
    local file = io.open(tpl_file)
    local text = file:read('*a')
    text = text:gsub('\n$', '')
    local body = vim.split(text, '\n')
    local snip = {
        kind = 'snipmate',
        prefix = '',
        description = '',
        body = body
    }
    local ok, snippy = pcall(require, 'snippy')
    if not ok then return end
    return snippy.expand_snippet(snip, '')
end

local function expand()
    local templates = list_templates()
    if #templates == 1 then
        expand_template(templates[1])
    elseif #templates > 1 then
        -- show menu
         vim.ui.select(templates, {
             prompt = 'Select template to expand:',
         }, function(selected)
            expand_template(selected)
         end)
    end
end

return {
    expand = expand
}

The autocmd would look like this in Vimscript:

augroup after_plugin_templates
    autocmd!
    autocmd BufNewFile *.* lua require 'template'.expand()
augroup END
Clone this wiki locally