[nvim] fix: snippets config
This commit is contained in:
parent
6581d9af42
commit
6fd5067bc4
@ -20,32 +20,32 @@ local f = ls.function_node
|
||||
|
||||
local copy = utils.copy
|
||||
|
||||
ls.snippets = {
|
||||
c = {
|
||||
s("main", {
|
||||
t({ "int main(int argc, char* argv[])" }),
|
||||
t({ "", "{", "\t" }),
|
||||
ls.add_snippets( "c", {
|
||||
s("main", {
|
||||
t({ "int main(int argc, char* argv[])" }),
|
||||
t({ "", "{", "\t" }),
|
||||
i(0),
|
||||
t({ "", "\treturn 0;"}),
|
||||
t({ "", "}"}),
|
||||
}),
|
||||
s("fn", {
|
||||
-- Simple static text.
|
||||
t("//Parameters: "),
|
||||
-- function, first parameter is the function, second the Placeholders
|
||||
-- whose text it gets as input.
|
||||
f(copy, 2),
|
||||
t({ "", "" }),
|
||||
-- Placeholder/Insert.
|
||||
i(1),
|
||||
t("("),
|
||||
-- Placeholder with initial text.
|
||||
i(2, "int foo"),
|
||||
-- Linebreak
|
||||
t({ ")", "{", "\t" }),
|
||||
i(0),
|
||||
t({ "", "\treturn 0;"}),
|
||||
t({ "", "}"}),
|
||||
}),
|
||||
s("fn", {
|
||||
-- Simple static text.
|
||||
t("//Parameters: "),
|
||||
-- function, first parameter is the function, second the Placeholders
|
||||
-- whose text it gets as input.
|
||||
f(copy, 2),
|
||||
t({ "", "" }),
|
||||
-- Placeholder/Insert.
|
||||
i(1),
|
||||
t("("),
|
||||
-- Placeholder with initial text.
|
||||
i(2, "int foo"),
|
||||
-- Linebreak
|
||||
t({ ")", "{", "\t" }),
|
||||
i(0),
|
||||
t({ "", "\treturn 0;"}),
|
||||
t({ "", "}"}),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}),
|
||||
}, {
|
||||
key = "c"
|
||||
})
|
||||
|
@ -44,86 +44,86 @@ local function rec_ls()
|
||||
)
|
||||
end
|
||||
|
||||
ls.snippets = {
|
||||
tex = {
|
||||
-- rec_ls is self-referencing. That makes this snippet 'infinite' eg. have as many
|
||||
-- \item as necessary by utilizing a choiceNode.
|
||||
s("ls", {
|
||||
t({ "\\begin{itemize}", "\t\\item " }),
|
||||
i(1),
|
||||
t({ "" }),
|
||||
d(2, rec_ls, {}),
|
||||
t({ "", "\\end{itemize}", "" }),
|
||||
}),
|
||||
s("lsl", {
|
||||
t({ "\\begin{itemize}[label=" }),
|
||||
i(1),
|
||||
t( { "]", "\t\\item " }),
|
||||
i(2),
|
||||
t({ "" }),
|
||||
d(3, rec_ls, {}),
|
||||
t({ "", "\\end{itemize}", "" }),
|
||||
}),
|
||||
s("frm", {
|
||||
t({ "\\begin{" }),
|
||||
i(1),
|
||||
t({ "}[" }),
|
||||
i(2),
|
||||
t({ "]{" }),
|
||||
f(copy, 1),
|
||||
t({ ":" }),
|
||||
i(3, "foo"),
|
||||
t({ "}", "\t" }),
|
||||
i(0),
|
||||
t({ "", "\\end{" }),
|
||||
f(copy, 1),
|
||||
t({ "}", "" }),
|
||||
}),
|
||||
s("env", {
|
||||
t({ "\\begin{" }),
|
||||
i(1, "foo"),
|
||||
t({ "}", "\t" }),
|
||||
i(2),
|
||||
t({ "", "\\end{" }),
|
||||
f(copy,1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("tikz", {
|
||||
t({ "\\begin{center}" }),
|
||||
t({ "", "\t\\begin{tikzpicture}[main/.style = {draw,circle}]", "\t\t" }),
|
||||
i(1),
|
||||
t({ "", "\t\\end{tikzpicture}", "\\end{center}" }),
|
||||
}),
|
||||
s("ra", { t( "\\rightarrow" )}),
|
||||
s("Ra", { t("\\Rightarrow" )}),
|
||||
s("la", { t("\\leftarrow" )}),
|
||||
s("La", { t("\\Leftarrow" )}),
|
||||
s("lra", { t("\\leftrightarrow" )}),
|
||||
s("Lra", { t("\\Leftrightarrow" )}),
|
||||
s("bb", {
|
||||
t({ "\\textbf{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("tt", {
|
||||
t({ "\\texttt{" }),
|
||||
ls.add_snippets("tex", {
|
||||
-- rec_ls is self-referencing. That makes this snippet 'infinite' eg. have as many
|
||||
-- \item as necessary by utilizing a choiceNode.
|
||||
s("ls", {
|
||||
t({ "\\begin{itemize}", "\t\\item " }),
|
||||
i(1),
|
||||
t({ "" }),
|
||||
d(2, rec_ls, {}),
|
||||
t({ "", "\\end{itemize}", "" }),
|
||||
}),
|
||||
s("lsl", {
|
||||
t({ "\\begin{itemize}[label=" }),
|
||||
i(1),
|
||||
t( { "]", "\t\\item " }),
|
||||
i(2),
|
||||
t({ "" }),
|
||||
d(3, rec_ls, {}),
|
||||
t({ "", "\\end{itemize}", "" }),
|
||||
}),
|
||||
s("frm", {
|
||||
t({ "\\begin{" }),
|
||||
i(1),
|
||||
t({ "}[" }),
|
||||
i(2),
|
||||
t({ "]{" }),
|
||||
f(copy, 1),
|
||||
t({ ":" }),
|
||||
i(3, "foo"),
|
||||
t({ "}", "\t" }),
|
||||
i(0),
|
||||
t({ "", "\\end{" }),
|
||||
f(copy, 1),
|
||||
t({ "}", "" }),
|
||||
}),
|
||||
s("env", {
|
||||
t({ "\\begin{" }),
|
||||
i(1, "foo"),
|
||||
t({ "}", "\t" }),
|
||||
i(2),
|
||||
t({ "", "\\end{" }),
|
||||
f(copy,1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("tikz", {
|
||||
t({ "\\begin{center}" }),
|
||||
t({ "", "\t\\begin{tikzpicture}[main/.style = {draw,circle}]", "\t\t" }),
|
||||
i(1),
|
||||
t({ "", "\t\\end{tikzpicture}", "\\end{center}" }),
|
||||
}),
|
||||
s("ra", { t( "\\rightarrow" )}),
|
||||
s("Ra", { t("\\Rightarrow" )}),
|
||||
s("la", { t("\\leftarrow" )}),
|
||||
s("La", { t("\\Leftarrow" )}),
|
||||
s("lra", { t("\\leftrightarrow" )}),
|
||||
s("Lra", { t("\\Leftrightarrow" )}),
|
||||
s("bb", {
|
||||
t({ "\\textbf{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("ii", {
|
||||
t({ "\\textit{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("uu", {
|
||||
t({ "\\underline{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("fsc", {
|
||||
t({ "\\textsc{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}),
|
||||
s("tt", {
|
||||
t({ "\\texttt{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("ii", {
|
||||
t({ "\\textit{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("uu", {
|
||||
t({ "\\underline{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
s("fsc", {
|
||||
t({ "\\textsc{" }),
|
||||
i(1),
|
||||
t({ "}"}),
|
||||
}),
|
||||
}, {
|
||||
key = "tex"
|
||||
})
|
||||
|
@ -59,270 +59,269 @@ local function date_input(fmt)
|
||||
return sn(nil, i(1, os.date(fmt)))
|
||||
end
|
||||
|
||||
ls.snippets = {
|
||||
-- When trying to expand a snippet, luasnip first searches the tables for
|
||||
-- each filetype specified in 'filetype' followed by 'all'.
|
||||
-- If ie. the filetype is 'lua.c'
|
||||
-- - luasnip.lua
|
||||
-- - luasnip.c
|
||||
-- - luasnip.all
|
||||
-- are searched in that order.
|
||||
all = {
|
||||
-- snippets are added via ls.add_snippets(filetype, snippets[, opts]), where
|
||||
-- opts may specify the `type` of the snippets ("snippets" or "autosnippets",
|
||||
-- for snippets that should expand directly after the trigger is typed).
|
||||
--
|
||||
-- opts can also specify a key. By passing an unique key to each add_snippets, it's possible to reload snippets by
|
||||
-- re-`:luafile`ing the file in which they are defined (eg. this one).
|
||||
ls.add_snippets( "all", {
|
||||
-- trigger is fn.
|
||||
s("fn", {
|
||||
-- Simple static text.
|
||||
t("//Parameters: "),
|
||||
-- function, first parameter is the function, second the Placeholders
|
||||
-- whose text it gets as input.
|
||||
f(copy, 2),
|
||||
t({ "", "function " }),
|
||||
-- Placeholder/Insert.
|
||||
i(1),
|
||||
t("("),
|
||||
-- Placeholder with initial text.
|
||||
i(2, "int foo"),
|
||||
-- Linebreak
|
||||
t({ ") {", "\t" }),
|
||||
-- Last Placeholder, exit Point of the snippet. EVERY 'outer' SNIPPET NEEDS Placeholder 0.
|
||||
i(0),
|
||||
t({ "", "}" }),
|
||||
}),
|
||||
s("class", {
|
||||
-- Choice: Switch between two different Nodes, first parameter is its position, second a list of nodes.
|
||||
c(1, {
|
||||
t("public "),
|
||||
t("private "),
|
||||
}),
|
||||
t("class "),
|
||||
i(2),
|
||||
t(" "),
|
||||
c(3, {
|
||||
t("{"),
|
||||
-- sn: Nested Snippet. Instead of a trigger, it has a position, just like insert-nodes. !!! These don't expect a 0-node!!!!
|
||||
-- Inside Choices, Nodes don't need a position as the choice node is the one being jumped to.
|
||||
sn(nil, {
|
||||
t("extends "),
|
||||
i(1),
|
||||
t(" {"),
|
||||
}),
|
||||
sn(nil, {
|
||||
t("implements "),
|
||||
i(1),
|
||||
t(" {"),
|
||||
}),
|
||||
}),
|
||||
t({ "", "\t" }),
|
||||
i(0),
|
||||
t({ "", "}" }),
|
||||
}),
|
||||
-- Use a dynamic_node to interpolate the output of a
|
||||
-- function (see date_input above) into the initial
|
||||
-- value of an insert_node.
|
||||
s("novel", {
|
||||
t("It was a dark and stormy night on "),
|
||||
d(1, date_input, {}, "%A, %B %d of %Y"),
|
||||
t(" and the clocks were striking thirteen."),
|
||||
}),
|
||||
-- Parsing snippets: First parameter: Snippet-Trigger, Second: Snippet body.
|
||||
-- Placeholders are parsed into choices with 1. the placeholder text(as a snippet) and 2. an empty string.
|
||||
-- This means they are not SELECTed like in other editors/Snippet engines.
|
||||
ls.parser.parse_snippet(
|
||||
"lspsyn",
|
||||
"Wow! This ${1:Stuff} really ${2:works. ${3:Well, a bit.}}"
|
||||
),
|
||||
s("fn", {
|
||||
-- Simple static text.
|
||||
t("//Parameters: "),
|
||||
-- function, first parameter is the function, second the Placeholders
|
||||
-- whose text it gets as input.
|
||||
f(copy, 2),
|
||||
t({ "", "function " }),
|
||||
-- Placeholder/Insert.
|
||||
i(1),
|
||||
t("("),
|
||||
-- Placeholder with initial text.
|
||||
i(2, "int foo"),
|
||||
-- Linebreak
|
||||
t({ ") {", "\t" }),
|
||||
-- Last Placeholder, exit Point of the snippet. EVERY 'outer' SNIPPET NEEDS Placeholder 0.
|
||||
i(0),
|
||||
t({ "", "}" }),
|
||||
}),
|
||||
s("class", {
|
||||
-- Choice: Switch between two different Nodes, first parameter is its position, second a list of nodes.
|
||||
c(1, {
|
||||
t("public "),
|
||||
t("private "),
|
||||
}),
|
||||
t("class "),
|
||||
i(2),
|
||||
t(" "),
|
||||
c(3, {
|
||||
t("{"),
|
||||
-- sn: Nested Snippet. Instead of a trigger, it has a position, just like insert-nodes. !!! These don't expect a 0-node!!!!
|
||||
-- Inside Choices, Nodes don't need a position as the choice node is the one being jumped to.
|
||||
sn(nil, {
|
||||
t("extends "),
|
||||
i(1),
|
||||
t(" {"),
|
||||
}),
|
||||
sn(nil, {
|
||||
t("implements "),
|
||||
i(1),
|
||||
t(" {"),
|
||||
}),
|
||||
}),
|
||||
t({ "", "\t" }),
|
||||
i(0),
|
||||
t({ "", "}" }),
|
||||
}),
|
||||
-- Use a dynamic_node to interpolate the output of a
|
||||
-- function (see date_input above) into the initial
|
||||
-- value of an insert_node.
|
||||
s("novel", {
|
||||
t("It was a dark and stormy night on "),
|
||||
d(1, date_input, {}, "%A, %B %d of %Y"),
|
||||
t(" and the clocks were striking thirteen."),
|
||||
}),
|
||||
-- Parsing snippets: First parameter: Snippet-Trigger, Second: Snippet body.
|
||||
-- Placeholders are parsed into choices with 1. the placeholder text(as a snippet) and 2. an empty string.
|
||||
-- This means they are not SELECTed like in other editors/Snippet engines.
|
||||
ls.parser.parse_snippet(
|
||||
"lspsyn",
|
||||
"Wow! This ${1:Stuff} really ${2:works. ${3:Well, a bit.}}"
|
||||
),
|
||||
|
||||
-- When wordTrig is set to false, snippets may also expand inside other words.
|
||||
ls.parser.parse_snippet(
|
||||
{ trig = "te", wordTrig = false },
|
||||
"${1:cond} ? ${2:true} : ${3:false}"
|
||||
),
|
||||
-- When wordTrig is set to false, snippets may also expand inside other words.
|
||||
ls.parser.parse_snippet(
|
||||
{ trig = "te", wordTrig = false },
|
||||
"${1:cond} ? ${2:true} : ${3:false}"
|
||||
),
|
||||
|
||||
-- When regTrig is set, trig is treated like a pattern, this snippet will expand after any number.
|
||||
ls.parser.parse_snippet({ trig = "%d", regTrig = true }, "A Number!!"),
|
||||
-- Using the condition, it's possible to allow expansion only in specific cases.
|
||||
s("cond", {
|
||||
t("will only expand in c-style comments"),
|
||||
}, {
|
||||
condition = function(line_to_cursor, matched_trigger, captures)
|
||||
-- optional whitespace followed by //
|
||||
return line_to_cursor:match("%s*//")
|
||||
end,
|
||||
}),
|
||||
-- there's some built-in conditions in "luasnip.extras.expand_conditions".
|
||||
s("cond2", {
|
||||
t("will only expand at the beginning of the line"),
|
||||
}, {
|
||||
condition = conds.line_begin,
|
||||
}),
|
||||
-- The last entry of args passed to the user-function is the surrounding snippet.
|
||||
s(
|
||||
{ trig = "a%d", regTrig = true },
|
||||
f(function(_, snip)
|
||||
return "Triggered with " .. snip.trigger .. "."
|
||||
end, {})
|
||||
),
|
||||
-- It's possible to use capture-groups inside regex-triggers.
|
||||
s(
|
||||
{ trig = "b(%d)", regTrig = true },
|
||||
f(function(_, snip)
|
||||
return "Captured Text: " .. snip.captures[1] .. "."
|
||||
end, {})
|
||||
),
|
||||
s({ trig = "c(%d+)", regTrig = true }, {
|
||||
t("will only expand for even numbers"),
|
||||
}, {
|
||||
condition = function(line_to_cursor, matched_trigger, captures)
|
||||
return tonumber(captures[1]) % 2 == 0
|
||||
end,
|
||||
}),
|
||||
-- Use a function to execute any shell command and print its text.
|
||||
s("bash", f(bash, {}, "ls")),
|
||||
-- Short version for applying String transformations using function nodes.
|
||||
s("transform", {
|
||||
i(1, "initial text"),
|
||||
t({ "", "" }),
|
||||
-- lambda nodes accept an l._1,2,3,4,5, which in turn accept any string transformations.
|
||||
-- This list will be applied in order to the first node given in the second argument.
|
||||
l(l._1:match("[^i]*$"):gsub("i", "o"):gsub(" ", "_"):upper(), 1),
|
||||
}),
|
||||
s("transform2", {
|
||||
i(1, "initial text"),
|
||||
t("::"),
|
||||
i(2, "replacement for e"),
|
||||
t({ "", "" }),
|
||||
-- Lambdas can also apply transforms USING the text of other nodes:
|
||||
l(l._1:gsub("e", l._2), { 1, 2 }),
|
||||
}),
|
||||
s({ trig = "trafo(%d+)", regTrig = true }, {
|
||||
-- env-variables and captures can also be used:
|
||||
l(l.CAPTURE1:gsub("1", l.TM_FILENAME), {}),
|
||||
}),
|
||||
-- Set store_selection_keys = "<Tab>" (for example) in your
|
||||
-- luasnip.config.setup() call to access TM_SELECTED_TEXT. In
|
||||
-- this case, select a URL, hit Tab, then expand this snippet.
|
||||
s("link_url", {
|
||||
t('<a href="'),
|
||||
f(function(_, snip)
|
||||
return snip.env.TM_SELECTED_TEXT[1] or {}
|
||||
end, {}),
|
||||
t('">'),
|
||||
i(1),
|
||||
t("</a>"),
|
||||
i(0),
|
||||
}),
|
||||
-- Shorthand for repeating the text in a given node.
|
||||
s("repeat", { i(1, "text"), t({ "", "" }), r(1) }),
|
||||
-- Directly insert the ouput from a function evaluated at runtime.
|
||||
s("part", p(os.date, "%Y")),
|
||||
-- use matchNodes to insert text based on a pattern/function/lambda-evaluation.
|
||||
s("mat", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(1, "%d", "contains a number", "no number :("),
|
||||
}),
|
||||
-- The inserted text defaults to the first capture group/the entire
|
||||
-- match if there are none
|
||||
s("mat2", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(1, "[abc][abc][abc]"),
|
||||
}),
|
||||
-- It is even possible to apply gsubs' or other transformations
|
||||
-- before matching.
|
||||
s("mat3", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(
|
||||
1,
|
||||
l._1:gsub("[123]", ""):match("%d"),
|
||||
"contains a number that isn't 1, 2 or 3!"
|
||||
),
|
||||
}),
|
||||
-- `match` also accepts a function, which in turn accepts a string
|
||||
-- (text in node, \n-concatted) and returns any non-nil value to match.
|
||||
-- If that value is a string, it is used for the default-inserted text.
|
||||
s("mat4", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(1, function(text)
|
||||
return (#text % 2 == 0 and text) or nil
|
||||
end),
|
||||
}),
|
||||
-- The nonempty-node inserts text depending on whether the arg-node is
|
||||
-- empty.
|
||||
s("nempty", {
|
||||
i(1, "sample_text"),
|
||||
n(1, "i(1) is not empty!"),
|
||||
}),
|
||||
-- dynamic lambdas work exactly like regular lambdas, except that they
|
||||
-- don't return a textNode, but a dynamicNode containing one insertNode.
|
||||
-- This makes it easier to dynamically set preset-text for insertNodes.
|
||||
s("dl1", {
|
||||
i(1, "sample_text"),
|
||||
t({ ":", "" }),
|
||||
dl(2, l._1, 1),
|
||||
}),
|
||||
-- Obviously, it's also possible to apply transformations, just like lambdas.
|
||||
s("dl2", {
|
||||
i(1, "sample_text"),
|
||||
i(2, "sample_text_2"),
|
||||
t({ "", "" }),
|
||||
dl(3, l._1:gsub("\n", " linebreak ") .. l._2, { 1, 2 }),
|
||||
}),
|
||||
-- Alternative printf-like notation for defining snippets. It uses format
|
||||
-- string with placeholders similar to the ones used with Python's .format().
|
||||
s(
|
||||
"fmt1",
|
||||
fmt("To {title} {} {}.", {
|
||||
i(2, "Name"),
|
||||
i(3, "Surname"),
|
||||
title = c(1, { t("Mr."), t("Ms.") }),
|
||||
})
|
||||
),
|
||||
-- To escape delimiters use double them, e.g. `{}` -> `{{}}`.
|
||||
-- Multi-line format strings by default have empty first/last line removed.
|
||||
-- Indent common to all lines is also removed. Use the third `opts` argument
|
||||
-- to control this behaviour.
|
||||
s(
|
||||
"fmt2",
|
||||
fmt(
|
||||
[[
|
||||
foo({1}, {3}) {{
|
||||
return {2} * {4}
|
||||
}}
|
||||
]],
|
||||
{
|
||||
i(1, "x"),
|
||||
r(1),
|
||||
i(2, "y"),
|
||||
r(2),
|
||||
}
|
||||
)
|
||||
),
|
||||
-- Empty placeholders are numbered automatically starting from 1 or the last
|
||||
-- value of a numbered placeholder. Named placeholders do not affect numbering.
|
||||
s(
|
||||
"fmt3",
|
||||
fmt("{} {a} {} {1} {}", {
|
||||
t("1"),
|
||||
t("2"),
|
||||
a = t("A"),
|
||||
})
|
||||
),
|
||||
-- The delimiters can be changed from the default `{}` to something else.
|
||||
s(
|
||||
"fmt4",
|
||||
fmt("foo() { return []; }", i(1, "x"), { delimiters = "[]" })
|
||||
),
|
||||
-- `fmta` is a convenient wrapper that uses `<>` instead of `{}`.
|
||||
s("fmt5", fmta("foo() { return <>; }", i(1, "x"))),
|
||||
-- By default all args must be used. Use strict=false to disable the check
|
||||
s(
|
||||
"fmt6",
|
||||
fmt("use {} only", { t("this"), t("not this") }, { strict = false })
|
||||
),
|
||||
},
|
||||
}
|
||||
-- When regTrig is set, trig is treated like a pattern, this snippet will expand after any number.
|
||||
ls.parser.parse_snippet({ trig = "%d", regTrig = true }, "A Number!!"),
|
||||
-- Using the condition, it's possible to allow expansion only in specific cases.
|
||||
s("cond", {
|
||||
t("will only expand in c-style comments"),
|
||||
}, {
|
||||
condition = function(line_to_cursor, matched_trigger, captures)
|
||||
-- optional whitespace followed by //
|
||||
return line_to_cursor:match("%s*//")
|
||||
end,
|
||||
}),
|
||||
-- there's some built-in conditions in "luasnip.extras.expand_conditions".
|
||||
s("cond2", {
|
||||
t("will only expand at the beginning of the line"),
|
||||
}, {
|
||||
condition = conds.line_begin,
|
||||
}),
|
||||
-- The last entry of args passed to the user-function is the surrounding snippet.
|
||||
s(
|
||||
{ trig = "a%d", regTrig = true },
|
||||
f(function(_, snip)
|
||||
return "Triggered with " .. snip.trigger .. "."
|
||||
end, {})
|
||||
),
|
||||
-- It's possible to use capture-groups inside regex-triggers.
|
||||
s(
|
||||
{ trig = "b(%d)", regTrig = true },
|
||||
f(function(_, snip)
|
||||
return "Captured Text: " .. snip.captures[1] .. "."
|
||||
end, {})
|
||||
),
|
||||
s({ trig = "c(%d+)", regTrig = true }, {
|
||||
t("will only expand for even numbers"),
|
||||
}, {
|
||||
condition = function(line_to_cursor, matched_trigger, captures)
|
||||
return tonumber(captures[1]) % 2 == 0
|
||||
end,
|
||||
}),
|
||||
-- Use a function to execute any shell command and print its text.
|
||||
s("bash", f(bash, {}, "ls")),
|
||||
-- Short version for applying String transformations using function nodes.
|
||||
s("transform", {
|
||||
i(1, "initial text"),
|
||||
t({ "", "" }),
|
||||
-- lambda nodes accept an l._1,2,3,4,5, which in turn accept any string transformations.
|
||||
-- This list will be applied in order to the first node given in the second argument.
|
||||
l(l._1:match("[^i]*$"):gsub("i", "o"):gsub(" ", "_"):upper(), 1),
|
||||
}),
|
||||
s("transform2", {
|
||||
i(1, "initial text"),
|
||||
t("::"),
|
||||
i(2, "replacement for e"),
|
||||
t({ "", "" }),
|
||||
-- Lambdas can also apply transforms USING the text of other nodes:
|
||||
l(l._1:gsub("e", l._2), { 1, 2 }),
|
||||
}),
|
||||
s({ trig = "trafo(%d+)", regTrig = true }, {
|
||||
-- env-variables and captures can also be used:
|
||||
l(l.CAPTURE1:gsub("1", l.TM_FILENAME), {}),
|
||||
}),
|
||||
-- Set store_selection_keys = "<Tab>" (for example) in your
|
||||
-- luasnip.config.setup() call to access TM_SELECTED_TEXT. In
|
||||
-- this case, select a URL, hit Tab, then expand this snippet.
|
||||
s("link_url", {
|
||||
t('<a href="'),
|
||||
f(function(_, snip)
|
||||
return snip.env.TM_SELECTED_TEXT[1] or {}
|
||||
end, {}),
|
||||
t('">'),
|
||||
i(1),
|
||||
t("</a>"),
|
||||
i(0),
|
||||
}),
|
||||
-- Shorthand for repeating the text in a given node.
|
||||
s("repeat", { i(1, "text"), t({ "", "" }), r(1) }),
|
||||
-- Directly insert the ouput from a function evaluated at runtime.
|
||||
s("part", p(os.date, "%Y")),
|
||||
-- use matchNodes to insert text based on a pattern/function/lambda-evaluation.
|
||||
s("mat", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(1, "%d", "contains a number", "no number :("),
|
||||
}),
|
||||
-- The inserted text defaults to the first capture group/the entire
|
||||
-- match if there are none
|
||||
s("mat2", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(1, "[abc][abc][abc]"),
|
||||
}),
|
||||
-- It is even possible to apply gsubs' or other transformations
|
||||
-- before matching.
|
||||
s("mat3", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(
|
||||
1,
|
||||
l._1:gsub("[123]", ""):match("%d"),
|
||||
"contains a number that isn't 1, 2 or 3!"
|
||||
),
|
||||
}),
|
||||
-- `match` also accepts a function, which in turn accepts a string
|
||||
-- (text in node, \n-concatted) and returns any non-nil value to match.
|
||||
-- If that value is a string, it is used for the default-inserted text.
|
||||
s("mat4", {
|
||||
i(1, { "sample_text" }),
|
||||
t(": "),
|
||||
m(1, function(text)
|
||||
return (#text % 2 == 0 and text) or nil
|
||||
end),
|
||||
}),
|
||||
-- The nonempty-node inserts text depending on whether the arg-node is
|
||||
-- empty.
|
||||
s("nempty", {
|
||||
i(1, "sample_text"),
|
||||
n(1, "i(1) is not empty!"),
|
||||
}),
|
||||
-- dynamic lambdas work exactly like regular lambdas, except that they
|
||||
-- don't return a textNode, but a dynamicNode containing one insertNode.
|
||||
-- This makes it easier to dynamically set preset-text for insertNodes.
|
||||
s("dl1", {
|
||||
i(1, "sample_text"),
|
||||
t({ ":", "" }),
|
||||
dl(2, l._1, 1),
|
||||
}),
|
||||
-- Obviously, it's also possible to apply transformations, just like lambdas.
|
||||
s("dl2", {
|
||||
i(1, "sample_text"),
|
||||
i(2, "sample_text_2"),
|
||||
t({ "", "" }),
|
||||
dl(3, l._1:gsub("\n", " linebreak ") .. l._2, { 1, 2 }),
|
||||
}),
|
||||
-- Alternative printf-like notation for defining snippets. It uses format
|
||||
-- string with placeholders similar to the ones used with Python's .format().
|
||||
s(
|
||||
"fmt1",
|
||||
fmt("To {title} {} {}.", {
|
||||
i(2, "Name"),
|
||||
i(3, "Surname"),
|
||||
title = c(1, { t("Mr."), t("Ms.") }),
|
||||
})
|
||||
),
|
||||
-- To escape delimiters use double them, e.g. `{}` -> `{{}}`.
|
||||
-- Multi-line format strings by default have empty first/last line removed.
|
||||
-- Indent common to all lines is also removed. Use the third `opts` argument
|
||||
-- to control this behaviour.
|
||||
s(
|
||||
"fmt2",
|
||||
fmt(
|
||||
[[
|
||||
foo({1}, {3}) {{
|
||||
return {2} * {4}
|
||||
}}
|
||||
]],
|
||||
{
|
||||
i(1, "x"),
|
||||
r(1),
|
||||
i(2, "y"),
|
||||
r(2),
|
||||
}
|
||||
)
|
||||
),
|
||||
-- Empty placeholders are numbered automatically starting from 1 or the last
|
||||
-- value of a numbered placeholder. Named placeholders do not affect numbering.
|
||||
s(
|
||||
"fmt3",
|
||||
fmt("{} {a} {} {1} {}", {
|
||||
t("1"),
|
||||
t("2"),
|
||||
a = t("A"),
|
||||
})
|
||||
),
|
||||
-- The delimiters can be changed from the default `{}` to something else.
|
||||
s(
|
||||
"fmt4",
|
||||
fmt("foo() { return []; }", i(1, "x"), { delimiters = "[]" })
|
||||
),
|
||||
-- `fmta` is a convenient wrapper that uses `<>` instead of `{}`.
|
||||
s("fmt5", fmta("foo() { return <>; }", i(1, "x"))),
|
||||
-- By default all args must be used. Use strict=false to disable the check
|
||||
s(
|
||||
"fmt6",
|
||||
fmt("use {} only", { t("this"), t("not this") }, { strict = false })
|
||||
),
|
||||
}, {
|
||||
key = "all",
|
||||
})
|
||||
|
||||
-- autotriggered snippets have to be defined in a separate table, luasnip.autosnippets.
|
||||
ls.autosnippets = {
|
||||
|
Reference in New Issue
Block a user