Skip to content

Commit

Permalink
feat: merge snippets to single source
Browse files Browse the repository at this point in the history
  • Loading branch information
Saghen committed Jan 7, 2025
1 parent f29fb9d commit 85d2a6a
Show file tree
Hide file tree
Showing 16 changed files with 120 additions and 90 deletions.
3 changes: 3 additions & 0 deletions docs/configuration/general.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ For more common configurations, see the [recipes](../recipes.md).
cmdline = {},
},

-- Use a preset for snippets, check the snippets documentation for more information
snippets = { preset = 'default' | 'luasnip' | 'mini_snippets' },

-- Experimental signature help support
signature = { enabled = true }
}
Expand Down
17 changes: 13 additions & 4 deletions docs/configuration/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ sources.providers = {
score_offset = 0, -- Boost/penalize the score of the items
override = nil, -- Override the source's functions
},

path = {
name = 'Path',
module = 'blink.cmp.sources.path',
Expand All @@ -447,9 +448,12 @@ sources.providers = {
show_hidden_files_by_default = false,
}
},

snippets = {
name = 'Snippets',
module = 'blink.cmp.sources.snippets',

-- For `snippets.preset == 'default'`
opts = {
friendly_snippets = true,
search_paths = { vim.fn.stdpath('config') .. '/snippets' },
Expand All @@ -462,17 +466,22 @@ sources.providers = {
-- Set to '+' to use the system clipboard, or '"' to use the unnamed register
clipboard_register = nil,
}
},
luasnip = {
name = 'Luasnip',
module = 'blink.cmp.sources.luasnip',

-- For `snippets.preset == 'luasnip'`
opts = {
-- Whether to use show_condition for filtering snippets
use_show_condition = true,
-- Whether to show autosnippets in the completion list
show_autosnippets = true,
}

-- For `snippets.preset == 'mini_snippets'`
opts = {
-- Whether to use a cache for completion items
use_items_cache = true,
}
},

buffer = {
name = 'Buffer',
module = 'blink.cmp.sources.buffer',
Expand Down
9 changes: 6 additions & 3 deletions docs/configuration/snippets.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ By default, the `snippets` source will check `~/.config/nvim/snippets` for your
dependencies = { 'L3MON4D3/LuaSnip', version = 'v2.*' },
opts = {
snippets = { preset = 'luasnip' },
-- ensure you have the `snippets` source (enabled by default)
sources = {
default = { 'lsp', 'path', 'luasnip', 'buffer' },
default = { 'lsp', 'path', 'snippets', 'buffer' },
},
}
}
Expand All @@ -58,12 +59,14 @@ By default, the `snippets` source will check `~/.config/nvim/snippets` for your
'saghen/blink.cmp',
dependencies = 'echasnovski/mini.snippets',
opts = {
snippets = { preset = 'mini.snippets' },
snippets = { preset = 'mini_snippets' },
-- ensure you have the `snippets` source (enabled by default)
sources = {
default = { 'lsp', 'path', 'mini_snippets', 'buffer' },
default = { 'lsp', 'path', 'snippets', 'buffer' },
},
}
}
```

## Disable all snippets

Expand Down
13 changes: 10 additions & 3 deletions lua/blink/cmp/config/snippets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ local snippets = {
default = function(snippet) vim.snippet.expand(snippet) end,
luasnip = function(snippet) require('luasnip').lsp_expand(snippet) end,
mini_snippets = function(snippet)
local insert = require('mini.snippets').config.expand.insert or require('mini.snippets').default_insert
if not _G.MiniSnippets then error('mini.snippets has not been setup') end
local insert = MiniSnippets.config.expand.insert or MiniSnippets.default_insert
insert(snippet)
end,
}),
Expand All @@ -32,12 +33,18 @@ local snippets = {
if filter and filter.direction then return require('luasnip').jumpable(filter.direction) end
return require('luasnip').in_snippet()
end,
mini_snippets = function() return require('mini.snippets').session.get(false) ~= nil end,
mini_snippets = function()
if not _G.MiniSnippets then error('mini.snippets has not been setup') end
return MiniSnippets.session.get(false) ~= nil
end,
}),
jump = by_preset({
default = function(direction) vim.snippet.jump(direction) end,
luasnip = function(direction) require('luasnip').jump(direction) end,
mini_snippets = function(direction) require('mini.snippets').session.jump(direction == -1 and 'prev' or 'next') end,
mini_snippets = function(direction)
if not _G.MiniSnippets then error('mini.snippets has not been setup') end
MiniSnippets.session.jump(direction == -1 and 'prev' or 'next')
end,
}),
},
}
Expand Down
10 changes: 0 additions & 10 deletions lua/blink/cmp/config/sources.lua
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,6 @@ local sources = {
module = 'blink.cmp.sources.snippets',
score_offset = -3,
},
luasnip = {
name = 'Luasnip',
module = 'blink.cmp.sources.luasnip',
score_offset = -3,
},
mini_snippets = {
name = 'MiniSnippets',
module = 'blink.cmp.sources.mini_snippets',
score_offset = -3,
},
buffer = {
name = 'Buffer',
module = 'blink.cmp.sources.buffer',
Expand Down
3 changes: 2 additions & 1 deletion lua/blink/cmp/sources/buffer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ end
local buffer = {}

function buffer.new(opts)
opts = opts or {} ---@type blink.cmp.BufferOpts
--- @cast opts blink.cmp.BufferOpts

local self = setmetatable({}, { __index = buffer })
self.get_bufnrs = opts.get_bufnrs
or function()
Expand Down
7 changes: 7 additions & 0 deletions lua/blink/cmp/sources/lib/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ function sources.get_enabled_providers(mode)
end

function sources.get_provider_by_id(provider_id)
-- TODO: remove in v1.0
if not sources.providers[provider_id] and provider_id == 'luasnip' then
error(
"Luasnip has been moved to the `snippets` source, alongside a new preset system (`snippets.preset = 'luasnip'`). See the documentation for more information."
)
end

assert(
sources.providers[provider_id] ~= nil or config.sources.providers[provider_id] ~= nil,
'Requested provider "'
Expand Down
2 changes: 1 addition & 1 deletion lua/blink/cmp/sources/lib/provider/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function source.new(id, config)
self.id = id
self.name = config.name
self.module = require('blink.cmp.sources.lib.provider.override').new(
require(config.module).new(config.opts, config),
require(config.module).new(config.opts or {}, config),
config.override
)
self.config = require('blink.cmp.sources.lib.provider.config').new(config)
Expand Down
2 changes: 1 addition & 1 deletion lua/blink/cmp/sources/path/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function path.new(opts)
local self = setmetatable({}, { __index = path })

--- @type blink.cmp.PathOpts
opts = vim.tbl_deep_extend('keep', opts or {}, {
opts = vim.tbl_deep_extend('keep', opts, {
trailing_slash = true,
label_trailing_slash = true,
get_cwd = function(context) return vim.fn.expand(('#%d:p:h'):format(context.bufnr)) end,
Expand Down
File renamed without changes.
65 changes: 65 additions & 0 deletions lua/blink/cmp/sources/snippets/default/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
--- @class blink.cmp.SnippetsOpts
--- @field friendly_snippets? boolean
--- @field search_paths? string[]
--- @field global_snippets? string[]
--- @field extended_filetypes? table<string, string[]>
--- @field ignored_filetypes? string[]
--- @field get_filetype? fun(context: blink.cmp.Context): string
--- @field clipboard_register? string

local snippets = {}

function snippets.new(opts)
--- @cast opts blink.cmp.SnippetsOpts

local self = setmetatable({}, { __index = snippets })
--- @type table<string, blink.cmp.CompletionItem[]>
self.cache = {}
self.registry = require('blink.cmp.sources.snippets.default.registry').new(opts)
self.get_filetype = opts.get_filetype or function() return vim.bo.filetype end
return self
end

function snippets:get_completions(context, callback)
local filetype = self.get_filetype(context)
if vim.tbl_contains(self.registry.config.ignored_filetypes, filetype) then return callback() end

if not self.cache[filetype] then
local global_snippets = self.registry:get_global_snippets()
local extended_snippets = self.registry:get_extended_snippets(filetype)
local ft_snippets = self.registry:get_snippets_for_ft(filetype)
local snips = vim.list_extend({}, global_snippets)
vim.list_extend(snips, extended_snippets)
vim.list_extend(snips, ft_snippets)

self.cache[filetype] = snips
end

local items = vim.tbl_map(
function(item) return self.registry:snippet_to_completion_item(item) end,
self.cache[filetype]
)
callback({
is_incomplete_forward = false,
is_incomplete_backward = false,
items = items,
})
end

function snippets:resolve(item, callback)
local parsed_snippet = require('blink.cmp.sources.snippets.utils').safe_parse(item.insertText)
local snippet = parsed_snippet and tostring(parsed_snippet) or item.insertText

local resolved_item = vim.deepcopy(item)
resolved_item.detail = snippet
resolved_item.documentation = {
kind = 'markdown',
value = item.description,
}
callback(resolved_item)
end

--- For external integrations to force reloading the snippets
function snippets:reload() self.cache = {} end

return snippets
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
--- @field description? string

local registry = {
builtin_vars = require('blink.cmp.sources.snippets.builtin'),
builtin_vars = require('blink.cmp.sources.snippets.default.builtin'),
}

local utils = require('blink.cmp.sources.snippets.utils')
Expand All @@ -33,7 +33,7 @@ function registry.new(config)
if string.match(path, 'friendly.snippets') then table.insert(self.config.search_paths, path) end
end
end
self.registry = require('blink.cmp.sources.snippets.scan').register_snippets(self.config.search_paths)
self.registry = require('blink.cmp.sources.snippets.default.scan').register_snippets(self.config.search_paths)

return self
end
Expand Down
File renamed without changes.
68 changes: 6 additions & 62 deletions lua/blink/cmp/sources/snippets/init.lua
Original file line number Diff line number Diff line change
@@ -1,65 +1,9 @@
--- @class blink.cmp.SnippetsOpts
--- @field friendly_snippets? boolean
--- @field search_paths? string[]
--- @field global_snippets? string[]
--- @field extended_filetypes? table<string, string[]>
--- @field ignored_filetypes? string[]
--- @field get_filetype? fun(context: blink.cmp.Context): string
--- @field clipboard_register? string
local source = {}

local snippets = {}

function snippets.new(opts)
--- @type blink.cmp.SnippetsOpts
opts = opts or {}
local self = setmetatable({}, { __index = snippets })
--- @type table<string, blink.cmp.CompletionItem[]>
self.cache = {}
self.registry = require('blink.cmp.sources.snippets.registry').new(opts)
self.get_filetype = opts.get_filetype or function() return vim.bo.filetype end
return self
end

function snippets:get_completions(context, callback)
local filetype = self.get_filetype(context)
if vim.tbl_contains(self.registry.config.ignored_filetypes, filetype) then return callback() end

if not self.cache[filetype] then
local global_snippets = self.registry:get_global_snippets()
local extended_snippets = self.registry:get_extended_snippets(filetype)
local ft_snippets = self.registry:get_snippets_for_ft(filetype)
local snips = vim.list_extend({}, global_snippets)
vim.list_extend(snips, extended_snippets)
vim.list_extend(snips, ft_snippets)

self.cache[filetype] = snips
end

local items = vim.tbl_map(
function(item) return self.registry:snippet_to_completion_item(item) end,
self.cache[filetype]
)
callback({
is_incomplete_forward = false,
is_incomplete_backward = false,
items = items,
})
function source.new(opts)
local preset = opts.preset or require('blink.cmp.config').snippets.preset
local module = 'blink.cmp.sources.snippets.' .. preset
return require(module).new(opts)
end

function snippets:resolve(item, callback)
local parsed_snippet = require('blink.cmp.sources.snippets.utils').safe_parse(item.insertText)
local snippet = parsed_snippet and tostring(parsed_snippet) or item.insertText

local resolved_item = vim.deepcopy(item)
resolved_item.detail = snippet
resolved_item.documentation = {
kind = 'markdown',
value = item.description,
}
callback(resolved_item)
end

--- For external integrations to force reloading the snippets
function snippets:reload() self.cache = {} end

return snippets
return source
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ local defaults_config = {
}

function source.new(opts)
local config = vim.tbl_deep_extend('keep', opts or {}, defaults_config)
local config = vim.tbl_deep_extend('keep', opts, defaults_config)
require('blink.cmp.config.utils').validate('sources.providers.luasnip', {
use_show_condition = { config.use_show_condition, 'boolean' },
show_autosnippets = { config.show_autosnippets, 'boolean' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
local source = {}

local defaults_config = {
use_items_cache = true, -- allow the user to disable caching completion items
--- Whether to use a cache for completion items
use_items_cache = true,
}

function source.new(opts)
local config = vim.tbl_deep_extend('keep', opts or {}, defaults_config)
local config = vim.tbl_deep_extend('keep', opts, defaults_config)
vim.validate({
use_items_cache = { config.use_items_cache, 'boolean' },
})
Expand Down

0 comments on commit 85d2a6a

Please sign in to comment.