L3MON4D3 / LuaSnip

Snippet Engine for Neovim written in Lua.
Apache License 2.0
3.37k stars 240 forks source link

Ubuntu: Snippets not loaded, only after saving the file #1228

Closed banana59 closed 1 month ago

banana59 commented 1 month ago

Hello,

when opening a file (e.g.: /tmp/a.cpp) the snippets are not loaded (for e.g. cpp). I can only access LSP completions, but no snippets. I have to open the corresponding snippet file (e.g.: cpp.lua), write it (:w - which saves and :so% with no errors) and then I can access the snippets in the file (e.g.: /tmp/a.cpp).

This is my LuaSnip plugin configuration:

snippets.lua

return {
    {
        "L3MON4D3/LuaSnip",
        build = "make install_jsregexp",
        lazy = false,
        dependencies = {
            "rafamadriz/friendly-snippets",
            "saadparwaiz1/cmp_luasnip",
        },

        -- :lua require("luasnip.loaders").edit_snippet_files() to inspect friendly snippets
        config = function()
            local luasnip = require("luasnip")
            local types = require("luasnip.util.types")

            -- Define highlight groups for virt_text
            vim.api.nvim_set_hl(0, 'PortalOrange', { fg = '#FFA500', bg = 'NONE' })
            vim.api.nvim_set_hl(0, 'PortalBlue', { fg = '#3388FF', bg = 'NONE' })

            luasnip.config.set_config({
                enable_autosnippets = true,  -- Enable autotriggered snippets
                store_selection_keys = "<C-k>",  -- to trigger visual selection
                updateevents = "TextChanged,TextChangedI",
                ext_opts = {
                    [types.choiceNode] = {
                        active = {
                            virt_text = {{"●", "PortalOrange"}},
                            hl_mode = "combine"
                        }
                    },
                    [types.insertNode] = {
                        active = {
                            virt_text = {{"●", "PortalBlue"}},
                            hl_mode = "combine"
                        }
                    }
                },
            })

            vim.keymap.set({"i", "s"}, "<C-j>", function() luasnip.expand_or_jump() end, {silent = true})
            vim.keymap.set({"i", "s"}, "<C-k>", function() luasnip.jump(-1) end, {silent = true})
            vim.keymap.set({"i", "s"}, "<C-l>", function() luasnip.change_choice( 1) end, {silent = true})
            vim.keymap.set({"i", "s"}, "<C-h>", function() luasnip.change_choice(-1) end, {silent = true})

            require("luasnip.loaders.from_vscode").lazy_load({include = {"lua"}})  -- only include these
            require("luasnip.loaders.from_lua").load({paths = "./Snippets/"})
        end,
    },
}

One snippet file like e.g. cpp.lua looks like this

local ls = require("luasnip")
local s = ls.snippet
local i = ls.insert_node
local t = ls.text_node
local c = ls.choice_node
local fmt = require("luasnip.extras.fmt").fmt
local fmta = require("luasnip.extras.fmt").fmta
local events = require("luasnip.util.events")
local relative_path = vim.fn.expand('%:p:h') .. '/helper-functions.lua'
package.path = package.path .. ";" .. relative_path
local helper = require("helper-functions")
local check_import = helper.check_import

return {
    s({trig = "cout"},
        fmt([[
                std::cout << {} << '\n';
                {}
            ]],
            {
                i(1),
                i(0),
            }
        ),
        {
            callbacks = {
                [-1] = {  -- -1 refers to the snippet as a whole
                    [events.pre_expand] = function(_, args)
                        check_import(args, {"#include <iostream>"})
                    end
                 }
            }
        }
    ),
    s({trig = "main"},
        fmta([[
                int main(<>)
                {
                    <>
                }
            ]],
            {
                c(1, {
                    t(""),
                    t("int argc, char **argv"),
                }),
                i(0),
            },
            { delimeters = "<>"}
        )
    )
}

My directory structure looks like

.
├── init.lua
├── lazy-lock.json
├── lua
│   ├── ...
│   ├── plugins
│   │   ├── ...
│   │   ├── snippets.lua
│   │   ├── ...
│   ├── plugins.lua
│   ├── ...
└── Snippets
    ├── all.lua
    ├── c.lua
    ├── cpp.lua
    ├── helper-functions.lua
    ├── ...
    ├── python
    │   └── ...
    └── tex
        └── ...

5 directories, 40 files

Any clue or any notice which could lead to this behaviour?

L3MON4D3 commented 1 month ago

Hey, could you check your logs (ls.log.set_loglevel("info") before call to load, ls.log.open())? There should be some info on luasnip searching these paths, that should help debugging the issue :)

banana59 commented 1 month ago

There are indeed some entries.

I have now inserted the set_loglevel here in snippets.lua:

local luasnip = require("luasnip")
local types = require("luasnip.util.types")

luasnip.log.set_loglevel("info")

--Define highlight groups for virt_text
vim.api.nvim_set_hl(0, 'PortalOrange', { fg = '#FFA500', bg = 'NONE' })
vim.api.nvim_set_hl(0, 'PortalBlue', { fg = '#3388FF', bg = 'NONE' })

and .log.open() here:

    luasnip.log.open()
    require("luasnip.loaders.from_vscode").lazy_load({include = {"lua"}})  -- only include these
    require("luasnip.loaders.from_lua").load({paths = "./Snippets/"})
