From d2d91f7a01d0b8ead8b3e5ff7c3209a6aaf92ce2 Mon Sep 17 00:00:00 2001 From: arne314 <73391160+arne314@users.noreply.github.com> Date: Tue, 19 Nov 2024 01:55:11 +0100 Subject: [PATCH] feat: port most snippets from lentilus/fastex.nvim --- lua/typstar/autosnippets.lua | 58 +++++++++++++++++++++ lua/typstar/config.lua | 12 ++++- lua/typstar/init.lua | 1 + lua/typstar/snippets/document.lua | 34 +++++++++++++ lua/typstar/snippets/letters.lua | 38 ++++++++++++++ lua/typstar/snippets/math.lua | 74 +++++++++++++++++++++++++++ lua/typstar/snippets/matrix.lua | 83 +++++++++++++++++++++++++++++++ lua/typstar/snippets/visual.lua | 38 ++++++++++++++ 8 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 lua/typstar/autosnippets.lua create mode 100644 lua/typstar/snippets/document.lua create mode 100644 lua/typstar/snippets/letters.lua create mode 100644 lua/typstar/snippets/math.lua create mode 100644 lua/typstar/snippets/matrix.lua create mode 100644 lua/typstar/snippets/visual.lua diff --git a/lua/typstar/autosnippets.lua b/lua/typstar/autosnippets.lua new file mode 100644 index 0000000..94f7de7 --- /dev/null +++ b/lua/typstar/autosnippets.lua @@ -0,0 +1,58 @@ +local M = {} +local cfg = require('typstar.config').config.snippets +local luasnip = require('luasnip') +local fmta = require("luasnip.extras.fmt").fmta + +M.in_math = function() return vim.api.nvim_eval("typst#in_math()") == 1 end +M.in_markup = function() return vim.api.nvim_eval("typst#in_markup()") == 1 end +M.in_code = function() return vim.api.nvim_eval("typst#in_code()") == 1 end +M.in_comment = function() return vim.api.nvim_eval("typst#in_comment()") == 1 end +M.not_in_math = function() return not M.in_math() end +M.not_in_markup = function() return not M.in_markup() end +M.not_in_code = function() return not M.in_code() end +M.not_in_comment = function() return not M.in_comment() end + + +function M.cap(i) + return luasnip.function_node(function(_, snip) return snip.captures[i] end) +end + +function M.get_visual(args, parent) + if (#parent.snippet.env.LS_SELECT_RAW > 0) then + return luasnip.snippet_node(nil, luasnip.insert_node(1, parent.snippet.env.LS_SELECT_RAW)) + else -- If LS_SELECT_RAW is empty, return a blank insert node + return luasnip.snippet_node(nil, luasnip.insert_node(1)) + end +end + +function M.ri(insert_node_id) + return luasnip.function_node(function(args) return args[1][1] end, insert_node_id) +end + +function M.snip(trigger, expand, insert, condition, priority) + priority = priority or 1000 + return luasnip.snippet( + { trig = trigger, regTrig = true, wordtrig = false, priority = priority, snippetType = 'autosnippet' }, + fmta(expand, { unpack(insert) }), + { condition = condition } + ) +end + +function M.start_snip(trigger, expand, insert, condition, priority) + return M.snip('^%s*' .. trigger, expand, insert, condition, priority) +end + +function M.setup() + if cfg.enable then + local autosnippets = {} + for _, file in ipairs(cfg.modules) do + vim.list_extend( + autosnippets, + require(('typstar.snippets.%s'):format(file)) + ) + end + luasnip.add_snippets('typst', autosnippets) + end +end + +return M diff --git a/lua/typstar/config.lua b/lua/typstar/config.lua index b9af3b9..403d7d4 100644 --- a/lua/typstar/config.lua +++ b/lua/typstar/config.lua @@ -7,7 +7,17 @@ local default_config = { filename = 'drawing-%Y-%m-%d-%H-%M-%S', fileExtensionInserted = '.excalidraw.svg', obsidianOpenConfig = nil, - } + }, + snippets = { + enable = true, + modules = { + 'document', + 'letters', + 'math', + 'matrix', + 'visual', + } + }, } function M.merge_config(args) diff --git a/lua/typstar/init.lua b/lua/typstar/init.lua index 534c4fa..40908d8 100644 --- a/lua/typstar/init.lua +++ b/lua/typstar/init.lua @@ -7,6 +7,7 @@ M.setup = function(args) local excalidraw = require('typstar.excalidraw') vim.api.nvim_create_user_command('TypstarInsertExcalidraw', excalidraw.insert_drawing, {}) vim.api.nvim_create_user_command('TypstarOpenExcalidraw', excalidraw.open_drawing, {}) + require('typstar.autosnippets').setup() end return M diff --git a/lua/typstar/snippets/document.lua b/lua/typstar/snippets/document.lua new file mode 100644 index 0000000..2a93e57 --- /dev/null +++ b/lua/typstar/snippets/document.lua @@ -0,0 +1,34 @@ +local ls = require('luasnip') +local i = ls.insert_node +local d = ls.dynamic_node + +local helper = require('typstar.autosnippets') +local snip = helper.snip +local start = helper.start_snip +local markup = helper.in_markup + + +local ctheorems = { + { 'tem', 'theorem', markup }, + { 'pro', 'proof', markup }, + { 'axi', 'axiom', markup }, + { 'cor', 'corollary', markup }, + { 'lem', 'lemma', markup }, + { 'def', 'definition', markup }, + { 'exa', 'example', markup }, + { 'rem', 'remark', markup }, +} + +local ctheoremsstr = '#%s[\n\t<>\n]' +local document_snippets = {} + +for _, val in pairs(ctheorems) do + local snippet = start(val[1], string.format(ctheoremsstr, val[2]), { i(1) }, val[3]) + table.insert(document_snippets, snippet) +end + +return { + start('dm', '$\n\t<>\n$', { i(1) }, markup), + snip('ll', ' $<>$ ', { i(1, '1+1') }, markup), + unpack(document_snippets), +} diff --git a/lua/typstar/snippets/letters.lua b/lua/typstar/snippets/letters.lua new file mode 100644 index 0000000..6d07553 --- /dev/null +++ b/lua/typstar/snippets/letters.lua @@ -0,0 +1,38 @@ +local helper = require('typstar.autosnippets') +local snip = helper.snip + +local letters = { + { 'a', 'alpha' }, { 'A', 'Alpha' }, + { 'b', 'beta' }, { 'B', 'Beta' }, + { 'c', 'chi' }, { 'C', 'Chi' }, + { 'd', 'delta' }, { 'D', 'Delta' }, + { 'e', 'epsilon' }, { 'E', 'Epsilon' }, + { 'g', 'gamma' }, { 'G', 'Gamma' }, + { 'h', 'phi' }, { 'H', 'Phi' }, + { 'i', 'iotta' }, { 'I', 'Iotta' }, + { 'j', 'theta' }, { 'J', 'Theta' }, + { 'k', 'kappa' }, { 'K', 'Kappa' }, + { 'l', 'lambda' }, { 'L', 'Lambda' }, + { 'm', 'mu' }, { 'M', 'Mu' }, + { 'n', 'nu' }, { 'N', 'Nu' }, + { 'o', 'omega' }, { 'O', 'Omega' }, + { 'p', 'pi' }, { 'P', 'Pi' }, + { 'q', 'eta' }, { 'Q', 'Eta' }, + { 'r', 'rho' }, { 'R', 'Rho' }, + { 's', 'sigma' }, { 'S', 'Sigma' }, + { 't', 'tau' }, { 'T', 'Tau' }, + { 'x', 'xi' }, { 'X', 'xi' }, + { 'z', 'zeta' }, { 'Z', 'Zeta' }, +} + +local letter_snippets = {} + +for _, val in pairs(letters) do + table.insert(letter_snippets, snip(';' .. val[1], val[2], {}, helper.in_math)) + table.insert(letter_snippets, snip(';' .. val[1], '$' .. val[2] .. '$ ', {}, helper.in_markup)) + table.insert(letter_snippets, snip(':' .. val[1], '$' .. val[1] .. '$ ', {}, helper.in_markup)) +end + +return { + unpack(letter_snippets) +} diff --git a/lua/typstar/snippets/math.lua b/lua/typstar/snippets/math.lua new file mode 100644 index 0000000..6204bab --- /dev/null +++ b/lua/typstar/snippets/math.lua @@ -0,0 +1,74 @@ +local ls = require('luasnip') +local i = ls.insert_node + +local helper = require('typstar.autosnippets') +local snip = helper.snip +local math = helper.in_math +local cap = helper.cap + +return { + snip('fa', 'forall ', {}, math), + snip('ex', 'exists ', {}, math), + snip('ni', 'in.not ', {}, math), + + -- logical chunks + snip('fen', 'forall epsilon>>0 ', {}, math), + snip('fdn', 'forall delta>>0 ', {}, math), + snip('edn', 'exists delta>>0 ', {}, math), + snip('een', 'exists epsilon>>0 ', {}, math), + + -- boolean logic + snip('an', 'and ', {}, math), + snip('no', 'not ', {}, math), + + -- relations + snip('el', '=', {}, math), + snip('df', ':=', {}, math), + snip('lt', '<<', {}, math), + snip('gt', '>>', {}, math), + snip('le', '<<= ', {}, math), + snip('ne', '!= ', {}, math), + snip('ge', '>>= ', {}, math), + + -- operators + snip('(.*)sk', '<>+', { cap(1) }, math), + snip('(.*)ak', '<>-', { cap(1) }, math), + snip('oak', 'plus.circle ', {}, math, 1100), + snip('bak', 'plus.square ', {}, math, 1100), + snip('xx', 'times ', {}, math), + snip('oxx', 'times.circle ', {}, math), + snip('bxx', 'times.square ', {}, math), + + -- sets + snip('set', '{<>}', { i(1) }, math), + snip('es', 'emptyset ', {}, math), + snip('ses', '{emptyset}', {}, math), + snip('sp', 'supset ', {}, math), + snip('sb', 'subset ', {}, math), + snip('sep', 'supset.eq ', {}, math), + snip('seb', 'subset.eq ', {}, math), + snip('nn', 'sect ', {}, math), + snip('uu', 'union ', {}, math), + snip('bnn', 'sect.big', {}, math, 1100), + snip('buu', 'untion.big', {}, math, 1100), + snip('swo', 'without ', {}, math), + + -- misc + snip('to', '->> ', {}, math), + snip('mt', '|->> ', {}, math), + snip('Oo', 'compose ', {}, math), + snip('iso', 'tilde.equiv ', {}, math), + snip('rrn', 'RR^n', {}, math), + snip('cc', 'cases(\n\t<>\n)\\', { i(1, '1') }, math), + snip('(.*)iv', '<>^(-1)', { cap(1) }, math), + snip('(.*)sr', '<>^(2)', { cap(1) }, math), + snip('(.*)rd', '<>^(<>)', { cap(1), i(1, 'n') }, math), + + snip('ddx', '(d <>)(d <>)', { i(1, 'f'), i(2, 'x') }, math), + snip('it', 'integral_(<>)^(<>)', { i(1, 'a'), i(2, 'b') }, math), + snip('oit', 'integral_(Omega}', {}, math), + snip('dit', 'integral_{<>}', { i(1, 'Omega') }, math), + snip('sm', 'sum_(<>)^(<>)', { i(1, 'i=0'), i(2, 'oo') }, math), + snip('lm', 'lim <> ', { i(1, 'n') }, math), + snip('lim', 'lim_(<> ->> <>) <> ', { i(1, 'n'), i(2, 'oo'), i(3) }, math), +} diff --git a/lua/typstar/snippets/matrix.lua b/lua/typstar/snippets/matrix.lua new file mode 100644 index 0000000..bb077da --- /dev/null +++ b/lua/typstar/snippets/matrix.lua @@ -0,0 +1,83 @@ +local ls = require('luasnip') +local i = ls.insert_node +local d = ls.dynamic_node +local sn = ls.snippet_node +local t = ls.text_node +local r = ls.restore_node + +local helper = require('typstar.autosnippets') +local snip = helper.snip +local math = helper.in_math + +-- generating function +local mat = function(_, sp) + local rows = tonumber(sp.captures[1]) + local cols = tonumber(sp.captures[2]) + local nodes = {} + local ins_indx = 1 + for j = 1, rows do + if j == 1 then + table.insert(nodes, r(ins_indx, tostring(j) .. 'x1', i(1, '1'))) + else + table.insert(nodes, r(ins_indx, tostring(j) .. 'x1', i(1, ' '))) + end + ins_indx = ins_indx + 1 + for k = 2, cols do + table.insert(nodes, t(', ')) + if j == k then + table.insert(nodes, r(ins_indx, tostring(j) .. 'x' .. tostring(k), i(1, '1'))) + else + table.insert(nodes, r(ins_indx, tostring(j) .. 'x' .. tostring(k), i(1, ' '))) + end + ins_indx = ins_indx + 1 + end + table.insert(nodes, t({ ';', '\t' })) + end + nodes[#nodes] = t(';') + return sn(nil, nodes) +end + +local lmat = function(_, sp) + local rows = tonumber(sp.captures[1]) + local cols = tonumber(sp.captures[2]) + local nodes = {} + local ins_indx = 1 + for j = 1, rows do + if j == rows then + for k = 1, cols + 1 do + if k == cols then + table.insert(nodes, t('dots.down, ')) + else + table.insert(nodes, t('dots.v, ')) + end + end + table.insert(nodes, t({ ';', '\t' })) + end + if j == 1 then + table.insert(nodes, r(ins_indx, tostring(j) .. 'x1', i(1, '1'))) + else + table.insert(nodes, r(ins_indx, tostring(j) .. 'x1', i(1, '0'))) + end + ins_indx = ins_indx + 1 + for k = 2, cols do + table.insert(nodes, t(', ')) + if k == cols then + table.insert(nodes, t('dots, ')) + end + if j == k then + table.insert(nodes, r(ins_indx, tostring(j) .. 'x' .. tostring(k), i(1, '1'))) + else + table.insert(nodes, r(ins_indx, tostring(j) .. 'x' .. tostring(k), i(1, '0'))) + end + ins_indx = ins_indx + 1 + end + table.insert(nodes, t({ ';', '\t' })) + end + nodes[#nodes] = t(';') + return sn(nil, nodes) +end + +return { + snip('(%d)(%d)ma', 'mat(\n\t<>\n)', { d(1, mat) }, math), + snip('(%d)(%d)lma', 'mat(\n\t<>\n)', { d(1, lmat) }, math), +} diff --git a/lua/typstar/snippets/visual.lua b/lua/typstar/snippets/visual.lua new file mode 100644 index 0000000..363a313 --- /dev/null +++ b/lua/typstar/snippets/visual.lua @@ -0,0 +1,38 @@ +local ls = require('luasnip') +local i = ls.insert_node +local d = ls.dynamic_node + +local helper = require('typstar.autosnippets') +local math = helper.in_math +local snip = helper.snip +local cap = helper.cap +local get_visual = helper.get_visual + +local snippets = {} +local operations = { + { 'vi', '1/(', ')' }, + { 'rb', '(', ')' }, + { 'sq', '[', ']' }, + { 'abs', '|', '|' }, + { 'ul', 'underline(', ')' }, + { 'ol', 'overline(', ')' }, + { 'ht', 'hat(', ')' }, + { 'br', 'macron(', ')' }, + { 'dt', 'dot(', ')' }, + { 'ci', 'circle(', ')' }, + { 'td', 'tilde(', ')' }, + { 'nr', 'norm(', ')' }, + { 'vv', 'vec(', ')' }, + { 'rt', 'sqrt(', ')' }, +} + +for _, val in pairs(operations) do + table.insert(snippets, snip(val[1], val[2] .. '<>' .. val[3], { d(1, get_visual) }, math, 1200)) + table.insert(snippets, + snip('(%s)([^%s]*)' .. val[1], '<>' .. val[2] .. '<>' .. val[3], { cap(1), cap(2) }, math, 1100)) + table.insert(snippets, snip('%s' .. val[1], val[2] .. '<>' .. val[3], { i(1, '1') }, math)) +end + +return { + unpack(snippets) +}