mirror of
https://github.com/Ascyii/typstar.git
synced 2026-01-01 05:24:24 -05:00
27
flake.lock
generated
27
flake.lock
generated
@@ -5,11 +5,11 @@
|
|||||||
"nixpkgs-lib": "nixpkgs-lib"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1736143030,
|
"lastModified": 1743550720,
|
||||||
"narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=",
|
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de",
|
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1737525964,
|
"lastModified": 1746518791,
|
||||||
"narHash": "sha256-3wFonKmNRWKq1himW9N3TllbeGIHFACI5vmLpk6moF8=",
|
"narHash": "sha256-MiJ11L7w18S2G5ftcoYtcrrS0JFqBaj9d5rwJFpC5Wk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5757bbb8bd7c0630a0cc4bb19c47e588db30b97c",
|
"rev": "1cb1c02a6b1b7cf67e3d7731cbbf327a53da9679",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -36,14 +36,17 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-lib": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1735774519,
|
"lastModified": 1743296961,
|
||||||
"narHash": "sha256-CewEm1o2eVAnoqb6Ml+Qi9Gg/EfNAxbRx1lANGVyoLI=",
|
"narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=",
|
||||||
"type": "tarball",
|
"owner": "nix-community",
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/e9b51731911566bbf7e4895475a87fe06961de0b.tar.gz"
|
"repo": "nixpkgs.lib",
|
||||||
|
"rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa",
|
||||||
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"owner": "nix-community",
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/e9b51731911566bbf7e4895475a87fe06961de0b.tar.gz"
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
|
|||||||
@@ -28,6 +28,10 @@
|
|||||||
pkgs.vimPlugins.luasnip
|
pkgs.vimPlugins.luasnip
|
||||||
pkgs.vimPlugins.nvim-treesitter-parsers.typst
|
pkgs.vimPlugins.nvim-treesitter-parsers.typst
|
||||||
];
|
];
|
||||||
|
# TODO: make this check pass instead of skipping
|
||||||
|
neovimRequireCheckHook = ''
|
||||||
|
echo "Skipping neovimRequireCheckHook"
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
packages = {
|
packages = {
|
||||||
@@ -43,7 +47,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
require('luasnip').config.set_config({
|
require('luasnip').config.set_config({
|
||||||
enable_autosnippets = true,
|
enable_autosnippets = true,
|
||||||
|
store_selection_keys = "<Tab>",
|
||||||
})
|
})
|
||||||
|
|
||||||
require('typstar').setup()
|
require('typstar').setup()
|
||||||
|
|||||||
@@ -32,23 +32,34 @@ function M.cap(i)
|
|||||||
return luasnip.function_node(function(_, snip) return snip.captures[i] end)
|
return luasnip.function_node(function(_, snip) return snip.captures[i] end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.leading_white_spaces(i)
|
local compute_leading_white_spaces = function(snip, i)
|
||||||
-- isolate whitespaces of captured group
|
local capture = snip.captures[i] or ''
|
||||||
return luasnip.function_node(function(_, snip)
|
return capture:match('^%s*') or ''
|
||||||
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)
|
|
||||||
end
|
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 ''
|
default = default or ''
|
||||||
return luasnip.dynamic_node(idx, function(args, parent)
|
line_prefix = line_prefix or ''
|
||||||
if #parent.snippet.env.LS_SELECT_RAW > 0 then
|
return luasnip.dynamic_node(idx, function(_, snip)
|
||||||
return luasnip.snippet_node(nil, luasnip.text_node(parent.snippet.env.LS_SELECT_RAW))
|
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
|
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)
|
end)
|
||||||
end
|
end
|
||||||
@@ -57,14 +68,18 @@ function M.ri(insert_node_id)
|
|||||||
return luasnip.function_node(function(args) return args[1][1] end, insert_node_id)
|
return luasnip.function_node(function(args) return args[1][1] end, insert_node_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.snip(trigger, expand, insert, condition, priority, wordTrig, maxTrigLength)
|
function M.snip(trigger, expand, insert, condition, priority, trigOptions)
|
||||||
priority = priority or 1000
|
priority = priority or 1000
|
||||||
if wordTrig == nil then wordTrig = true end
|
trigOptions = vim.tbl_deep_extend('force', {
|
||||||
|
maxTrigLength = nil,
|
||||||
|
wordTrig = true,
|
||||||
|
blacklist = {},
|
||||||
|
}, trigOptions or {})
|
||||||
return luasnip.snippet(
|
return luasnip.snippet(
|
||||||
{
|
{
|
||||||
trig = trigger,
|
trig = trigger,
|
||||||
trigEngine = M.engine,
|
trigEngine = M.engine,
|
||||||
trigEngineOpts = { condition = condition, wordTrig = wordTrig, maxTrigLength = maxTrigLength },
|
trigEngineOpts = vim.tbl_deep_extend('keep', { condition = condition }, trigOptions),
|
||||||
wordTrig = false,
|
wordTrig = false,
|
||||||
priority = priority,
|
priority = priority,
|
||||||
snippetType = 'autosnippet',
|
snippetType = 'autosnippet',
|
||||||
@@ -76,18 +91,18 @@ function M.snip(trigger, expand, insert, condition, priority, wordTrig, maxTrigL
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.start_snip(trigger, expand, insert, condition, priority)
|
function M.start_snip(trigger, expand, insert, condition, priority, trigOptions)
|
||||||
return M.snip('^(\\s*)' .. trigger, '<>' .. expand, { M.cap(1), unpack(insert) }, condition, priority)
|
return M.snip('^(\\s*)' .. trigger, '<>' .. expand, { M.cap(1), unpack(insert) }, condition, priority, trigOptions)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.start_snip_in_newl(trigger, expand, insert, condition, priority)
|
function M.start_snip_in_newl(trigger, expand, insert, condition, priority, trigOptions)
|
||||||
return M.snip(
|
return M.snip(
|
||||||
'([^\\s]\\s+)' .. trigger,
|
'([^\\s]\\s+)' .. trigger,
|
||||||
'<>\n<>' .. expand,
|
'<>\n<>' .. expand,
|
||||||
{ M.cap(1), M.leading_white_spaces(1), unpack(insert) },
|
{ M.cap(1), M.leading_white_spaces(1), unpack(insert) },
|
||||||
condition,
|
condition,
|
||||||
priority,
|
priority,
|
||||||
false
|
vim.tbl_deep_extend('keep', { wordTrig = false }, trigOptions or {})
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -99,7 +114,7 @@ function M.engine(trigger, opts)
|
|||||||
-- determine possibly max/fixed length of trigger
|
-- determine possibly max/fixed length of trigger
|
||||||
local max_length = opts.maxTrigLength
|
local max_length = opts.maxTrigLength
|
||||||
local is_fixed_length = false
|
local is_fixed_length = false
|
||||||
if alts_regex ~= '' and not trigger:match('[%+%*]') then
|
if max_length == nil and alts_regex ~= '' and not trigger:match('[%+%*]') then
|
||||||
max_length = #trigger
|
max_length = #trigger
|
||||||
- utils.count_string(trigger, '\\')
|
- utils.count_string(trigger, '\\')
|
||||||
- utils.count_string(trigger, '%(')
|
- utils.count_string(trigger, '%(')
|
||||||
@@ -137,10 +152,11 @@ function M.engine(trigger, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- matching
|
-- matching
|
||||||
return function(line, trig)
|
return function(line_full, trig)
|
||||||
if not M.snippets_toggle or not condition() then return nil end
|
if not M.snippets_toggle or not condition() then return nil end
|
||||||
|
local first_idx = 1
|
||||||
if max_length ~= nil then
|
if max_length ~= nil then
|
||||||
local first_idx = #line - max_length -- include additional char for wordtrig
|
first_idx = #line_full - max_length -- include additional char for wordtrig
|
||||||
if first_idx < 0 then
|
if first_idx < 0 then
|
||||||
if is_fixed_length then
|
if is_fixed_length then
|
||||||
return nil
|
return nil
|
||||||
@@ -149,10 +165,10 @@ function M.engine(trigger, opts)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if first_idx > 0 then
|
if first_idx > 0 then
|
||||||
if string.byte(line, first_idx) > 127 then return nil end
|
if string.byte(line_full, first_idx) > 127 then return nil end
|
||||||
end
|
end
|
||||||
line = line:sub(first_idx)
|
|
||||||
end
|
end
|
||||||
|
local line = line_full:sub(first_idx)
|
||||||
local whole, captures = base_engine(line, trig)
|
local whole, captures = base_engine(line, trig)
|
||||||
if whole == nil then return nil end
|
if whole == nil then return nil end
|
||||||
|
|
||||||
@@ -161,6 +177,11 @@ function M.engine(trigger, opts)
|
|||||||
if opts.wordTrig and from ~= 1 and string.match(string.sub(line, from - 1, from - 1), '[%w.]') ~= nil then
|
if opts.wordTrig and from ~= 1 and string.match(string.sub(line, from - 1, from - 1), '[%w.]') ~= nil then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- blacklist
|
||||||
|
for _, w in ipairs(opts.blacklist) do
|
||||||
|
if line_full:sub(-#w) == w then return nil end
|
||||||
|
end
|
||||||
return whole, captures
|
return whole, captures
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -177,7 +198,7 @@ function M.setup()
|
|||||||
jsregexp_ok, jsregexp = pcall(require, 'jsregexp')
|
jsregexp_ok, jsregexp = pcall(require, 'jsregexp')
|
||||||
end
|
end
|
||||||
if jsregexp_ok then
|
if jsregexp_ok then
|
||||||
alts_regex = jsregexp.compile_safe(alts_regex)
|
if type(alts_regex) == 'string' then alts_regex = jsregexp.compile_safe(alts_regex) end
|
||||||
else
|
else
|
||||||
alts_regex = ''
|
alts_regex = ''
|
||||||
vim.notify("WARNING: Most snippets won't work as jsregexp is not installed", vim.log.levels.WARN)
|
vim.notify("WARNING: Most snippets won't work as jsregexp is not installed", vim.log.levels.WARN)
|
||||||
|
|||||||
@@ -116,8 +116,7 @@ return {
|
|||||||
{ d(1, get_index, {}, { user_args = { 1, 2, false } }), d(2, prepend_space, {}, { user_args = { 3 } }) },
|
{ d(1, get_index, {}, { user_args = { 1, 2, false } }), d(2, prepend_space, {}, { user_args = { 3 } }) },
|
||||||
markup,
|
markup,
|
||||||
500,
|
500,
|
||||||
true,
|
{ maxTrigLength = 13 }
|
||||||
13
|
|
||||||
),
|
),
|
||||||
snip(
|
snip(
|
||||||
'(' .. trigger_index_pre .. ')' .. '(' .. trigger_index_post .. ')([^\\w])',
|
'(' .. trigger_index_pre .. ')' .. '(' .. trigger_index_post .. ')([^\\w])',
|
||||||
@@ -125,14 +124,13 @@ return {
|
|||||||
{ d(1, get_index, {}, { user_args = { 1, 2, true } }), d(2, prepend_space, {}, { user_args = { 3 } }) },
|
{ d(1, get_index, {}, { user_args = { 1, 2, true } }), d(2, prepend_space, {}, { user_args = { 3 } }) },
|
||||||
math,
|
math,
|
||||||
200,
|
200,
|
||||||
true,
|
{ maxTrigLength = 10 } -- epsilon123
|
||||||
10 -- epsilon123
|
|
||||||
),
|
),
|
||||||
|
|
||||||
-- series of numbered letters
|
-- series of numbered letters
|
||||||
snip('(' .. trigger_index_pre .. ') ot ', '<>_1, <>_2, ... ', { cap(1), cap(1) }, math), -- a_1, a_2, ...
|
snip('(' .. trigger_index_pre .. ') ot ', '<>_1, <>_2, ... ', { cap(1), cap(1) }, math), -- a_1, a_2, ...
|
||||||
snip('(' .. trigger_index_pre .. ') ot(\\w+) ', '<> ', { d(1, get_series) }, math, 1000, true, 13), -- a_1, a_2, ... a_j or a_1, a_2, a_2, a_3, a_4, a_5
|
snip('(' .. trigger_index_pre .. ') ot(\\w+) ', '<> ', { d(1, get_series) }, math, 1000, { maxTrigLength = 13 }), -- a_1, a_2, ... a_j or a_1, a_2, a_2, a_3, a_4, a_5
|
||||||
|
|
||||||
-- misc
|
-- misc
|
||||||
snip('(' .. trigger_index_pre .. ')bl', 'B_<> (<>)', { cap(1), i(1, 'x_0') }, math),
|
snip('(' .. trigger_index_pre .. ')bl', 'B_<> (<>) ', { cap(1), i(1, 'x_0') }, math, 100),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ local i = ls.insert_node
|
|||||||
local helper = require('typstar.autosnippets')
|
local helper = require('typstar.autosnippets')
|
||||||
local cap = helper.cap
|
local cap = helper.cap
|
||||||
local markup = helper.in_markup
|
local markup = helper.in_markup
|
||||||
local visual = helper.visual
|
|
||||||
local snip = helper.snip
|
local snip = helper.snip
|
||||||
local start = helper.start_snip
|
local start = helper.start_snip
|
||||||
|
|
||||||
|
local indent_visual = function(idx, default) return helper.visual(idx, default or '', '\t', 1) end
|
||||||
|
|
||||||
local ctheorems = {
|
local ctheorems = {
|
||||||
{ 'tem', 'theorem' },
|
{ 'tem', 'theorem' },
|
||||||
{ 'pro', 'proof' },
|
{ 'pro', 'proof' },
|
||||||
|
{ 'prp', 'proposition' },
|
||||||
{ 'axi', 'axiom' },
|
{ 'axi', 'axiom' },
|
||||||
{ 'cor', 'corollary' },
|
{ 'cor', 'corollary' },
|
||||||
{ 'lem', 'lemma' },
|
{ 'lem', 'lemma' },
|
||||||
@@ -28,29 +30,24 @@ local wrappings = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local document_snippets = {}
|
local document_snippets = {}
|
||||||
local ctheoremsstr = '#%s[\n<>\t<>\n<>]'
|
local ctheoremsstr = '#%s[\n<>\n<>]'
|
||||||
local wrappingsstr = '%s<>%s'
|
local wrappingsstr = '%s<>%s'
|
||||||
|
|
||||||
for _, val in pairs(ctheorems) do
|
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)
|
table.insert(document_snippets, snippet)
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, val in pairs(wrappings) do
|
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)
|
table.insert(document_snippets, snippet)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start('dm', '$\n<>\t<>\n<>$', { cap(1), visual(1), cap(1) }, markup),
|
start('dm', '$\n<>\n<>$', { indent_visual(1), cap(1) }, markup),
|
||||||
helper.start_snip_in_newl(
|
helper.start_snip_in_newl('dm', '$\n<>\n<>$', { indent_visual(1), helper.leading_white_spaces(1) }, markup),
|
||||||
'dm',
|
start('fla', '#flashcard(0)[<>][\n<>\n<>]', { i(1, 'flashcard'), indent_visual(2), cap(1) }, markup),
|
||||||
'$\n<>\t<>\n<>$',
|
start('flA', '#flashcard(0, "<>")[\n<>\n<>]', { i(1, 'flashcard'), indent_visual(2), cap(1) }, markup),
|
||||||
{ 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),
|
|
||||||
snip('IMP', '$==>>$ ', {}, markup),
|
snip('IMP', '$==>>$ ', {}, markup),
|
||||||
snip('IFF', '$<<==>>$ ', {}, markup),
|
snip('IFF', '$<<==>>$ ', {}, markup),
|
||||||
unpack(document_snippets),
|
unpack(document_snippets),
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ return {
|
|||||||
snip('een', 'exists epsilon>>0 ', {}, math),
|
snip('een', 'exists epsilon>>0 ', {}, math),
|
||||||
|
|
||||||
-- boolean logic
|
-- boolean logic
|
||||||
snip('no', 'not ', {}, math),
|
snip('not', 'not ', {}, math),
|
||||||
snip('ip', '==>> ', {}, math),
|
snip('ip', '==>> ', {}, math),
|
||||||
snip('ib', '<<== ', {}, math),
|
snip('ib', '<<== ', {}, math),
|
||||||
snip('iff', '<<==>> ', {}, math),
|
snip('iff', '<<==>> ', {}, math),
|
||||||
@@ -34,8 +34,8 @@ return {
|
|||||||
snip('ge', '>>= ', {}, math),
|
snip('ge', '>>= ', {}, math),
|
||||||
|
|
||||||
-- operators
|
-- operators
|
||||||
snip('ak([^k ])', '+ <>', { cap(1) }, math, 100, false),
|
snip('ak([^k ])', '+ <>', { cap(1) }, math, 100, { wordTrig = false }),
|
||||||
snip('sk([^k ])', '- <>', { cap(1) }, math, 100, false),
|
snip('sk([^k ])', '- <>', { cap(1) }, math, 100, { wordTrig = false }),
|
||||||
snip('oak', 'plus.circle ', {}, math),
|
snip('oak', 'plus.circle ', {}, math),
|
||||||
snip('bak', 'plus.square ', {}, math),
|
snip('bak', 'plus.square ', {}, math),
|
||||||
snip('mak', 'plus.minus ', {}, math),
|
snip('mak', 'plus.minus ', {}, math),
|
||||||
@@ -45,11 +45,11 @@ return {
|
|||||||
snip('ff', '(<>) / (<>) <>', { i(1, 'a'), i(2, 'b'), i(3) }, math),
|
snip('ff', '(<>) / (<>) <>', { i(1, 'a'), i(2, 'b'), i(3) }, math),
|
||||||
|
|
||||||
-- exponents
|
-- exponents
|
||||||
snip('iv', '^(-1) ', {}, math, 500, false),
|
snip('iv', '^(-1) ', {}, math, 500, { wordTrig = false, blacklist = { 'equiv' } }),
|
||||||
snip('sr', '^2 ', {}, math, 500, false),
|
snip('sr', '^2 ', {}, math, 500, { wordTrig = false }),
|
||||||
snip('cb', '^3 ', {}, math, 500, false),
|
snip('cb', '^3 ', {}, math, 500, { wordTrig = false }),
|
||||||
snip('jj', '_(<>) ', { i(1, 'n') }, math, 500, false),
|
snip('jj', '_(<>) ', { i(1, 'n') }, math, 500, { wordTrig = false }),
|
||||||
snip('kk', '^(<>) ', { i(1, 'n') }, math, 500, false),
|
snip('kk', '^(<>) ', { i(1, 'n') }, math, 500, { wordTrig = false }),
|
||||||
snip('ep', 'exp(<>) ', { i(1, '1') }, math),
|
snip('ep', 'exp(<>) ', { i(1, '1') }, math),
|
||||||
|
|
||||||
-- sets
|
-- sets
|
||||||
@@ -73,6 +73,10 @@ return {
|
|||||||
snip('Oo', 'compose ', {}, math),
|
snip('Oo', 'compose ', {}, math),
|
||||||
snip('iso', 'tilde.equiv ', {}, math),
|
snip('iso', 'tilde.equiv ', {}, math),
|
||||||
snip('cc', 'cases(\n\t<>\n)\\', { i(1, '1') }, math),
|
snip('cc', 'cases(\n\t<>\n)\\', { i(1, '1') }, math),
|
||||||
|
snip('([A-Za-z])o([A-Za-z0-9])', '<>(<>) ', { cap(1), cap(2) }, math, 100, {
|
||||||
|
maxTrigLength = 3,
|
||||||
|
blacklist = { 'bot', 'cos', 'col', 'com', 'con', 'dol', 'dot', 'loz', 'mod', 'top', 'won', 'xor' },
|
||||||
|
}),
|
||||||
snip('(K|M|N|Q|R|S|Z)([\\dn]) ', '<><>^<> ', { cap(1), cap(1), cap(2) }, math),
|
snip('(K|M|N|Q|R|S|Z)([\\dn]) ', '<><>^<> ', { cap(1), cap(1), cap(2) }, math),
|
||||||
|
|
||||||
snip('dx', 'dif / (dif <>) ', { i(1, 'x') }, math, 900),
|
snip('dx', 'dif / (dif <>) ', { i(1, 'x') }, math, 900),
|
||||||
@@ -90,5 +94,12 @@ return {
|
|||||||
snip('lm', 'lim ', {}, math),
|
snip('lm', 'lim ', {}, math),
|
||||||
snip('lim', 'lim_(<> ->> <>) ', { i(1, 'n'), i(2, 'oo') }, math),
|
snip('lim', 'lim_(<> ->> <>) ', { i(1, 'n'), i(2, 'oo') }, math),
|
||||||
snip('lim (sup|inf)', 'lim<> ', { cap(1) }, math),
|
snip('lim (sup|inf)', 'lim<> ', { cap(1) }, math),
|
||||||
snip('lim(_\\(\\s?\\w+\\s?->\\s?\\w+\\s?\\)) (sup|inf)', 'lim<><> ', { cap(2), cap(1) }, math, 1000, true, 25),
|
snip(
|
||||||
|
'lim(_\\(\\s?\\w+\\s?->\\s?\\w+\\s?\\)) (sup|inf)',
|
||||||
|
'lim<><> ',
|
||||||
|
{ cap(2), cap(1) },
|
||||||
|
math,
|
||||||
|
1000,
|
||||||
|
{ maxTrigLength = 25 }
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ local lmat = function(_, sp)
|
|||||||
ins_indx = ins_indx + 1
|
ins_indx = ins_indx + 1
|
||||||
for k = 2, cols do
|
for k = 2, cols do
|
||||||
table.insert(nodes, t(', '))
|
table.insert(nodes, t(', '))
|
||||||
if k == cols then table.insert(nodes, t('dots, ')) end
|
if k == cols then table.insert(nodes, t('dots.c, ')) end
|
||||||
if j == k then
|
if j == k then
|
||||||
table.insert(nodes, r(ins_indx, tostring(j) .. 'x' .. tostring(k), i(1, '1')))
|
table.insert(nodes, r(ins_indx, tostring(j) .. 'x' .. tostring(k), i(1, '1')))
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ local operations = { -- first boolean: existing brackets should be kept; second
|
|||||||
{ 'sQ', '[', ']', false, false }, -- replace with square brackets
|
{ 'sQ', '[', ']', false, false }, -- replace with square brackets
|
||||||
{ 'BB', '', '', false, false }, -- remove brackets
|
{ 'BB', '', '', false, false }, -- remove brackets
|
||||||
{ 'ss', '"', '"', false, false },
|
{ 'ss', '"', '"', false, false },
|
||||||
|
{ 'agl', 'lr(angle.l ', ' angle.r)', false, false },
|
||||||
{ 'abs', 'abs', '', true, true },
|
{ 'abs', 'abs', '', true, true },
|
||||||
{ 'ul', 'underline', '', true, true },
|
{ 'ul', 'underline', '', true, true },
|
||||||
{ 'ol', 'overline', '', true, true },
|
{ 'ol', 'overline', '', true, true },
|
||||||
@@ -42,9 +43,9 @@ local ts_wrap_query = ts.query.parse('typst', '[(call) (ident) (letter) (number)
|
|||||||
local ts_wrapnobrackets_query = ts.query.parse('typst', '(group) @wrapnobrackets')
|
local ts_wrapnobrackets_query = ts.query.parse('typst', '(group) @wrapnobrackets')
|
||||||
|
|
||||||
local process_ts_query = function(bufnr, cursor, query, root, insert1, insert2, cut_offset)
|
local process_ts_query = function(bufnr, cursor, query, root, insert1, insert2, cut_offset)
|
||||||
for _, match, _ in query:iter_matches(root, bufnr, cursor[1], cursor[1] + 1) do
|
for _, match in ipairs(utils.treesitter_iter_matches(root, query, bufnr, cursor[1], cursor[1] + 1)) do
|
||||||
if match then
|
for _, nodes in pairs(match) do
|
||||||
local start_row, start_col, end_row, end_col = utils.treesitter_match_start_end(match)
|
local start_row, start_col, end_row, end_col = utils.treesitter_match_start_end(nodes)
|
||||||
if end_row == cursor[1] and end_col == cursor[2] then
|
if end_row == cursor[1] and end_col == cursor[2] then
|
||||||
vim.schedule(function() -- to not interfere with luasnip
|
vim.schedule(function() -- to not interfere with luasnip
|
||||||
local cursor_offset = 0
|
local cursor_offset = 0
|
||||||
@@ -81,7 +82,10 @@ local smart_wrap = function(args, parent, old_state, expand)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _, val in pairs(operations) do
|
for _, val in pairs(operations) do
|
||||||
table.insert(snippets, snip(val[1], '<>', { d(1, smart_wrap, {}, { user_args = { val } }) }, math, 1500, false))
|
table.insert(
|
||||||
|
snippets,
|
||||||
|
snip(val[1], '<>', { d(1, smart_wrap, {}, { user_args = { val } }) }, math, 1500, { wordTrig = false })
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -71,6 +71,21 @@ end
|
|||||||
|
|
||||||
function M.get_treesitter_root(bufnr) return ts.get_parser(bufnr):parse()[1]:root() end
|
function M.get_treesitter_root(bufnr) return ts.get_parser(bufnr):parse()[1]:root() end
|
||||||
|
|
||||||
|
function M.treesitter_iter_matches(root, query, bufnr, start, stop)
|
||||||
|
local result = {}
|
||||||
|
local idx = 1
|
||||||
|
for _, matches, _ in query:iter_matches(root, bufnr, start, stop) do
|
||||||
|
if #matches then
|
||||||
|
if type(matches[1]) == 'userdata' then -- nvim version < 0.11
|
||||||
|
matches = { matches }
|
||||||
|
end
|
||||||
|
result[idx] = matches
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
function M.treesitter_match_start_end(match)
|
function M.treesitter_match_start_end(match)
|
||||||
local start_row, start_col, _, _ = match[1]:range()
|
local start_row, start_col, _, _ = match[1]:range()
|
||||||
local _, _, end_row, end_col = match[#match]:range()
|
local _, _, end_row, end_col = match[#match]:range()
|
||||||
@@ -80,9 +95,10 @@ end
|
|||||||
function M.cursor_within_treesitter_query(query, match_tolerance, cursor)
|
function M.cursor_within_treesitter_query(query, match_tolerance, cursor)
|
||||||
cursor = cursor or M.get_cursor_pos()
|
cursor = cursor or M.get_cursor_pos()
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
for _, match, _ in query:iter_matches(M.get_treesitter_root(bufnr), bufnr, cursor[1], cursor[1] + 1) do
|
local root = M.get_treesitter_root(bufnr)
|
||||||
if match then
|
for _, match in ipairs(M.treesitter_iter_matches(root, query, bufnr, cursor[1], cursor[1] + 1)) do
|
||||||
local start_row, start_col, end_row, end_col = M.treesitter_match_start_end(match)
|
for _, nodes in pairs(match) do
|
||||||
|
local start_row, start_col, end_row, end_col = M.treesitter_match_start_end(nodes)
|
||||||
local matched = M.cursor_within_coords(cursor, start_row, end_row, start_col, end_col, match_tolerance)
|
local matched = M.cursor_within_coords(cursor, start_row, end_row, start_col, end_col, match_tolerance)
|
||||||
if matched then return true end
|
if matched then return true end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "pdm.backend"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "typstar"
|
name = "typstar"
|
||||||
version = "1.3.1"
|
version = "1.3.2"
|
||||||
description = "Neovim plugin for efficient note taking in Typst"
|
description = "Neovim plugin for efficient note taking in Typst"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "arne314" }
|
{ name = "arne314" }
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import html
|
||||||
|
|
||||||
import tree_sitter
|
import tree_sitter
|
||||||
|
|
||||||
from .file_handler import FileHandler
|
from .file_handler import FileHandler
|
||||||
@@ -48,7 +50,9 @@ class Flashcard:
|
|||||||
return f"#flashcard({self.note_id})[{self.front if front else ''}][{self.back if not front else ''}]"
|
return f"#flashcard({self.note_id})[{self.front if front else ''}][{self.back if not front else ''}]"
|
||||||
|
|
||||||
def as_html(self, front: bool) -> str:
|
def as_html(self, front: bool) -> str:
|
||||||
prefix = f"<p hidden>{self.front}: {self.back}{' ' * 10}</p>" # indexable via anki search
|
safe_front = html.escape(self.front)
|
||||||
|
safe_back = html.escape(self.back)
|
||||||
|
prefix = f"<p hidden>{safe_front}: {safe_back}{' ' * 10}</p>" # indexable via anki search
|
||||||
image = f'<img src="{self.svg_filename(front)}" />'
|
image = f'<img src="{self.svg_filename(front)}" />'
|
||||||
return prefix + image
|
return prefix + image
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user