Skip to content

Commit

Permalink
feat: major overhaul of loaders. Check DOC.md-changes for the gist.
Browse files Browse the repository at this point in the history
Previously, we could not
* add files that were not present when `load/lazy_load` was called to
  the collection. This is pretty annoying if one wants to add
  project-local snippets, or snippets for a new filetype (ofc).
* load collections whose directory/package.json(c) did not exist when
  `load` was called.
  This is also an annoyance when creating project-local snippets, since
  a re-`load()` is required for the snippets to be picked up.
* pick up on changes to the snippet-files from another neovim-instance
  (due to reloading on BufWritePost)

This patch fixes all of these by modularizing the loaders a bit more,
into one component ("Collection") which takes care of all the logic of
loading different files, and another ("fswatchers") which notify the
collections when a file-change is detected. This allows, first of all, a
better design where the first concern can be nullified, and secondly, us
to use libuvs api for file-watching, to implement the last two (if a
potentially non-existing collection should be loaded, we can use libuv
to wait for the collection-root/manifest-file, and create the collection
once that exists).

Another cool addition is the loader-snippet-cache, which makes it so
that the snippet files (for vscode and snipmate) are only loaded once
for all filetypes, and not once for each filetype. That's probably not
noticeable though, except if a collection with many extends/languages
for one json-file is loaded :D
  • Loading branch information
L3MON4D3 committed Dec 2, 2023
1 parent 3f58738 commit 3a47a1f
Show file tree
Hide file tree
Showing 19 changed files with 2,497 additions and 737 deletions.
19 changes: 19 additions & 0 deletions DOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -2544,12 +2544,28 @@ where `opts` can contain the following keys:
- `snipmate`: similar to lua, but the directory has to be `"snippets"`.
- `vscode`: any directory in `runtimepath` that contains a
`package.json` contributing snippets.
- `lazy_paths`: behaves essentially like `paths`, with two exceptions: if it is
`nil`, it does not default to `runtimepath`, and the paths listed here do not
need to exist, and will be loaded on creation.
LuaSnip will do its best to determine the path that this should resolve to,
but since the resolving we do is not very sophisticated it may produce
incorrect paths. Definitely check the log if snippets are not loaded as
expected.
- `exclude`: List of languages to exclude, empty by default.
- `include`: List of languages to include, includes everything by default.
- `{override,default}_priority`: These keys are passed straight to the
`add_snippets`-calls (documented in [API](#api)) and can therefore change the
priority of snippets loaded from some colletion (or, in combination with
`{in,ex}clude`, only some of its snippets).
- `fs_event_providers`: `table<string, boolean>?`, specifies which mechanisms
should be used to watch files for updates/creation.
If `autocmd` is set to `true`, a `BufWritePost`-hook watches files of this
collection, if `libuv` is set, the file-watcher-api exposed by libuv is used
to watch for updates.
Use `libuv` if you want snippets to update from other neovim-instances, and
`autocmd` if the collection resides on a filesystem where the libuv-watchers
may not work correctly. Or, of course, just enable both :D
By default, only `autocmd` is enabled.

While `load` will immediately load the snippets, `lazy_load` will defer loading until
the snippets are actually needed (whenever a new buffer is created, or the
Expand Down Expand Up @@ -2723,6 +2739,9 @@ If `scope` is not set, the snippet will be added to the global filetype (`all`).
- `{override,default}_priority`: These keys are passed straight to the
`add_snippets`-calls (documented in [API](#api)) and can be used to change
the priority of the loaded snippets.
- `lazy`: `boolean`, if it is set, the file does not have to exist when
`load_standalone` is called, and it will be loaded on creation.
`false` by default.

**Example**:
`a.code-snippets`:
Expand Down
3 changes: 3 additions & 0 deletions lua/luasnip/_types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
---@class LuaSnip.MatchRegion 0-based region
---@field row integer 0-based row
---@field col_range { [1]: integer, [2]: integer } 0-based column range, from-in, to-exclusive

---@alias LuaSnip.Addable table
---Anything that can be passed to ls.add_snippets().
77 changes: 0 additions & 77 deletions lua/luasnip/loaders/_caches.lua

This file was deleted.

27 changes: 27 additions & 0 deletions lua/luasnip/loaders/data.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--- This module stores all files loaded by any of the loaders, ordered by their
--- filetype, and other data.
--- This is to facilitate luasnip.loaders.edit_snippets, and to handle
--- persistency of data, which is not given if it is stored in the module-file,
--- since the module-name we use (luasnip.loaders.*) is not necessarily the one
--- used by the user (luasnip/loader/*, for example), and the returned modules
--- are different tables.

local autotable = require("luasnip.util.auto_table").autotable

local M = {
lua_collections = {},
lua_ft_paths = autotable(2),

snipmate_collections = {},
snipmate_ft_paths = autotable(2),
-- set by loader.
snipmate_cache = nil,

vscode_package_collections = {},
vscode_standalone_watchers = {},
vscode_ft_paths = autotable(2),
-- set by loader.
vscode_cache = nil,
}

return M
Loading

0 comments on commit 3a47a1f

Please sign in to comment.