mirror of
https://github.com/Ascyii/typstar.git
synced 2026-01-01 05:24:24 -05:00
Merge pull request #1 from arne314/dev
Big performance improvements and snippets for common indices
This commit is contained in:
@@ -1,16 +1,30 @@
|
||||
local M = {}
|
||||
local cfg = require('typstar.config').config.snippets
|
||||
local utils = require('typstar.utils')
|
||||
local luasnip = require('luasnip')
|
||||
local fmta = require('luasnip.extras.fmt').fmta
|
||||
local lsengines = require('luasnip.nodes.util.trig_engines')
|
||||
local ts = vim.treesitter
|
||||
|
||||
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
|
||||
local last_keystroke_time = nil
|
||||
vim.api.nvim_create_autocmd('TextChangedI', {
|
||||
callback = function()
|
||||
last_keystroke_time = vim.loop.now()
|
||||
end,
|
||||
})
|
||||
local lexical_result_cache = {}
|
||||
local ts_markup_query = ts.query.parse('typst', '(text) @markup')
|
||||
local ts_math_query = ts.query.parse('typst', '(math) @math')
|
||||
local ts_string_query = ts.query.parse('typst', '(string) @string')
|
||||
|
||||
M.in_math = function()
|
||||
local cursor = utils.get_cursor_pos()
|
||||
return utils.cursor_within_treesitter_query(ts_math_query, 0, cursor)
|
||||
and not utils.cursor_within_treesitter_query(ts_string_query, 0, cursor)
|
||||
end
|
||||
M.in_markup = function() return utils.cursor_within_treesitter_query(ts_markup_query, 2) 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
|
||||
M.snippets_toggle = true
|
||||
|
||||
function M.cap(i)
|
||||
@@ -32,25 +46,46 @@ 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' },
|
||||
{
|
||||
trig = trigger,
|
||||
trigEngine = M.engine,
|
||||
trigEngineOpts = { condition = condition },
|
||||
priority = priority,
|
||||
snippetType = 'autosnippet'
|
||||
},
|
||||
fmta(expand, { unpack(insert) }),
|
||||
{
|
||||
condition = function()
|
||||
if not M.snippets_toggle then
|
||||
return false
|
||||
end
|
||||
return condition()
|
||||
end
|
||||
condition = function() return M.snippets_toggle end
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
function M.start_snip(trigger, expand, insert, condition, priority)
|
||||
return M.snip('^%s*' .. trigger, expand, insert, condition, priority)
|
||||
return M.snip('^\\s*' .. trigger, expand, insert, condition, priority)
|
||||
end
|
||||
|
||||
function M.engine(trigger, opts)
|
||||
local base_engine = lsengines.ecma(trigger, opts)
|
||||
local condition = function()
|
||||
local cached = lexical_result_cache[opts.condition]
|
||||
if cached ~= nil and cached[1] == last_keystroke_time then
|
||||
return cached[2]
|
||||
end
|
||||
local result = opts.condition()
|
||||
lexical_result_cache[opts.condition] = { last_keystroke_time, result }
|
||||
return result
|
||||
end
|
||||
return function(line, trig)
|
||||
if not M.snippets_toggle or not condition() then
|
||||
return nil
|
||||
end
|
||||
return base_engine(line, trig)
|
||||
end
|
||||
end
|
||||
|
||||
function M.toggle_autosnippets()
|
||||
M.snippets_toggle = not M.snippets_toggle
|
||||
print(string.format('%sabled typstar autosnippets', M.snippets_toggle and 'En' or 'Dis'))
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
local helper = require('typstar.autosnippets')
|
||||
local snip = helper.snip
|
||||
local cap = helper.cap
|
||||
local math = helper.in_math
|
||||
local markup = helper.in_markup
|
||||
|
||||
local letters = {
|
||||
local letter_snippets = {}
|
||||
local greek_letters = {
|
||||
{ 'a', 'alpha' }, { 'A', 'Alpha' },
|
||||
{ 'b', 'beta' }, { 'B', 'Beta' },
|
||||
{ 'c', 'chi' }, { 'C', 'Chi' },
|
||||
@@ -24,13 +28,32 @@ local letters = {
|
||||
{ 'x', 'xi' }, { 'X', 'xi' },
|
||||
{ 'z', 'zeta' }, { 'Z', 'Zeta' },
|
||||
}
|
||||
local latin_letters = { 'f', 'u', 'v', 'w', 'y' } -- remaining ones are added dynamically
|
||||
local common_indices = { '\\d+', 'i', 'j', 'k', 'n' }
|
||||
|
||||
local letter_snippets = {}
|
||||
for _, letter in ipairs({ unpack(latin_letters) }) do
|
||||
table.insert(latin_letters, letter:upper())
|
||||
end
|
||||
|
||||
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))
|
||||
local generate_index_snippets = function(letter)
|
||||
for _, index in pairs(common_indices) do
|
||||
table.insert(letter_snippets,
|
||||
snip(letter .. '(' .. index .. ') ', letter .. '_(<>) ', { cap(1) }, math, 200))
|
||||
table.insert(letter_snippets,
|
||||
snip('\\$' .. letter .. '\\$(' .. index .. ') ', '$' .. letter .. '_(<>)$ ', { cap(1) }, markup, 200))
|
||||
end
|
||||
end
|
||||
|
||||
for _, val in pairs(greek_letters) do
|
||||
table.insert(letter_snippets, snip(';' .. val[1], val[2], {}, math))
|
||||
table.insert(letter_snippets, snip(';' .. val[1], '$' .. val[2] .. '$ ', {}, markup))
|
||||
generate_index_snippets(val[2])
|
||||
table.insert(latin_letters, val[1])
|
||||
end
|
||||
|
||||
for _, letter in pairs(latin_letters) do
|
||||
generate_index_snippets(letter)
|
||||
table.insert(letter_snippets, snip(':' .. letter, '$' .. letter .. '$ ', {}, markup))
|
||||
end
|
||||
|
||||
return {
|
||||
|
||||
@@ -62,6 +62,8 @@ return {
|
||||
snip('iso', 'tilde.equiv ', {}, math),
|
||||
snip('rrn', 'RR^n ', {}, math),
|
||||
snip('cc', 'cases(\n\t<>\n)\\', { i(1, '1') }, math),
|
||||
snip('pi', 'pi ', {}, math),
|
||||
snip('in', 'in ', {}, math),
|
||||
snip('(.*)iv', '<>^(-1)', { cap(1) }, math),
|
||||
snip('(.*)sr', '<>^(2)', { cap(1) }, math),
|
||||
snip('(.*)rd', '<>^(<>)', { cap(1), i(1, 'n') }, math),
|
||||
@@ -74,8 +76,6 @@ return {
|
||||
|
||||
snip('lm', 'lim <>', { i(1, 'a_n') }, math),
|
||||
snip('lim', 'lim_(<> ->> <>) <>', { i(1, 'n'), i(2, 'oo'), i(3, 'a_n') }, math),
|
||||
snip('lim sup', 'limsup <>', { i(1, 'a_n') }, math),
|
||||
snip('lim(_.*%-.*) sup', 'limsup<> <>', { cap(1), i(1, 'a_n') }, math),
|
||||
snip('lim inf', 'liminf <>', { i(1, 'a_n') }, math),
|
||||
snip('lim(_.*%-.*) inf', 'liminf<> <>', { cap(1), i(1, 'a_n') }, math),
|
||||
snip('lim (sup|inf)', 'lim<> <>', { cap(1), i(1, 'a_n') }, math),
|
||||
snip('lim(_.*-.*) (sup|inf)', 'lim<><> <>', { cap(2), cap(1), i(1, 'a_n') }, math),
|
||||
}
|
||||
|
||||
@@ -78,6 +78,6 @@ local lmat = function(_, sp)
|
||||
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),
|
||||
snip('(\\d)(\\d)ma', 'mat(\n\t<>\n)', { d(1, mat) }, math),
|
||||
snip('(\\d)(\\d)lma', 'mat(\n\t<>\n)', { d(1, lmat) }, math),
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ local operations = { -- boolean denotes whether an additional layer of () bracke
|
||||
{ 'vi', '1/(', ')', true },
|
||||
{ 'bb', '(', ')', false },
|
||||
{ 'sq', '[', ']', true },
|
||||
{ 'abs', '|', '|', false },
|
||||
{ 'abs', 'abs(', ')', false },
|
||||
{ 'ul', 'underline(', ')', false },
|
||||
{ 'ol', 'overline(', ')', false },
|
||||
{ 'ub', 'underbrace(', ')', false },
|
||||
@@ -61,12 +61,12 @@ end
|
||||
|
||||
for _, val in pairs(operations) do
|
||||
table.insert(snippets, snip(val[1], val[2] .. '<>' .. val[3], { d(1, get_visual) }, math))
|
||||
table.insert(snippets, snip('[%s$]' .. val[1], val[2] .. '<>' .. val[3], { i(1, '1') }, math))
|
||||
table.insert(snippets, snip('[\\s$]' .. val[1], val[2] .. '<>' .. val[3], { i(1, '1') }, math))
|
||||
table.insert(snippets,
|
||||
snip('([%w]+)'
|
||||
snip('([\\w]+)'
|
||||
.. val[1], val[2] .. '<>' .. val[3], { cap(1) }, math, 900))
|
||||
table.insert(snippets,
|
||||
snip('(.*[%)|%]|%}])' .. val[1], '<>', { f(wrap_brackets, {}, { user_args = { val } }), nil }, math, 1100))
|
||||
snip('(.*[\\)|\\]|\\}])' .. val[1], '<>', { f(wrap_brackets, {}, { user_args = { val } }), nil }, math, 1100))
|
||||
end
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
local M = {}
|
||||
local ts = vim.treesitter
|
||||
|
||||
function M.get_cursor_pos()
|
||||
local cursor_row, cursor_col = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
cursor_row = cursor_row - 1
|
||||
return { cursor_row, cursor_col }
|
||||
end
|
||||
|
||||
function M.insert_snippet(snip)
|
||||
local line_num = vim.fn.getcurpos()[2]
|
||||
local line_num = M.get_cursor_pos()[1] + 1
|
||||
local lines = {}
|
||||
for line in snip:gmatch '[^\r\n]+' do
|
||||
table.insert(lines, line)
|
||||
@@ -13,4 +20,34 @@ function M.run_shell_command(cmd)
|
||||
vim.fn.jobstart(cmd)
|
||||
end
|
||||
|
||||
function M.cursor_within_treesitter_query(query, match_tolerance, cursor)
|
||||
cursor = cursor or M.get_cursor_pos()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local root = ts.get_parser(bufnr):parse()[1]:root()
|
||||
for _, match, _ in query:iter_matches(root, bufnr, cursor[1], cursor[1] + 1) do
|
||||
if match then
|
||||
local start_row, start_col, _, _ = match[1]:range()
|
||||
local _, _, end_row, end_col = match[#match]:range()
|
||||
local matched = M.cursor_within_coords(cursor, start_row, end_row, start_col, end_col,
|
||||
match_tolerance)
|
||||
if matched then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function M.cursor_within_coords(cursor, start_row, end_row, start_col, end_col, match_tolerance)
|
||||
if start_row <= cursor[1] and end_row >= cursor[1] then
|
||||
if start_row == cursor[1] and start_col - match_tolerance >= cursor[2] then
|
||||
return false
|
||||
elseif end_row == cursor[1] and end_col + match_tolerance <= cursor[2] then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Reference in New Issue
Block a user