nvim: refactor telescope and add luasnip config
This commit is contained in:
parent
e7b04a5cd7
commit
1247556247
5 changed files with 631 additions and 20 deletions
|
@ -1,7 +1,8 @@
|
||||||
-- remap leader to <space>
|
-- remap leader to <space>
|
||||||
vim.g.mapleader = ' '
|
vim.g.mapleader = ' '
|
||||||
|
|
||||||
require('settings')
|
require('plugins')
|
||||||
require('lsp')
|
require('lsp')
|
||||||
require('keymappings')
|
require('keymappings')
|
||||||
require('plugins')
|
require('settings')
|
||||||
|
require('snippets')
|
||||||
|
|
|
@ -81,12 +81,12 @@ require('packer').startup(function()
|
||||||
use { 'hedyhli/outline.nvim' }
|
use { 'hedyhli/outline.nvim' }
|
||||||
|
|
||||||
use { "catppuccin/nvim", as = "catppuccin" }
|
use { "catppuccin/nvim", as = "catppuccin" }
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
require('plugins.catppuccin')
|
require('plugins.catppuccin')
|
||||||
require('plugins.cmp')
|
require('plugins.cmp')
|
||||||
require('plugins.gitsigns')
|
require('plugins.gitsigns')
|
||||||
|
require('plugins.luasnip_config')
|
||||||
require('plugins.neogit')
|
require('plugins.neogit')
|
||||||
require('plugins.oil')
|
require('plugins.oil')
|
||||||
require('plugins.outline')
|
require('plugins.outline')
|
||||||
|
|
12
dotfiles/.config/nvim/lua/plugins/luasnip_config.lua
Normal file
12
dotfiles/.config/nvim/lua/plugins/luasnip_config.lua
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
local luasnip = require('luasnip')
|
||||||
|
local lst = require('telescope').extensions.luasnip
|
||||||
|
|
||||||
|
vim.keymap.set({ "i" }, "<C-K>", function() luasnip.expand() end, { silent = true })
|
||||||
|
vim.keymap.set({ "i", "s" }, "<C-L>", function() luasnip.jump(1) end, { silent = true })
|
||||||
|
vim.keymap.set({ "i", "s" }, "<C-J>", function() luasnip.jump(-1) end, { silent = true })
|
||||||
|
|
||||||
|
vim.keymap.set({ "i", "s" }, "<C-E>", function()
|
||||||
|
if luasnip.choice_active() then
|
||||||
|
luasnip.change_choice(1)
|
||||||
|
end
|
||||||
|
end, { silent = true })
|
|
@ -4,25 +4,47 @@ local builtin = require('telescope.builtin')
|
||||||
|
|
||||||
local telescope_last = 0
|
local telescope_last = 0
|
||||||
function telescope_resume()
|
function telescope_resume()
|
||||||
if telescope_last == 0 then
|
if telescope_last == 0 then
|
||||||
telescope_last = 1
|
telescope_last = 1
|
||||||
builtin.live_grep()
|
builtin.live_grep()
|
||||||
else
|
else
|
||||||
builtin.resume()
|
builtin.resume()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local files_config = {
|
||||||
|
cache_picker = false,
|
||||||
|
layout_strategy = "vertical",
|
||||||
|
layout_config = {
|
||||||
|
vertical = {
|
||||||
|
prompt_position = "top",
|
||||||
|
mirror = true,
|
||||||
|
width = 0.5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
telescope.setup {
|
telescope.setup {
|
||||||
defaults = {
|
defaults = {
|
||||||
sorting_strategy = "ascending",
|
sorting_strategy = "ascending",
|
||||||
live_grep_arguments = { 'rg',
|
vimgrep_arguments = {
|
||||||
'--hidden', '--no-ignore', '--color=never',
|
'rg',
|
||||||
'--with-filename', '--line-number',
|
'--hidden',
|
||||||
'--column', '--smart-case', '--no-heading',
|
'--no-ignore',
|
||||||
|
'--color=never',
|
||||||
|
'--with-filename',
|
||||||
|
'--line-number',
|
||||||
|
'--column',
|
||||||
|
'--smart-case',
|
||||||
|
'--no-heading',
|
||||||
|
'-u',
|
||||||
},
|
},
|
||||||
preview = {
|
preview = {
|
||||||
treesitter = false
|
treesitter = false
|
||||||
},
|
},
|
||||||
|
file_ignore_patterns = {
|
||||||
|
'.git',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
pickers = {
|
pickers = {
|
||||||
live_grep = {
|
live_grep = {
|
||||||
|
@ -31,12 +53,10 @@ telescope.setup {
|
||||||
n = { ["<c-f>"] = telescope_resume },
|
n = { ["<c-f>"] = telescope_resume },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
find_files = {
|
find_files = vim.tbl_extend("force", files_config, {
|
||||||
cache_picker = false,
|
hidden = true,
|
||||||
},
|
}),
|
||||||
git_files = {
|
git_files = files_config,
|
||||||
cache_picker = false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +64,7 @@ telescope.setup {
|
||||||
vim.keymap.set('n', '<leader>ss', telescope.extensions.luasnip.luasnip, {})
|
vim.keymap.set('n', '<leader>ss', telescope.extensions.luasnip.luasnip, {})
|
||||||
|
|
||||||
-- Fuzzy * files, symbols, buffers, help, etc.
|
-- Fuzzy * files, symbols, buffers, help, etc.
|
||||||
vim.keymap.set('n', '<leader>fa', builtin.find_files) -- f[ind]a[ll]
|
vim.keymap.set('n', '<leader>fa', builtin.find_files) -- f[ind]a[ll]
|
||||||
vim.keymap.set('n', '<leader>fb', builtin.buffers)
|
vim.keymap.set('n', '<leader>fb', builtin.buffers)
|
||||||
vim.keymap.set('n', '<leader>fd', builtin.diagnostics)
|
vim.keymap.set('n', '<leader>fd', builtin.diagnostics)
|
||||||
vim.keymap.set('n', '<leader>ff', builtin.git_files)
|
vim.keymap.set('n', '<leader>ff', builtin.git_files)
|
||||||
|
|
578
dotfiles/.config/nvim/lua/snippets.lua
Normal file
578
dotfiles/.config/nvim/lua/snippets.lua
Normal file
|
@ -0,0 +1,578 @@
|
||||||
|
local ls = require("luasnip")
|
||||||
|
-- some shorthands...
|
||||||
|
local s = ls.snippet
|
||||||
|
local sn = ls.snippet_node
|
||||||
|
local t = ls.text_node
|
||||||
|
local i = ls.insert_node
|
||||||
|
local f = ls.function_node
|
||||||
|
local c = ls.choice_node
|
||||||
|
local d = ls.dynamic_node
|
||||||
|
local r = ls.restore_node
|
||||||
|
local l = require("luasnip.extras").lambda
|
||||||
|
local rep = require("luasnip.extras").rep
|
||||||
|
local p = require("luasnip.extras").partial
|
||||||
|
local m = require("luasnip.extras").match
|
||||||
|
local n = require("luasnip.extras").nonempty
|
||||||
|
local dl = require("luasnip.extras").dynamic_lambda
|
||||||
|
local fmt = require("luasnip.extras.fmt").fmt
|
||||||
|
local fmta = require("luasnip.extras.fmt").fmta
|
||||||
|
local types = require("luasnip.util.types")
|
||||||
|
local conds = require("luasnip.extras.conditions")
|
||||||
|
local conds_expand = require("luasnip.extras.conditions.expand")
|
||||||
|
|
||||||
|
-- If you're reading this file for the first time, best skip to around line 190
|
||||||
|
-- where the actual snippet-definitions start.
|
||||||
|
|
||||||
|
-- Every unspecified option will be set to the default.
|
||||||
|
ls.setup({
|
||||||
|
keep_roots = true,
|
||||||
|
link_roots = true,
|
||||||
|
link_children = true,
|
||||||
|
|
||||||
|
-- Update more often, :h events for more info.
|
||||||
|
update_events = "TextChanged,TextChangedI",
|
||||||
|
-- Snippets aren't automatically removed if their text is deleted.
|
||||||
|
-- `delete_check_events` determines on which events (:h events) a check for
|
||||||
|
-- deleted snippets is performed.
|
||||||
|
-- This can be especially useful when `history` is enabled.
|
||||||
|
delete_check_events = "TextChanged",
|
||||||
|
ext_opts = {
|
||||||
|
[types.choiceNode] = {
|
||||||
|
active = {
|
||||||
|
virt_text = { { "choiceNode", "Comment" } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- treesitter-hl has 100, use something higher (default is 200).
|
||||||
|
ext_base_prio = 300,
|
||||||
|
-- minimal increase in priority.
|
||||||
|
ext_prio_increase = 1,
|
||||||
|
enable_autosnippets = true,
|
||||||
|
-- mapping for cutting selected text so it's usable as SELECT_DEDENT,
|
||||||
|
-- SELECT_RAW or TM_SELECTED_TEXT (mapped via xmap).
|
||||||
|
store_selection_keys = "<Tab>",
|
||||||
|
-- luasnip uses this function to get the currently active filetype. This
|
||||||
|
-- is the (rather uninteresting) default, but it's possible to use
|
||||||
|
-- eg. treesitter for getting the current filetype by setting ft_func to
|
||||||
|
-- require("luasnip.extras.filetype_functions").from_cursor (requires
|
||||||
|
-- `nvim-treesitter/nvim-treesitter`). This allows correctly resolving
|
||||||
|
-- the current filetype in eg. a markdown-code block or `vim.cmd()`.
|
||||||
|
ft_func = function()
|
||||||
|
return vim.split(vim.bo.filetype, ".", true)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- args is a table, where 1 is the text in Placeholder 1, 2 the text in
|
||||||
|
-- placeholder 2,...
|
||||||
|
local function copy(args)
|
||||||
|
return args[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 'recursive' dynamic snippet. Expands to some text followed by itself.
|
||||||
|
local rec_ls
|
||||||
|
rec_ls = function()
|
||||||
|
return sn(
|
||||||
|
nil,
|
||||||
|
c(1, {
|
||||||
|
-- Order is important, sn(...) first would cause infinite loop of expansion.
|
||||||
|
t(""),
|
||||||
|
sn(nil, { t({ "", "\t\\item " }), i(1), d(2, rec_ls, {}) }),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- complicated function for dynamicNode.
|
||||||
|
local function jdocsnip(args, _, old_state)
|
||||||
|
-- !!! old_state is used to preserve user-input here. DON'T DO IT THAT WAY!
|
||||||
|
-- Using a restoreNode instead is much easier.
|
||||||
|
-- View this only as an example on how old_state functions.
|
||||||
|
local nodes = {
|
||||||
|
t({ "/**", " * " }),
|
||||||
|
i(1, "A short Description"),
|
||||||
|
t({ "", "" }),
|
||||||
|
}
|
||||||
|
|
||||||
|
-- These will be merged with the snippet; that way, should the snippet be updated,
|
||||||
|
-- some user input eg. text can be referred to in the new snippet.
|
||||||
|
local param_nodes = {}
|
||||||
|
|
||||||
|
if old_state then
|
||||||
|
nodes[2] = i(1, old_state.descr:get_text())
|
||||||
|
end
|
||||||
|
param_nodes.descr = nodes[2]
|
||||||
|
|
||||||
|
-- At least one param.
|
||||||
|
if string.find(args[2][1], ", ") then
|
||||||
|
vim.list_extend(nodes, { t({ " * ", "" }) })
|
||||||
|
end
|
||||||
|
|
||||||
|
local insert = 2
|
||||||
|
for indx, arg in ipairs(vim.split(args[2][1], ", ", true)) do
|
||||||
|
-- Get actual name parameter.
|
||||||
|
arg = vim.split(arg, " ", true)[2]
|
||||||
|
if arg then
|
||||||
|
local inode
|
||||||
|
-- if there was some text in this parameter, use it as static_text for this new snippet.
|
||||||
|
if old_state and old_state[arg] then
|
||||||
|
inode = i(insert, old_state["arg" .. arg]:get_text())
|
||||||
|
else
|
||||||
|
inode = i(insert)
|
||||||
|
end
|
||||||
|
vim.list_extend(
|
||||||
|
nodes,
|
||||||
|
{ t({ " * @param " .. arg .. " " }), inode, t({ "", "" }) }
|
||||||
|
)
|
||||||
|
param_nodes["arg" .. arg] = inode
|
||||||
|
|
||||||
|
insert = insert + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if args[1][1] ~= "void" then
|
||||||
|
local inode
|
||||||
|
if old_state and old_state.ret then
|
||||||
|
inode = i(insert, old_state.ret:get_text())
|
||||||
|
else
|
||||||
|
inode = i(insert)
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.list_extend(
|
||||||
|
nodes,
|
||||||
|
{ t({ " * ", " * @return " }), inode, t({ "", "" }) }
|
||||||
|
)
|
||||||
|
param_nodes.ret = inode
|
||||||
|
insert = insert + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim.tbl_count(args[3]) ~= 1 then
|
||||||
|
local exc = string.gsub(args[3][2], " throws ", "")
|
||||||
|
local ins
|
||||||
|
if old_state and old_state.ex then
|
||||||
|
ins = i(insert, old_state.ex:get_text())
|
||||||
|
else
|
||||||
|
ins = i(insert)
|
||||||
|
end
|
||||||
|
vim.list_extend(
|
||||||
|
nodes,
|
||||||
|
{ t({ " * ", " * @throws " .. exc .. " " }), ins, t({ "", "" }) }
|
||||||
|
)
|
||||||
|
param_nodes.ex = ins
|
||||||
|
insert = insert + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.list_extend(nodes, { t({ " */" }) })
|
||||||
|
|
||||||
|
local snip = sn(nil, nodes)
|
||||||
|
-- Error on attempting overwrite.
|
||||||
|
snip.old_state = param_nodes
|
||||||
|
return snip
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Make sure to not pass an invalid command, as io.popen() may write over nvim-text.
|
||||||
|
local function bash(_, _, command)
|
||||||
|
local file = io.popen(command, "r")
|
||||||
|
local res = {}
|
||||||
|
for line in file:lines() do
|
||||||
|
table.insert(res, line)
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns a snippet_node wrapped around an insertNode whose initial
|
||||||
|
-- text value is set to the current date in the desired format.
|
||||||
|
local date_input = function(args, snip, old_state, fmt)
|
||||||
|
local fmt = fmt or "%Y-%m-%d"
|
||||||
|
return sn(nil, i(1, os.date(fmt)))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 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`, second argument to snippet-constructor are the nodes to insert into the buffer on expansion.
|
||||||
|
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.
|
||||||
|
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 insertNodes. !!! 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 "),
|
||||||
|
-- restoreNode: stores and restores nodes.
|
||||||
|
-- pass position, store-key and nodes.
|
||||||
|
r(1, "other_class", i(1)),
|
||||||
|
t(" {"),
|
||||||
|
}),
|
||||||
|
sn(nil, {
|
||||||
|
t("implements "),
|
||||||
|
-- no need to define the nodes for a given key a second time.
|
||||||
|
r(1, "other_class"),
|
||||||
|
t(" {"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
t({ "", "\t" }),
|
||||||
|
i(0),
|
||||||
|
t({ "", "}" }),
|
||||||
|
}),
|
||||||
|
-- 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"),
|
||||||
|
rep(1),
|
||||||
|
i(2, "y"),
|
||||||
|
rep(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 })
|
||||||
|
),
|
||||||
|
-- Use a dynamicNode to interpolate the output of a
|
||||||
|
-- function (see date_input above) into the initial
|
||||||
|
-- value of an insertNode.
|
||||||
|
s("novel", {
|
||||||
|
t("It was a dark and stormy night on "),
|
||||||
|
d(1, date_input, {}, { user_args = { "%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 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.conditions.expand" and "luasnip.extras.conditions.show".
|
||||||
|
s("cond2", {
|
||||||
|
t("will only expand at the beginning of the line"),
|
||||||
|
}, {
|
||||||
|
condition = conds_expand.line_begin,
|
||||||
|
}),
|
||||||
|
s("cond3", {
|
||||||
|
t("will only expand at the end of the line"),
|
||||||
|
}, {
|
||||||
|
condition = conds_expand.line_end,
|
||||||
|
}),
|
||||||
|
-- on conditions some logic operators are defined
|
||||||
|
s("cond4", {
|
||||||
|
t("will only expand at the end and the start of the line"),
|
||||||
|
}, {
|
||||||
|
-- last function is just an example how to make own function objects and apply operators on them
|
||||||
|
condition = conds_expand.line_end
|
||||||
|
+ conds_expand.line_begin
|
||||||
|
* conds.make_condition(function()
|
||||||
|
return true
|
||||||
|
end),
|
||||||
|
}),
|
||||||
|
-- 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, {}, { user_args = { "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 populate
|
||||||
|
-- TM_SELECTED_TEXT/SELECT_RAW/SELECT_DEDENT.
|
||||||
|
-- In this case: select a URL, hit Tab, then expand this snippet.
|
||||||
|
s("link_url", {
|
||||||
|
t('<a href="'),
|
||||||
|
f(function(_, snip)
|
||||||
|
-- TM_SELECTED_TEXT is a table to account for multiline-selections.
|
||||||
|
-- In this case only the first line is inserted.
|
||||||
|
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({ "", "" }), rep(1) }),
|
||||||
|
-- Directly insert the ouput from a function evaluated at runtime.
|
||||||
|
s("part", p(os.date, "%Y")),
|
||||||
|
-- use matchNodes (`m(argnode, condition, then, else)`) to insert text
|
||||||
|
-- based on a pattern/function/lambda-evaluation.
|
||||||
|
-- It's basically a shortcut for simple functionNodes:
|
||||||
|
s("mat", {
|
||||||
|
i(1, { "sample_text" }),
|
||||||
|
t(": "),
|
||||||
|
m(1, "%d", "contains a number", "no number :("),
|
||||||
|
}),
|
||||||
|
-- The `then`-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 in place of the condition, which in
|
||||||
|
-- turn accepts the usual functionNode-args.
|
||||||
|
-- The condition is considered true if the function returns any
|
||||||
|
-- non-nil/false-value.
|
||||||
|
-- If that value is a string, it is used as the `if`-text if no if is explicitly given.
|
||||||
|
s("mat4", {
|
||||||
|
i(1, { "sample_text" }),
|
||||||
|
t(": "),
|
||||||
|
m(1, function(args)
|
||||||
|
-- args is a table of multiline-strings (as usual).
|
||||||
|
return (#args[1][1] % 2 == 0 and args[1]) 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 }),
|
||||||
|
}),
|
||||||
|
}, {
|
||||||
|
key = "all",
|
||||||
|
})
|
||||||
|
|
||||||
|
ls.add_snippets("java", {
|
||||||
|
-- Very long example for a java class.
|
||||||
|
s("fn", {
|
||||||
|
d(6, jdocsnip, { 2, 4, 5 }),
|
||||||
|
t({ "", "" }),
|
||||||
|
c(1, {
|
||||||
|
t("public "),
|
||||||
|
t("private "),
|
||||||
|
}),
|
||||||
|
c(2, {
|
||||||
|
t("void"),
|
||||||
|
t("String"),
|
||||||
|
t("char"),
|
||||||
|
t("int"),
|
||||||
|
t("double"),
|
||||||
|
t("boolean"),
|
||||||
|
i(nil, ""),
|
||||||
|
}),
|
||||||
|
t(" "),
|
||||||
|
i(3, "myFunc"),
|
||||||
|
t("("),
|
||||||
|
i(4),
|
||||||
|
t(")"),
|
||||||
|
c(5, {
|
||||||
|
t(""),
|
||||||
|
sn(nil, {
|
||||||
|
t({ "", " throws " }),
|
||||||
|
i(1),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
t({ " {", "\t" }),
|
||||||
|
i(0),
|
||||||
|
t({ "", "}" }),
|
||||||
|
}),
|
||||||
|
}, {
|
||||||
|
key = "java",
|
||||||
|
})
|
||||||
|
|
||||||
|
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),
|
||||||
|
d(2, rec_ls, {}),
|
||||||
|
t({ "", "\\end{itemize}" }),
|
||||||
|
}),
|
||||||
|
}, {
|
||||||
|
key = "tex",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- set type to "autosnippets" for adding autotriggered snippets.
|
||||||
|
ls.add_snippets("all", {
|
||||||
|
s("autotrigger", {
|
||||||
|
t("autosnippet"),
|
||||||
|
}),
|
||||||
|
}, {
|
||||||
|
type = "autosnippets",
|
||||||
|
key = "all_auto",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- in a lua file: search lua-, then c-, then all-snippets.
|
||||||
|
ls.filetype_extend("lua", { "c" })
|
||||||
|
-- in a cpp file: search c-snippets, then all-snippets only (no cpp-snippets!!).
|
||||||
|
ls.filetype_set("cpp", { "c" })
|
||||||
|
|
||||||
|
-- Beside defining your own snippets you can also load snippets from "vscode-like" packages
|
||||||
|
-- that expose snippets in json files, for example <https://github.com/rafamadriz/friendly-snippets>.
|
||||||
|
|
||||||
|
require("luasnip.loaders.from_vscode").load({ include = { "python" } }) -- Load only python snippets
|
||||||
|
|
||||||
|
-- The directories will have to be structured like eg. <https://github.com/rafamadriz/friendly-snippets> (include
|
||||||
|
-- a similar `package.json`)
|
||||||
|
require("luasnip.loaders.from_vscode").load({ paths = { "./my-snippets" } }) -- Load snippets from my-snippets folder
|
||||||
|
|
||||||
|
-- You can also use lazy loading so snippets are loaded on-demand, not all at once (may interfere with lazy-loading luasnip itself).
|
||||||
|
require("luasnip.loaders.from_vscode").lazy_load() -- You can pass { paths = "./my-snippets/"} as well
|
||||||
|
|
||||||
|
-- You can also use snippets in snipmate format, for example <https://github.com/honza/vim-snippets>.
|
||||||
|
-- The usage is similar to vscode.
|
||||||
|
|
||||||
|
-- One peculiarity of honza/vim-snippets is that the file containing global
|
||||||
|
-- snippets is _.snippets, so we need to tell luasnip that the filetype "_"
|
||||||
|
-- contains global snippets:
|
||||||
|
ls.filetype_extend("all", { "_" })
|
||||||
|
|
||||||
|
require("luasnip.loaders.from_snipmate").load({ include = { "c" } }) -- Load only snippets for c.
|
||||||
|
|
||||||
|
-- Load snippets from my-snippets folder
|
||||||
|
-- The "." refers to the directory where of your `$MYVIMRC` (you can print it
|
||||||
|
-- out with `:lua print(vim.env.MYVIMRC)`.
|
||||||
|
-- NOTE: It's not always set! It isn't set for example if you call neovim with
|
||||||
|
-- the `-u` argument like this: `nvim -u yeet.txt`.
|
||||||
|
require("luasnip.loaders.from_snipmate").load({ path = { "./my-snippets" } })
|
||||||
|
-- If path is not specified, luasnip will look for the `snippets` directory in rtp (for custom-snippet probably
|
||||||
|
-- `~/.config/nvim/snippets`).
|
||||||
|
|
||||||
|
require("luasnip.loaders.from_snipmate").lazy_load() -- Lazy loading
|
||||||
|
|
||||||
|
-- see DOC.md/LUA SNIPPETS LOADER for some details.
|
||||||
|
require("luasnip.loaders.from_lua").load({ include = { "c" } })
|
||||||
|
require("luasnip.loaders.from_lua").lazy_load({ include = { "all", "cpp" } })
|
Loading…
Reference in a new issue