mirror of
https://github.com/Ascyii/typstar.git
synced 2025-12-31 21:14:25 -05:00
@@ -10,6 +10,8 @@ Neovim plugin for efficient note taking in Typst
|
||||
|
||||
### Snippets
|
||||
Use `:TypstarToggleSnippets` to toggle all snippets at any time.
|
||||
To efficiently navigate insert nodes and avoid overlapping ones,
|
||||
use `:TypstarSmartJump` and `:TypstarSmartJumpBack`.
|
||||
Available snippets can mostly be intuitively derived from [here](././lua/typstar/snippets), they include:
|
||||
|
||||
Markup snippets:
|
||||
@@ -86,7 +88,8 @@ require('typstar').setup({ -- depending on your neovim plugin system
|
||||
1. Install [LuaSnip](https://github.com/L3MON4D3/LuaSnip/), set `enable_autosnippets = true` and set a visual mode selection key (e.g. `store_selection_keys = '<Tab>'`) in the configuration
|
||||
2. Install [jsregexp](https://github.com/kmarius/jsregexp) as described [here](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#transformations) (You will see a warning on startup if jsregexp isn't installed properly)
|
||||
3. Install [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) and run `:TSInstall typst`
|
||||
4. Optional: Setup [ctheorems](https://typst.app/universe/package/ctheorems/) with names like [here](./lua/typstar/snippets/markup.lua)
|
||||
4. Make sure you haven't remapped `<C-g>`. Otherwise set `add_undo_breakpoints = false` in the [config](#configuration)
|
||||
5. Optional: Setup [ctheorems](https://typst.app/universe/package/ctheorems/) with names like [here](./lua/typstar/snippets/markup.lua)
|
||||
|
||||
### Excalidraw
|
||||
1. Install [Obsidian](https://obsidian.md/) and create a vault in your typst note taking directory
|
||||
@@ -136,6 +139,10 @@ The [config](#configuration) allows you to
|
||||
- disable all snippets via `snippets.enable = false`
|
||||
- only include specific modules from the snippets folder via e.g. `snippets.modules = { 'letters' }`
|
||||
- exclude specific triggers via e.g. `snippets.exclude = { 'dx', 'ddx' }`
|
||||
- disable different behaviors of snippets from the `visual` module
|
||||
- visual selection via e.g. `snippets.visual_disable = { 'br' }`
|
||||
- normal snippets (`abs` → `abs(1+1)`) via e.g. `snippets.visual_disable_normal = { 'abs' }`
|
||||
- postfix snippets (`xabs` → `abs(x)`) via e.g. `snippets.visual_disable_postfix = { 'abs' }`
|
||||
|
||||
For further customization you can make use of the provided wrappers from within your [LuaSnip](https://github.com/L3MON4D3/LuaSnip/) config.
|
||||
Let's say you prefer the short `=>` arrow over the long `==>` one and would like to change the `ip` trigger to `imp`.
|
||||
|
||||
@@ -52,11 +52,12 @@
|
||||
store_selection_keys = "<Tab>",
|
||||
})
|
||||
|
||||
require('typstar').setup()
|
||||
local typstar = require('typstar')
|
||||
typstar.setup({})
|
||||
|
||||
vim.keymap.set({'n', 'i'}, '<M-t>', '<Cmd>TypstarToggleSnippets<CR>', { silent = true, noremap = true })
|
||||
vim.keymap.set({'n', 'i'}, '<M-j>', function() ls.jump( 1) end, { silent = true, noremap = true })
|
||||
vim.keymap.set({'n', 'i'}, '<M-k>', function() ls.jump(-1) end, { silent = true, noremap = true })
|
||||
vim.keymap.set({'n', 'i'}, '<M-j>', '<Cmd>TypstarSmartJump<CR>', { silent = true, noremap = true })
|
||||
vim.keymap.set({'n', 'i'}, '<M-k>', '<Cmd>TypstarSmartJumpBack<CR>', { silent = true, noremap = true })
|
||||
EOF
|
||||
'';
|
||||
plugins = [
|
||||
|
||||
@@ -27,6 +27,9 @@ local default_config = {
|
||||
'visual',
|
||||
},
|
||||
exclude = {}, -- list of triggers to exclude
|
||||
visual_disable = {}, -- visual.lua: list of triggers to exclude from visual selection mode
|
||||
visual_disable_normal = {}, -- visual.lua: list of triggers to exclude from normal snippet mode
|
||||
visual_disable_postfix = {}, -- visual.lua: list of triggers to exclude from postfix snippet mode
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ vim.api.nvim_create_autocmd('TextChangedI', {
|
||||
|
||||
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)
|
||||
return utils.cursor_within_treesitter_query(ts_math_query, 0, 0, cursor)
|
||||
and not utils.cursor_within_treesitter_query(ts_string_query, 0, 0, cursor)
|
||||
end
|
||||
M.in_markup = function() return utils.cursor_within_treesitter_query(ts_markup_query, 2) end
|
||||
M.in_markup = function() return utils.cursor_within_treesitter_query(ts_markup_query, 1, 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.snippets_toggle = true
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local M = {}
|
||||
|
||||
local config = require('typstar.config')
|
||||
local luasnip = nil
|
||||
|
||||
M.setup = function(args)
|
||||
config.merge_config(args)
|
||||
@@ -9,6 +10,8 @@ M.setup = function(args)
|
||||
local anki = require('typstar.anki')
|
||||
|
||||
vim.api.nvim_create_user_command('TypstarToggleSnippets', autosnippets.toggle_autosnippets, {})
|
||||
vim.api.nvim_create_user_command('TypstarSmartJump', function() M.smart_jump(1) end, {})
|
||||
vim.api.nvim_create_user_command('TypstarSmartJumpBack', function() M.smart_jump(-1) end, {})
|
||||
|
||||
vim.api.nvim_create_user_command('TypstarInsertExcalidraw', excalidraw.insert_drawing, {})
|
||||
vim.api.nvim_create_user_command('TypstarOpenExcalidraw', excalidraw.open_drawing, {})
|
||||
@@ -19,8 +22,23 @@ M.setup = function(args)
|
||||
vim.api.nvim_create_user_command('TypstarAnkiForceReimport', anki.scan_force_reimport, {})
|
||||
vim.api.nvim_create_user_command('TypstarAnkiForceCurrent', anki.scan_force_current, {})
|
||||
vim.api.nvim_create_user_command('TypstarAnkiForceCurrentReimport', anki.scan_force_current_reimport, {})
|
||||
|
||||
autosnippets.setup()
|
||||
end
|
||||
|
||||
-- source: https://github.com/lentilus/fastex.nvim
|
||||
M.smart_jump = function(length, x, y, tries)
|
||||
if luasnip == nil then luasnip = require('luasnip') end
|
||||
local x2, y2 = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
local tries = tries or 0
|
||||
|
||||
if tries > 10 then return end
|
||||
if x == nil or y == nil then
|
||||
x, y = x2, y2
|
||||
end
|
||||
if x == x2 and y == y2 then
|
||||
luasnip.jump(length)
|
||||
vim.schedule(function() M.smart_jump(length, x, y, tries + 1) end)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -41,7 +41,7 @@ local greek_keys = {}
|
||||
local greek_letters_set = {}
|
||||
local common_indices = { '\\d+', '[i-n]' }
|
||||
-- buitins and caligraphic letters from github.com/lentilus/readable-typst
|
||||
local index_conflicts = { 'Im', 'in', 'ln', 'pi', 'xi', 'Ii', 'Jj', 'Kk', 'Ll', 'Mm', 'Nn' }
|
||||
local index_conflicts = { 'Im', 'in', 'ln', 'Pi', 'pi', 'Xi', 'xi', 'Ii', 'Jj', 'Kk', 'Ll', 'Mm', 'Nn' }
|
||||
local index_conflicts_set = {}
|
||||
local punctuation_prepend_space = { ',', ';' }
|
||||
local punctuation_prepend_space_set = {}
|
||||
|
||||
@@ -75,14 +75,14 @@ return {
|
||||
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', 'log', 'loz', 'mod', 'top', 'won', 'xor' },
|
||||
blacklist = { 'bot', 'col', 'com', 'con', 'cos', 'cot', 'dol', 'dot', 'log', 'loz', 'mod', 'roo', 'top', 'won', 'xor' },
|
||||
}),
|
||||
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('ddx', '(dif <>) / (dif <>) ', { i(1, 'f'), i(2, 'x') }, math),
|
||||
snip('DX', 'partial / (partial <>) ', { i(1, 'x') }, math, 900),
|
||||
snip('DDX', '(partial <>) / (partial <>) ', { i(1, 'f'), i(2, 'x') }, math),
|
||||
snip('DX', 'diff / (diff <>) ', { i(1, 'x') }, math, 900),
|
||||
snip('DDX', '(diff <>) / (diff <>) ', { i(1, 'f'), i(2, 'x') }, math),
|
||||
snip('part', 'partial ', {}, math, 1600),
|
||||
snip('it', 'integral ', {}, math, 900),
|
||||
snip('int', 'integral_(<>)^(<>) ', { i(1, 'a'), i(2, 'b') }, math),
|
||||
|
||||
@@ -47,6 +47,8 @@ local lmat = function(_, sp)
|
||||
for k = 1, cols + 1 do
|
||||
if k == cols then
|
||||
table.insert(nodes, t('dots.down, '))
|
||||
elseif k == cols + 1 then
|
||||
table.insert(nodes, t('dots.v'))
|
||||
else
|
||||
table.insert(nodes, t('dots.v, '))
|
||||
end
|
||||
|
||||
@@ -7,10 +7,17 @@ local t = ls.text_node
|
||||
|
||||
local helper = require('typstar.autosnippets')
|
||||
local utils = require('typstar.utils')
|
||||
local cfg = require('typstar.config').config.snippets
|
||||
local math = helper.in_math
|
||||
local snip = helper.snip
|
||||
|
||||
local snippets = {}
|
||||
local visual_disable = {}
|
||||
local visual_disable_normal = {}
|
||||
local visual_disable_postfix = {}
|
||||
utils.generate_bool_set(cfg.visual_disable, visual_disable)
|
||||
utils.generate_bool_set(cfg.visual_disable_normal, visual_disable_normal)
|
||||
utils.generate_bool_set(cfg.visual_disable_postfix, visual_disable_postfix)
|
||||
|
||||
local operations = { -- first boolean: existing brackets should be kept; second boolean: brackets should be added
|
||||
{ 'vi', '1/', '', true, false },
|
||||
@@ -68,17 +75,31 @@ local smart_wrap = function(args, parent, old_state, expand)
|
||||
local cursor = utils.get_cursor_pos()
|
||||
local root = utils.get_treesitter_root(bufnr)
|
||||
|
||||
if process_ts_query(bufnr, cursor, ts_wrapnobrackets_query, root, expand[2], expand[3], expand[4] and 0 or 1) then
|
||||
return s(nil, t())
|
||||
end
|
||||
|
||||
local trigger = expand[1]
|
||||
local expand1 = expand[5] and expand[2] .. '(' or expand[2]
|
||||
local expand2 = expand[5] and expand[3] .. ')' or expand[3]
|
||||
if process_ts_query(bufnr, cursor, ts_wrap_query, root, expand1, expand2) then return s(nil, t()) end
|
||||
if #parent.env.LS_SELECT_RAW > 0 then
|
||||
|
||||
-- visual selection
|
||||
if not visual_disable[trigger] and #parent.env.LS_SELECT_RAW > 0 then
|
||||
return s(nil, t(expand1 .. table.concat(parent.env.LS_SELECT_RAW) .. expand2))
|
||||
end
|
||||
return s(nil, { t(expand1), i(1, '1+1'), t(expand2) })
|
||||
|
||||
-- postfix
|
||||
if not visual_disable_postfix[trigger] then
|
||||
if
|
||||
process_ts_query(bufnr, cursor, ts_wrapnobrackets_query, root, expand[2], expand[3], expand[4] and 0 or 1)
|
||||
or process_ts_query(bufnr, cursor, ts_wrap_query, root, expand1, expand2)
|
||||
then
|
||||
return s(nil, t())
|
||||
end
|
||||
end
|
||||
|
||||
-- normal snippet
|
||||
if not visual_disable_normal[trigger] then
|
||||
return s(nil, { t(expand1), i(1, '1+1'), t(expand2) })
|
||||
else
|
||||
return s(nil, t(trigger))
|
||||
end
|
||||
end
|
||||
|
||||
for _, val in pairs(operations) do
|
||||
|
||||
@@ -92,25 +92,35 @@ function M.treesitter_match_start_end(match)
|
||||
return start_row, start_col, end_row, end_col
|
||||
end
|
||||
|
||||
function M.cursor_within_treesitter_query(query, match_tolerance, cursor)
|
||||
function M.cursor_within_treesitter_query(query, match_tolerance_l, match_tolerance_r, cursor)
|
||||
cursor = cursor or M.get_cursor_pos()
|
||||
match_tolerance_l = match_tolerance_l or 0
|
||||
match_tolerance_r = match_tolerance_r or 0
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local root = M.get_treesitter_root(bufnr)
|
||||
for _, match in ipairs(M.treesitter_iter_matches(root, query, bufnr, cursor[1], cursor[1] + 1)) do
|
||||
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_l,
|
||||
match_tolerance_r
|
||||
)
|
||||
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)
|
||||
function M.cursor_within_coords(cursor, start_row, end_row, start_col, end_col, match_tolerance_l, match_tolerance_r)
|
||||
if start_row <= cursor[1] and end_row >= cursor[1] then
|
||||
if start_row == cursor[1] and start_col - match_tolerance >= cursor[2] then
|
||||
if start_row == cursor[1] and start_col - match_tolerance_l >= cursor[2] then
|
||||
return false
|
||||
elseif end_row == cursor[1] and end_col + match_tolerance <= cursor[2] then
|
||||
elseif end_row == cursor[1] and end_col + match_tolerance_r <= cursor[2] then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "pdm.backend"
|
||||
|
||||
[project]
|
||||
name = "typstar"
|
||||
version = "1.3.3"
|
||||
version = "1.3.4"
|
||||
description = "Neovim plugin for efficient note taking in Typst"
|
||||
authors = [
|
||||
{ name = "arne314" }
|
||||
|
||||
Reference in New Issue
Block a user