wiki/editor.neovim.plugins.luasnip.html

113 lines
25 KiB
HTML
Raw Permalink Normal View History

2022-07-29 15:41:17 +00:00
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width"/><meta charSet="utf-8"/><title>Neovim plugin: LuaSnip</title><script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script><script id="MathJax-script" async="" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script><script type="text/x-mathjax-config">
MathJax = {
tex: {
inlineMath: [ [&#x27;$&#x27;,&#x27;$&#x27;], [&#x27;\(&#x27;,&#x27;\)&#x27;] ],
displayMath: [ [&#x27;$$&#x27;,&#x27;$$&#x27;], [&#x27;[&#x27;,&#x27;]&#x27;] ]
},
options = {
processHtmlClass = &quot;math&quot;
}
}
</script><meta name="next-head-count" content="6"/><link rel="preload" href="/wiki/_next/static/css/52fc2ba29703df73922c.css" as="style"/><link rel="stylesheet" href="/wiki/_next/static/css/52fc2ba29703df73922c.css" data-n-g=""/><noscript data-n-css=""></noscript><link rel="preload" href="/wiki/_next/static/chunks/main-ae4733327bd95c4ac325.js" as="script"/><link rel="preload" href="/wiki/_next/static/chunks/webpack-50bee04d1dc61f8adf5b.js" as="script"/><link rel="preload" href="/wiki/_next/static/chunks/framework.9d524150d48315f49e80.js" as="script"/><link rel="preload" href="/wiki/_next/static/chunks/commons.0e1c3f9aa780c2dfe9f0.js" as="script"/><link rel="preload" href="/wiki/_next/static/chunks/pages/_app-8e3d0c58a60ec788aa69.js" as="script"/><link rel="preload" href="/wiki/_next/static/chunks/940643274e605e7596ecea1f2ff8d83317a3fb76.4841a16762f602a59f00.js" as="script"/><link rel="preload" href="/wiki/_next/static/chunks/pages/%5B%5B...slug%5D%5D-1aa198f87ede1cd0e1dc.js" as="script"/></head><body><div id="__next"><main><h1>Neovim plugin: LuaSnip</h1><section class="post-metadata"><span>Date: <!-- -->2022-04-21 15:33:29 +08:00</span><span>Date modified: <!-- -->2022-04-21 16:41:42 +08:00</span></section><nav class="toc"><ol class="toc-level toc-level-1"><li class="toc-item toc-item-h1"><a href="/wiki/editor.neovim.plugins.luasnip#example-snippets-in-lua" class="toc-link toc-link-h1">Example snippets in Lua</a><ol class="toc-level toc-level-2"><li class="toc-item toc-item-h2"><a href="/wiki/editor.neovim.plugins.luasnip#simple-word-trigger" class="toc-link toc-link-h2">Simple word trigger</a></li><li class="toc-item toc-item-h2"><a href="/wiki/editor.neovim.plugins.luasnip#patterned-trigger" class="toc-link toc-link-h2">Patterned trigger</a></li><li class="toc-item toc-item-h2"><a href="/wiki/editor.neovim.plugins.luasnip#choosing-between-asciidoctor-admonition-blocks" class="toc-link toc-link-h2">Choosing between Asciidoctor admonition blocks</a></li><li class="toc-item toc-item-h2"><a href="/wiki/editor.neovim.plugins.luasnip#dynamic-asciidoctor-header-with-optional-automatic-toc" class="toc-link toc-link-h2">Dynamic Asciidoctor header with optional automatic TOC</a></li></ol></li></ol></nav><ul><li><p>manual from <a href="/wiki/editor.neovim.help-system">Neovim help system</a>: <code class="inline-verbatim">luasnip.txt</code></p></li><li><p>snippets are made of nodes
</p></li><li><p>there are different type of nodes;
these can be found on the <code class="inline-verbatim">luasnip-snippets</code> on the manual
</p><ul><li><p><strong>text nodes</strong> are just static text
</p></li><li><p><strong>insert nodes</strong> are points to be edited;
can be given default text for the snippet
</p></li><li><p><strong>function nodes</strong> generate text based from other nodes;
this is used mostly to generate dynamic output from the snippet
</p></li><li><p><strong>choice nodes</strong> contains multiple nodes to be chosen for a given jump position
</p></li><li><p><strong>snippet nodes</strong> contains other node to be inserted in the snippet
</p></li><li><p><strong>dynamic nodes</strong> are similar to function nodes except they return snippet nodes
</p></li></ul></li><li><p>LuaSnip can support several types of snippets other than its own
</p><ul><li><p>SnipMate snippets
</p></li><li><p>Visual Studio Code snippets
</p></li><li><p>Lua snippets, obviously
</p></li></ul></li><li><p>snippets are not automatically loaded unless you have invoked the appropriate function for a certain type;
you will not load Visual Studio Code-style snippets unless you have run <code class="inline-verbatim">lazy_load</code> function from <code class="inline-verbatim">luasnip.loaders.from_vscode</code>;
for more details, each supported format has a specific section for loading them from the manual (e.g., <code class="inline-verbatim">luasnip-vscode-snippets-loader</code>)
</p></li><li><p>adding snippets is as simple as adding them in <code class="inline-verbatim">require(&quot;luasnip&quot;).snippets.FILETYPE</code>;
though, you have to know how to add a snippet through LuaSnip module
</p></li></ul><h1 id="example-snippets-in-lua">Example snippets in Lua</h1><p>We&#x27;ll explore different examples from the simplest to the more complex snippets made with Lua.
The following code blocks will assume the environment with the default value from <code class="inline-verbatim">luasnip.config.snip_env</code>.
</p><p>The plugin source code also has a comprehensive set of examples in the <code class="inline-verbatim">Examples/</code> folder.
It also has a <a href="https://github.com/L3MON4D3/LuaSnip/wiki">wiki</a> containing multiple example snippets showcasing the various nodes.
</p><h2 id="simple-word-trigger">Simple word trigger</h2><p>The simplest snippet possible.
This will simply replace <code class="inline-verbatim">hello</code> with <code class="inline-verbatim">world</code>.
</p><pre class="src-block"><code class="language-lua">s(&quot;hello&quot;, t &quot;world&quot;)
</code></pre><p>Exploring other nodes, we could replace the text node with a function node.
</p><pre class="src-block"><code class="language-lua">s(&quot;hello&quot;, f(function ()
return &quot;world&quot;
end))
</code></pre><h2 id="patterned-trigger">Patterned trigger</h2><p>A simple snippet that will answer you back when triggered.
</p><p>This snippet makes use of:
</p><ul><li><p>Pattern triggers (see <a href="roam:Lua patterns">roam:Lua patterns</a>).
</p></li><li><p>Snippet captures similar to UltiSnips&#x27; capture.
</p></li><li><p>Usage of a function node.
</p></li></ul><pre class="src-block"><code class="language-lua">s(
{ trig = &quot;hello (%a+)&quot;, regTrig = true },
f(function (_, snip)
return string.format(&quot;hey there, %s&quot;, snip.captures[1])
end)
)
</code></pre><h2 id="choosing-between-asciidoctor-admonition-blocks">Choosing between Asciidoctor admonition blocks</h2><p>We can easily create a snippet for multiple choices.
In Asciidoctor, we have <a href="https://docs.asciidoctor.org/asciidoc/latest/blocks/admonitions/">admonition blocks</a> that are formatted similarly.
</p><p>Here&#x27;s one way to define such snippet...
</p><pre class="src-block"><code class="language-lua">s(
&quot;admo&quot;,
fmt([[
{}: {}
]], {
c(1, {
t &quot;NOTE&quot;,
t &quot;TIP&quot;,
t &quot;IMPORTANT&quot;,
t &quot;CAUTION&quot;,
t &quot;WARNING&quot;,
}),
i(0),
})
)
</code></pre><h2 id="dynamic-asciidoctor-header-with-optional-automatic-toc">Dynamic Asciidoctor header with optional automatic TOC</h2><p>Here is a snippet for Asciidoc documents for creating headers.
As an example, <code class="inline-verbatim">h6</code> should print the appropriate header level.
</p><p>It should follow some restrictions for this snippet.
</p><ul><li><p>It can only have a maximum level of 6.
</p></li><li><p>As a bonus, we could set the table of contents on if the header level is 1.
</p></li></ul><p>This snippet makes use of dynamic node to change the node between a choice node for the first heading level and a blank text node for the rest.
</p><pre class="src-block"><code class="language-lua">function min_asciidoc_header_level(level)
math.min(level, 6)
end
s(
{ trig = &quot;h(%d)&quot;, regTrig = true },
fmt([[
{} {}
{}
{}
]], {
f(function(_, snip)
local level = min_asciidoc_header(snip.captures[1])
return string.rep(&quot;=&quot;, level)
end),
i(1, &quot;CHAPTER&quot;),
d(2, function(_, snip)
local nodes = {}
table.insert(nodes, t &quot;&quot;)
local level = min_asciidoc_header(snip.captures[1])
if level == 1 then
table.insert(nodes, t &quot;:toc:&quot;)
end
local parent = c(1, nodes)
if level &gt; 1 then
parent = t &quot;&quot;
end
return sn(nil, parent)
end, {}),
i(0),
})
)
</code></pre></main></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"metadata":{"date":"2022-04-21 15:33:29 +08:00","date_modified":"2022-04-21 16:41:42 +08:00","language":"en","source":""},"title":"Neovim plugin: LuaSnip","hast":{"type":"root","children":[{"type":"element","tagName":"nav","properties":{"className":"toc"},"children":[{"type":"element","tagName":"ol","properties":{"className":"toc-level toc-level-1"},"children":[{"type":"element","tagName":"li","data":{"hookArgs":[{"type":"element","tagName":"h1","properties":{"id":"example-snippets-in-lua"},"children":[{"type":"text","value":"Example snippets in Lua"}]}]},"properties":{"className":"toc-item toc-item-h1"},"children":[{"type":"element","tagName":"a","properties":{"className":"toc-link toc-link-h1","href":"/editor.neovim.plugins.luasnip#example-snippets-in-lua"},"children":[{"type":"text","value":"Example snippets in Lua"}]},{"type":"element","tagName":"ol","properties":{"className":"toc-level toc-level-2"},"children":[{"type":"element","tagName":"li","data":{"hookArgs":[{"type":"element","tagName":"h2","properties":{"id":"simple-word-trigger"},"children":[{"type":"text","value":"Simple word trigger"}]}]},"properties":{"className":"toc-item toc-item-h2"},"children":[{"type":"element","tagName":"a","properties":{"className":"toc-link toc-link-h2","href":"/editor.neovim.plugins.luasnip#simple-word-trigger"},"children":[{"type":"text","value":"Simple word trigger"}]}]},{"type":"element","tagName":"li","data":{"hookArgs":[{"type":"element","tagName":"h2","properties":{"id":"patterned-trigger"},"children":[{"type":"text","value":"Patterned trigger"}]}]},"properties":{"className":"toc-item toc-item-h2"},"children":[{"type":"element","tagName":"a","properties":{"className":"toc-link toc-link-h2","href":"/editor.neovim.plugins.luasnip#patterned-trigger"},"children":[{"type":"text","value":"Patterned trigger"}]}]},{"type":"element","tagName":"li","data":{"hookArgs":[{"type":"element","tagName":"h2","properties":{"id":"choosing-between-asciidoctor-admonition-blocks"},"children":[{"type":"text","value":"Choosing between Asciidoctor admonition blocks"}]}]},"properties":{"className":"toc-item toc-item-h2"},"children":[{"type":"element","tagName":"a","properties":{"className":"toc-link toc-link-h2","href":"/editor.neovim.plugins.luasnip#choosing-between-asciidoctor-admonition-blocks"},"children":[{"type":"text","value":"Choosing between Asciidoctor admonition blocks"}]}]},{"type":"element","tagName":"li","data":{"hookArgs":[{"type":"element","tagName":"h2","properties":{"id":"dynamic-asciidoctor-header-with-optional-automatic-toc"},"children":[{"type":"text","value":"Dynamic Asciidoctor header with optional automatic TOC"}]}]},"properties":{"className":"toc-item toc-item-h2"},"children":[{"type":"element","tagName":"a","properties":{"className":"toc-link toc-link-h2","href":"/editor.neovim.plugins.luasnip#dynamic-asciidoctor-header-with-optional-automatic-toc"},"children":[{"type":"text","value":"Dynamic Asciidoctor header with optional automatic TOC"}]}]}]}]}]}]},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"manual from "},{"type":"element","tagName":"a","properties":{"href":"/editor.neovim.help-system"},"children":[{"type":"text","value":"Neovim help system"}]},{"type":"text","value":": "},{"type":"element","tagName":"code","properties":{"className":["inline-verbatim"]},"children":[{"type":"text","value":"luasnip.txt"}]}]}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"snippets are made of nodes\n"}]}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"there are different type of nodes;\n these can be found on the "},{"type":"element","tagName":"code","properties":{"className":["inline-v