diff --git a/lua/typstar/autosnippets.lua b/lua/typstar/autosnippets.lua index bbf8029..002bdf4 100644 --- a/lua/typstar/autosnippets.lua +++ b/lua/typstar/autosnippets.lua @@ -32,23 +32,34 @@ function M.cap(i) return luasnip.function_node(function(_, snip) return snip.captures[i] end) end -function M.leading_white_spaces(i) - -- isolate whitespaces of captured group - return luasnip.function_node(function(_, snip) - local capture = snip.captures[i] or '' -- Return capture or empty string if nil - -- Extract only leading whitespace using pattern matching - local whitespace = capture:match('^%s*') or '' - return whitespace - end) +local compute_leading_white_spaces = function(snip, i) + local capture = snip.captures[i] or '' + return capture:match('^%s*') or '' end -function M.visual(idx, default) +function M.leading_white_spaces(i) + return luasnip.function_node(function(_, snip) return compute_leading_white_spaces(snip, i) end) +end + +function M.visual(idx, default, line_prefix, indent_capture_idx) default = default or '' - return luasnip.dynamic_node(idx, function(args, parent) - if #parent.snippet.env.LS_SELECT_RAW > 0 then - return luasnip.snippet_node(nil, luasnip.text_node(parent.snippet.env.LS_SELECT_RAW)) + line_prefix = line_prefix or '' + return luasnip.dynamic_node(idx, function(_, snip) + local select_raw = snip.snippet.env.LS_SELECT_RAW + if #select_raw > 0 then + if line_prefix ~= '' then -- e.g. indentation + for i, s in ipairs(select_raw) do + select_raw[i] = line_prefix .. s + end + end + return luasnip.snippet_node(nil, luasnip.text_node(select_raw)) else -- If LS_SELECT_RAW is empty, return an insert node - return luasnip.snippet_node(nil, luasnip.insert_node(1, default)) + local leading = '' + if indent_capture_idx ~= nil then leading = compute_leading_white_spaces(snip, indent_capture_idx) end + return luasnip.snippet_node(nil, { + luasnip.text_node(leading .. line_prefix), + luasnip.insert_node(1, default), + }) end end) end diff --git a/lua/typstar/snippets/markup.lua b/lua/typstar/snippets/markup.lua index b621cd3..0ca394c 100644 --- a/lua/typstar/snippets/markup.lua +++ b/lua/typstar/snippets/markup.lua @@ -4,10 +4,11 @@ local i = ls.insert_node local helper = require('typstar.autosnippets') local cap = helper.cap local markup = helper.in_markup -local visual = helper.visual local snip = helper.snip local start = helper.start_snip +local indent_visual = function(idx, default) return helper.visual(idx, default or '', '\t', 1) end + local ctheorems = { { 'tem', 'theorem' }, { 'pro', 'proof' }, @@ -29,29 +30,24 @@ local wrappings = { } local document_snippets = {} -local ctheoremsstr = '#%s[\n<>\t<>\n<>]' +local ctheoremsstr = '#%s[\n<>\n<>]' local wrappingsstr = '%s<>%s' for _, val in pairs(ctheorems) do - local snippet = start(val[1], string.format(ctheoremsstr, val[2]), { cap(1), visual(1), cap(1) }, markup) + local snippet = start(val[1], string.format(ctheoremsstr, val[2]), { indent_visual(1), cap(1) }, markup) table.insert(document_snippets, snippet) end for _, val in pairs(wrappings) do - local snippet = snip(val[1], string.format(wrappingsstr, val[2], val[3]), { visual(1, val[4]) }, markup) + local snippet = snip(val[1], string.format(wrappingsstr, val[2], val[3]), { helper.visual(1, val[4]) }, markup) table.insert(document_snippets, snippet) end return { - start('dm', '$\n<>\t<>\n<>$', { cap(1), visual(1), cap(1) }, markup), - helper.start_snip_in_newl( - 'dm', - '$\n<>\t<>\n<>$', - { helper.leading_white_spaces(1), visual(1), helper.leading_white_spaces(1) }, - markup - ), - start('fla', '#flashcard(0)[<>][\n<>\t<>\n<>]', { i(1, 'flashcard'), cap(1), visual(2), cap(1) }, markup), - start('flA', '#flashcard(0, "<>")[\n<>\t<>\n<>]', { i(1, 'flashcard'), cap(1), visual(2), cap(1) }, markup), + start('dm', '$\n<>\n<>$', { indent_visual(1), cap(1) }, markup), + helper.start_snip_in_newl('dm', '$\n<>\n<>$', { indent_visual(1), helper.leading_white_spaces(1) }, markup), + start('fla', '#flashcard(0)[<>][\n<>\n<>]', { i(1, 'flashcard'), indent_visual(2), cap(1) }, markup), + start('flA', '#flashcard(0, "<>")[\n<>\n<>]', { i(1, 'flashcard'), indent_visual(2), cap(1) }, markup), snip('IMP', '$==>>$ ', {}, markup), snip('IFF', '$<<==>>$ ', {}, markup), unpack(document_snippets),