end,

The ~/.local/state/nvim/luasnip.log

INFO  | lua-loader: Loading lazy-load-snippets for filetype ``
INFO  | snipmate-loader: Loading lazy-load-snippets for filetype ``
INFO  | vscode-loader: Loading lazy-load-snippets for filetype ``
INFO  | lua-loader: Loading lazy-load-snippets for filetype `all`
INFO  | snipmate-loader: Loading lazy-load-snippets for filetype `all`
INFO  | vscode-loader: Loading lazy-load-snippets for filetype `all`
INFO  | vscode-loader: Found manifests `{ "/home/lennart/.local/share/nvim/lazy/friendly-snippets/package.json" }` for paths `nil`.
INFO  | vscode-loader: Determined roots `{}` for lazy_paths `{}`.
INFO  | path-watcher: Monitoring file /home/lennart/.local/share/nvim/lazy/friendly-snippets/package.json with autocmd-monitor.
INFO  | path-watcher: adding path /home/lennart/.local/share/nvim/lazy/friendly-snippets/package.json
INFO  | vscode-loader: Registering lazy-load-snippets for ft `lua` from file `/home/lennart/.local/share/nvim/lazy/friendly-snippets/snippets/lua/lua.json`
INFO  | vscode-loader: Initialized snippet-collection with manifest /home/lennart/.local/share/nvim/lazy/friendly-snippets/package.json
INFO  | vscode-loader: Loading lazy-load-snippets for filetype ``
INFO  | vscode-loader: Loading lazy-load-snippets for filetype `all`
INFO  | lua-loader: Found roots `{ "/home/lennart/Documents/Neovim/default/Snippets" }` for paths `{ "./Snippets/" }`.
INFO  | lua-loader: Determined roots `{}` for lazy_paths `{}`.
INFO  | tree-watcher: Monitoring root-directory /home/lennart/Documents/Neovim/default/Snippets with autocmd-monitor.
INFO  | lua-loader: Adding snippets for filetype `all` from file `/home/lennart/Documents/Neovim/default/Snippets/all.lua`
INFO  | loaders: Adding 3 snippets and 0 autosnippets from /home/lennart/Documents/Neovim/default/Snippets/all.lua to ft `all`
INFO  | lua-loader: Adding snippets for filetype `c` from file `/home/lennart/Documents/Neovim/default/Snippets/c.lua`
ERROR | lua-loader: Failed to execute
      | : /home/lennart/Documents/Neovim/default/Snippets/c.lua
ERROR | lua-loader: Could not create collection at /home/lennart/Documents/Neovim/default/Snippets: ...share/nvim/lazy/LuaSnip/lua/luasnip/loaders/from_lua.lua:246: Could not create watcher: ...share/nvim/lazy/LuaSnip/lua/luasnip/loaders/from_lua.lua:169: Failed to execute /home/lennart/Documents/Neovim/default/Snippets/c.lua
      | : /home/lennart/Documents/Neovim/default/Snippets/c.lua:10: module 'helper-functions' not found:
      |     no field package.preload['helper-functions']
      | cache_loader: module helper-functions not found
      | cache_loader_lib: module helper-functions not found
      |     no file './helper-functions.lua'
      |     no file '/build/nvim/parts/nvim/build/.deps/usr/share/luajit-2.1/helper-functions.lua'
      |     no file '/usr/local/share/lua/5.1/helper-functions.lua'
      |     no file '/usr/local/share/lua/5.1/helper-functions/init.lua'
      |     no file '/build/nvim/parts/nvim/build/.deps/usr/share/lua/5.1/helper-functions.lua'
      |     no file '/build/nvim/parts/nvim/build/.deps/usr/share/lua/5.1/helper-functions/init.lua'
      |     no file '/home/lennart/.local/state/nvim/helper-functions.lua'
      |     no file './helper-functions.so'
      |     no file '/usr/local/lib/lua/5.1/helper-functions.so'
      |     no file '/build/nvim/parts/nvim/build/.deps/usr/lib/lua/5.1/helper-functions.so'
      |     no file '/usr/local/lib/lua/5.1/loadall.so'

There seems to be a error with the helper-functions.lua which can't seem to be properly found. The other snippets don't seem to be loaded as well. Presumably because the would be loaded after c.lua. Why is there no error thrown then when writing and sourcing the snippet c.lua? Isn't

local relative_path = vim.fn.expand('%:p:h') .. '/helper-functions.lua'
package.path = package.path .. ";" .. relative_path
local helper = require("helper-functions")
local check_import = helper.check_import

this sufficient? The helper-functions.lua is in the same directory as the snippet files.

L3MON4D3 commented 1 month ago

Oh, this works when sourcing the file while editing it (because '%' is the file in the current buffer), but not when luasnip does it. You can move helper-functions.lua to Neovim/lua/helper-functions.lua, then require should work :) (also, try ls.tracked_dopackage instead of require so that the snippets are reloaded on editing the helper-file ;D (but this is not at all necessary! require should work))

banana59 commented 1 month ago

That's it. Thank you L3MON4D3 once again :). The ls_tracked_dopackage did it after require("luasnip") pretty well. Futhermore it fixed another error I had with LuaSnip.

L3MON4D3 commented 1 month ago

Nice, happy to help :)