LuaSnip
LuaSnip copied to clipboard
[ Help ] Trying to make custom condition function in markdown replicating VimTex plugin
Hi, I'm trying to use my snippets which I used in my LaTeX workflow but now in markdown. Thing is I had many ones using functions like in_mathzone provided by the VimTex plugin. I'm trying to replicate that for markdown but I admit my lua skills are not good enough...
My setup is the following, first I create a ~/.config/lvim/lua/user/my-things/luasnips/locals.lua
---@diagnostic disable: undefined-global
-- functions used in .tex files with vimtex plugin
local in_mathzone = function()
return vim.fn["vimtex#syntax#in_mathzone"]() == 1
end
local in_comment = function()
return vim.fn["vimtex#syntax#in_comment"]() == 1
end
local in_text = function()
return not in_mathzone() and not in_comment()
end
local in_align = function()
return vim.fn["vimtex#env#is_inside"]("align")[1] ~= 0
end
local in_enumerate = function()
return vim.fn["vimtex#env#is_inside"]("enumerate")[1] ~= 0
end
local in_itemize = function()
return vim.fn["vimtex#env#is_inside"]("itemize")[1] ~= 0
end
local begins_line = function()
local cur_line = vim.api.nvim_get_current_line()
-- Checks if the current line consists of whitespace and then the snippet
-- TODO: Fix limitation that the snippet cannot contain whitespace itself
return #cur_line == #string.match(cur_line, "%s*[^%s]+")
end
local get_env = function(name)
return {
t({ "\\begin{" .. name .. "}", "\t" }),
i(0),
t({ "", "\\end{" .. name .. "}" }),
}
end
-- functions used in markdown files without vimtex plugin
local function vimtex_syntax_stack(line, col)
line = line or vim.fn.line('.')
col = col or vim.fn.col('.')
if vim.fn.mode() == 'i' then
col = tonumber(col) - 1
else
col = tonumber(col)
end
line = tonumber(line) or 1
col = tonumber(col) or 0
line = math.max(line, 1)
col = math.max(col, 0)
local stack = vim.fn.synstack(line, col)
return vim.fn.map(stack, function(val) return vim.fn.synIDattr(val, "name") end)
end
local function vimtex_syntax_in(name, ...)
local stack = vimtex_syntax_stack(...)
return vim.fn.match(stack[1], '^' .. name) >= 0
end
local function vimtex_syntax_in_comment(...)
return vimtex_syntax_in('texComment', ...)
end
local function vimtex_syntax_in_mathzone(...)
local groups = vim.fn.reverse(vimtex_syntax_stack(...))
local group = vim.fn.matchstr(groups, '\\v^tex\\%(Math%(Zone\\|Text\\|Tag\\)\\|RefArg\\)')
return vim.fn.match(group, '^texMathZone') ~= -1
end
-- all returns in one place
return {
s = require("luasnip.nodes.snippet").S,
sn = require("luasnip.nodes.snippet").SN,
isn = require("luasnip.nodes.snippet").ISN,
t = require("luasnip.nodes.textNode").T,
i = require("luasnip.nodes.insertNode").I,
f = require("luasnip.nodes.functionNode").F,
c = require("luasnip.nodes.choiceNode").C,
d = require("luasnip.nodes.dynamicNode").D,
r = require("luasnip.nodes.restoreNode").R,
events = require("luasnip.util.events"),
ai = require("luasnip.nodes.absolute_indexer"),
extras = require("luasnip.extras"),
l = require("luasnip.extras").lambda,
rep = require("luasnip.extras").rep,
p = require("luasnip.extras").partial,
m = require("luasnip.extras").match,
n = require("luasnip.extras").nonempty,
dl = require("luasnip.extras").dynamic_lambda,
fmt = require("luasnip.extras.fmt").fmt,
fmta = require("luasnip.extras.fmt").fmta,
conds = require("luasnip.extras.expand_conditions"),
postfix = require("luasnip.extras.postfix").postfix,
types = require("luasnip.util.types"),
parse = require("luasnip.util.parser").parse_snippet,
-- my locals from the part using vimtex functions
in_mathzone = in_mathzone,
in_comment = in_comment,
in_text = in_text,
in_align = in_align,
in_enumerate = in_enumerate,
in_itemize = in_itemize,
begins_line = begins_line,
get_env = get_env,
-- my locals from the part using vimtex functions
vimtex_syntax_stack = vimtex_syntax_stack,
vimtex_syntax_in = vimtex_syntax_in,
vimtex_syntax_in_comment = vimtex_syntax_in_comment,
vimtex_syntax_in_mathzone = vimtex_syntax_in_mathzone,
}
Then I import this file in my ~/.config/lvim/config.lua as such
reload("user.luasnips") -- luasnippets related configs
Then I create my snippets in ~/.config/lvim/luasnippets/markdown/test.lua using the functions I made
---@diagnostic disable: undefined-global
return {
-- LaTeX: Inline math mode
s({ trig = "mm", snippetType = "autosnippet" },
{
t("$ "),
i(1),
t(" $ "),
}),
-- LaTeX: Display math mode
s({ trig = ";dm", snippetType = "autosnippet" }, {
t({ "$$", "\t" }),
i(1),
t({ "", "$$" }),
}),
-- test in mathzone but markdown
s({ trig = "rangle", snippetType = "autosnippet" }, { t(" \\rangle ") }, { condition = vimtex_syntax_in_mathzone }),
}
but the rangle snippet is triggered ignoring the condition.
Now, is it because the condition function is badly implemented? Or am I importing the functions wrongly? Is it possible to just use VimTex plugin in markdown files to "load" all the functions and use the same conditions in markdown files?
Edit: If I do
local vimtex_syntax_in_mathzone = require("user.my-things.luasnips.locals").vimtex_syntax_in_mathzone
in my test.lua file it now typing rangle in a markdown file gives me the following error, it's getting loaded now but the function in locals.lua seems to be wrong
Error executing lua callback: ...e/jx/.config/lvim/lua/user/my-things/luasnips/locals.lua:52: attempt to perform arithmetic on a nil value
stack traceback:
...e/jx/.config/lvim/lua/user/my-things/luasnips/locals.lua:52: in function 'vimtex_syntax_stack'
...e/jx/.config/lvim/lua/user/my-things/luasnips/locals.lua:80: in function 'condition'
...site/pack/lazy/opt/LuaSnip/lua/luasnip/nodes/snippet.lua:546: in function 'matches'
...y/opt/LuaSnip/lua/luasnip/session/snippet_collection.lua:174: in function 'match_snippet'
...lunarvim/site/pack/lazy/opt/LuaSnip/lua/luasnip/init.lua:325: in function 'expand_auto'
...narvim/site/pack/lazy/opt/LuaSnip/lua/luasnip/config.lua:264: in function <...narvim/site/pack/lazy/opt/LuaSnip/lua/luasnip/config.lua:262>
Aw man, I don't think I can help much here :/ A few troubleshooting ideas:
- put the function-definition into the snippet-file to rule out something going wrong with importing
- call the vimtex-function manually when inside a markdown-file to make sure it's returning the results you expect.
The snippets look correct at least :D
@JxJxxJxJ did you got it to work? i'm also looking for reusing my math latex snippets on markdown :face_exhaling: