2025-12-08 20:18:20 +00:00
|
|
|
local ls = require 'luasnip'
|
|
|
|
|
local s = ls.snippet
|
|
|
|
|
local sn = ls.snippet_node
|
|
|
|
|
local fn = ls.function_node
|
2025-12-09 10:35:51 +00:00
|
|
|
local ms = ls.multi_snippet
|
2025-12-08 20:18:20 +00:00
|
|
|
local t = ls.text_node
|
|
|
|
|
local c = ls.choice_node
|
|
|
|
|
local i = ls.insert_node
|
|
|
|
|
local f = ls.function_node
|
|
|
|
|
local d = ls.dynamic_node
|
|
|
|
|
local fmt = require('luasnip.extras.fmt').fmt
|
|
|
|
|
local rep = require('luasnip.extras').rep
|
|
|
|
|
local line_begin = require('luasnip.extras.conditions').line_begin
|
2025-12-17 16:52:51 +00:00
|
|
|
local line_end = require('luasnip.extras.conditions').line_end
|
2025-12-08 20:18:20 +00:00
|
|
|
local extend_decorator = require 'luasnip.util.extend_decorator'
|
|
|
|
|
local fmta = extend_decorator.apply(fmt, { delimiters = '#~' })
|
|
|
|
|
|
|
|
|
|
local utils = {}
|
|
|
|
|
|
|
|
|
|
--- Check if the trigger is at the beginning of a line
|
|
|
|
|
---@param line_to_cursor string
|
|
|
|
|
---@param matched_trigger string
|
|
|
|
|
---@return boolean
|
|
|
|
|
utils.line_begin = function(line_to_cursor, matched_trigger)
|
|
|
|
|
return line_to_cursor:sub(1, -(#matched_trigger + 1)):match '^%s*$'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Check if the trigger is on an empty line
|
|
|
|
|
---@param _ string
|
|
|
|
|
---@param matched_trigger string
|
|
|
|
|
---@return boolean
|
|
|
|
|
utils.empty_line = function(_, matched_trigger)
|
|
|
|
|
return vim.api.nvim_get_current_line():match('^%s*' .. vim.pesc(matched_trigger) .. '$')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Check if the trigger is at the start of a file
|
|
|
|
|
---@param line_to_cursor string
|
|
|
|
|
---@param matched_trigger string
|
|
|
|
|
---@return boolean
|
|
|
|
|
utils.file_begin = function(line_to_cursor, matched_trigger)
|
|
|
|
|
local line_number = vim.fn.line '.'
|
|
|
|
|
return line_number == 1 and line_begin(line_to_cursor, matched_trigger)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Check if the trigger is inside a string
|
|
|
|
|
---@return boolean
|
|
|
|
|
utils.in_string = function()
|
|
|
|
|
local node_type = vim.treesitter.get_node():type()
|
|
|
|
|
return node_type == 'string_content' or node_type == 'string'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Check if the trigger is inside a comment
|
|
|
|
|
---@return boolean
|
|
|
|
|
utils.in_comment = function()
|
|
|
|
|
local node_type = vim.treesitter.get_node():type()
|
|
|
|
|
return node_type == 'comment'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Check if the trigger is not inside a string or a comment
|
|
|
|
|
---@return boolean
|
|
|
|
|
utils.not_in_string_or_comment = function()
|
|
|
|
|
return (not utils.in_string()) and (not utils.in_comment())
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Create a basic auto expand trigger
|
|
|
|
|
---@param trigger string
|
|
|
|
|
---@param description? string
|
|
|
|
|
---@param options? table
|
|
|
|
|
---@return table
|
|
|
|
|
utils.tr = function(trigger, description, options)
|
|
|
|
|
return vim.tbl_extend('force', {
|
|
|
|
|
trig = trigger,
|
|
|
|
|
desc = description,
|
|
|
|
|
snippetType = 'autosnippet',
|
|
|
|
|
}, options or {})
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Create a trigger for an empty line snippet
|
|
|
|
|
---@param trigger string
|
|
|
|
|
---@param description? string
|
|
|
|
|
---@param options? table
|
|
|
|
|
---@return table
|
|
|
|
|
utils.etr = function(trigger, description, options)
|
|
|
|
|
return utils.tr(trigger, description, vim.tbl_extend('force', { condition = utils.empty_line }, options or {}))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Create a trigger for a comment trigger
|
|
|
|
|
---@param trigger string
|
|
|
|
|
---@param description? string
|
|
|
|
|
---@param options? table
|
|
|
|
|
---@return table
|
|
|
|
|
utils.ctr = function(trigger, description, options)
|
|
|
|
|
return utils.tr(trigger, description, vim.tbl_extend('force', { condition = utils.in_comment }, options or {}))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Create a trigger for a snippet to expand anywhere outside a string/comment
|
|
|
|
|
---@param trigger string
|
|
|
|
|
---@param description? string
|
|
|
|
|
---@param options? table
|
|
|
|
|
---@return table
|
|
|
|
|
utils.atr = function(trigger, description, options)
|
|
|
|
|
return utils.tr(
|
|
|
|
|
trigger,
|
|
|
|
|
description,
|
|
|
|
|
vim.tbl_extend('force', {
|
|
|
|
|
regTrig = true,
|
|
|
|
|
wordTrig = false,
|
|
|
|
|
condition = utils.not_in_string_or_comment,
|
|
|
|
|
}, options or {})
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
2025-12-17 16:52:51 +00:00
|
|
|
--- Create a trigger for a snippet to expand at the end of a line
|
|
|
|
|
---@param trigger string
|
|
|
|
|
---@param description? string
|
|
|
|
|
---@param options? table
|
|
|
|
|
---@return table
|
|
|
|
|
utils.Etr = function(trigger, description, options)
|
|
|
|
|
return utils.tr(
|
|
|
|
|
trigger,
|
|
|
|
|
description,
|
|
|
|
|
vim.tbl_extend('force', {
|
|
|
|
|
condition = line_end
|
|
|
|
|
}, options or {})
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
2025-12-08 20:18:20 +00:00
|
|
|
--- Create a snippet that will expand anywhere but in the middle of a word
|
|
|
|
|
---@param trigger any
|
|
|
|
|
---@param nodes any
|
|
|
|
|
---@param options? any
|
|
|
|
|
---@return table
|
|
|
|
|
utils.bs = function(trigger, nodes, options)
|
2025-12-09 10:35:51 +00:00
|
|
|
local btrigger
|
2025-12-08 20:18:20 +00:00
|
|
|
if type(trigger) == 'string' then
|
2025-12-09 10:35:51 +00:00
|
|
|
btrigger = utils.atr('([^%w_-])' .. trigger)
|
2025-12-08 20:18:20 +00:00
|
|
|
else
|
2025-12-09 10:35:51 +00:00
|
|
|
btrigger = vim.tbl_extend('keep', utils.atr('([^%w_-])' .. trigger.trig), trigger)
|
2025-12-08 20:18:20 +00:00
|
|
|
end
|
2025-12-09 10:35:51 +00:00
|
|
|
return ms(
|
|
|
|
|
{
|
|
|
|
|
trigger,
|
|
|
|
|
btrigger,
|
|
|
|
|
},
|
2025-12-08 20:18:20 +00:00
|
|
|
vim.list_extend({ fn(function(args, snip)
|
2025-12-09 10:35:51 +00:00
|
|
|
return snip.captures[1] or ''
|
2025-12-08 20:18:20 +00:00
|
|
|
end) }, nodes),
|
|
|
|
|
options
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return utils
|