summaryrefslogtreecommitdiff
path: root/stowables-dotlocal/share/nvim/site/pack/manual/start/LuaSnip-v2.3.0/lua/luasnip/loaders/init.lua
blob: daf6064c313ebe62121c2397a7390d7645d9af31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
local util = require("luasnip.util.util")
local Path = require("luasnip.util.path")
local loader_util = require("luasnip.loaders.util")
local session = require("luasnip.session")
local loader_data = require("luasnip.loaders.data")
local fs_watchers = require("luasnip.loaders.fs_watchers")
local log = require("luasnip.util.log").new("loader")

local M = {}

-- used to map cache-name to name passed to format.
local clean_name = {
	vscode_packages = "vscode",
	vscode_standalone = "vscode-standalone",
	snipmate = "snipmate",
	lua = "lua",
}
local function default_format(path, _)
	path = path:gsub(
		vim.pesc(vim.fn.stdpath("data") .. "/site/pack/packer/start"),
		"$PLUGINS"
	)
	if vim.env.HOME then
		path = path:gsub(vim.pesc(vim.env.HOME .. "/.config/nvim"), "$CONFIG")
	end
	return path
end

local function default_edit(file)
	vim.cmd("edit " .. file)
end

--- Quickly jump to snippet-file from any source for the active filetypes.
---@param opts nil|table, options for this function:
--- - ft_filter: fn(filetype:string) -> bool
---   Optionally filter filetypes which can be picked from. `true` -> filetype
---   is listed, `false` -> not listed.
---
--- - format: fn(path:string, source_name:string) -> string|nil
---   source_name is one of "vscode", "snipmate" or "lua".
---   May be used to format the displayed items. For example, replace the
---   excessively long packer-path with something shorter.
---   If format returns nil for some item, the item will not be displayed.
---
--- - edit: fn(file:string): this function is called with the snippet-file as
---   the lone argument.
---   The default is a function which just calls `vim.cmd("edit " .. file)`.
function M.edit_snippet_files(opts)
	opts = opts or {}
	local format = opts.format or default_format
	local edit = opts.edit or default_edit
	local extend = opts.extend or function(_, _)
		return {}
	end

	local function ft_edit_picker(ft, _)
		if ft then
			local ft_paths = {}
			local items = {}

			-- concat files from all loaders for the selected filetype ft.
			for cache_name, ft_file_set in pairs({
				vscode_packages = loader_data.vscode_ft_paths[ft],
				vscode_standalone = {},
				snipmate = loader_data.snipmate_ft_paths[ft],
				lua = loader_data.lua_ft_paths[ft],
			}) do
				for path, _ in pairs(ft_file_set or {}) do
					local fmt_name = format(path, clean_name[cache_name])
					if fmt_name then
						table.insert(ft_paths, path)
						table.insert(items, fmt_name)
					end
				end
			end

			-- extend filetypes with user-defined function.
			local extended = extend(ft, ft_paths)
			assert(
				type(extended) == "table",
				"You must return a table in extend function"
			)
			for _, pair in ipairs(extended) do
				table.insert(items, pair[1])
				table.insert(ft_paths, pair[2])
			end

			-- prompt user again if there are multiple files providing this filetype.
			if #ft_paths > 1 then
				vim.ui.select(items, {
					prompt = "Multiple files for this filetype, choose one:",
				}, function(_, indx)
					if indx and ft_paths[indx] then
						edit(ft_paths[indx])
					end
				end)
			elseif ft_paths[1] then
				edit(ft_paths[1])
			end
		end
	end

	local ft_filter = opts.ft_filter or util.yes

	local all_fts = {}
	vim.list_extend(all_fts, util.get_snippet_filetypes())
	vim.list_extend(
		all_fts,
		loader_util.get_load_fts(vim.api.nvim_get_current_buf())
	)
	all_fts = util.deduplicate(all_fts)

	local filtered_fts = {}
	for _, ft in ipairs(all_fts) do
		if ft_filter(ft) then
			table.insert(filtered_fts, ft)
		end
	end

	if #filtered_fts == 1 then
		ft_edit_picker(filtered_fts[1])
	elseif #filtered_fts > 1 then
		vim.ui.select(filtered_fts, {
			prompt = "Select filetype:",
		}, ft_edit_picker)
	end
end

function M.cleanup()
	require("luasnip.loaders.from_lua").clean()
	require("luasnip.loaders.from_snipmate").clean()
	require("luasnip.loaders.from_vscode").clean()
end

function M.load_lazy_loaded(bufnr)
	local fts = loader_util.get_load_fts(bufnr)

	for _, ft in ipairs(fts) do
		if not session.loaded_fts[ft] then
			require("luasnip.loaders.from_lua")._load_lazy_loaded_ft(ft)
			require("luasnip.loaders.from_snipmate")._load_lazy_loaded_ft(ft)
			require("luasnip.loaders.from_vscode")._load_lazy_loaded_ft(ft)
		end
		session.loaded_fts[ft] = true
	end
end

function M.reload_file(path)
	local realpath = Path.normalize(path)
	if not realpath then
		return nil, ("Could not reload file %s: does not exist."):format(path)
	else
		fs_watchers.write_notify(realpath)
		return true
	end
end

return M