blink.cmp icon indicating copy to clipboard operation
blink.cmp copied to clipboard

How I can trigger 1 char length snippets?

Open NikolaM-Dev opened this issue 8 months ago • 7 comments

Feature Description

Description

I want to trigger this kind of snippets, 1 char of length. For example, I want to trigger := <cursor> when I type ;. I don't know why if I type ; I don't get snippets autocomplete by default. I've been trying modifying completion.trigger options, but I don't have any results :c

{
  "short var declaration": {
    "prefix": ";",
    "body": ":= $0"
  }
}

Config

---@module 'lazy'
---@type LazySpec
return {
	'saghen/blink.cmp',
	desc = 'Performant, batteries-included completion plugin for Neovim',
	docs = 'https://cmp.saghen.dev',
	enabled = true,
	-- optional: provides snippets for the snippet source
	-- dependencies = { 'rafamadriz/friendly-snippets' },

	-- use a release tag to download pre-built binaries
	version = '1.*',
	-- AND/OR build from source, requires nightly: https://rust-lang.github.io/rustup/concepts/channels.html#working-with-nightly-rust
	build = 'cargo build --release',
	-- If you use nix, you can build from source using latest nightly rust with:
	-- build = 'nix run .#build-plugin',

	---@module 'blink.cmp'
	---@type blink.cmp.Config
	opts = {
		-- 'default' (recommended) for mappings similar to built-in completions (C-y to accept)
		-- 'super-tab' for mappings similar to vscode (tab to accept)
		-- 'enter' for enter to accept
		-- 'none' for no mappings
		--
		-- All presets have the following mappings:
		-- C-space: Open menu or open docs if already open
		-- C-n/C-p or Up/Down: Select next/previous item
		-- C-e: Hide menu
		-- C-k: Toggle signature help (if signature.enabled = true)
		--
		-- See :h blink-cmp-config-keymap for defining your own keymap
		keymap = {
			preset = 'enter',

			['<C-j>'] = { 'select_next', 'fallback_to_mappings' },
			['<C-k>'] = { 'select_prev', 'fallback_to_mappings' },
			['<C-d>'] = { 'scroll_documentation_down', 'fallback' },
			['<C-u>'] = { 'scroll_documentation_up', 'fallback' },
			-- ['<Tab>'] = {
			-- function ()
			-- 	local cmp = require('blink.cmp')
			-- 	if cmp.snippet_active() then
			-- 		return cmp.accept()
			-- 	else
			-- 		return cmp.select_accept_and_enter()
			-- 	end
			-- end, 'snippet_forward', 'fallback'}
		},
		cmdline = {
			keymap = {
				preset = 'cmdline',
				['<C-j>'] = { 'select_next' },
				['<C-k>'] = { 'select_prev' },
			},
		},
		signature = {
			enabled = true,
		},
		-- keymap = { preset = 'default' },

		appearance = {
			-- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font'
			-- Adjusts spacing to ensure icons are aligned
			nerd_font_variant = 'mono',
		},

		-- (Default) Only show the documentation popup when manually triggered
		completion = {
			documentation = { auto_show = true },
			ghost_text = { enabled = true },
		},

		-- Default list of enabled providers defined so that you can extend it
		-- elsewhere in your config, without redefining it, due to `opts_extend`
		sources = {
			-- default = { 'lsp', 'path', 'snippets', 'buffer' },
			default = { 'snippets', 'lsp', 'path', 'buffer' },
		},

		-- (Default) Rust fuzzy matcher for typo resistance and significantly better performance
		-- You may use a lua implementation instead by using `implementation = "lua"` or fallback to the lua implementation,
		-- when the Rust fuzzy matcher is not available, by using `implementation = "prefer_rust"`
		--
		-- See the fuzzy documentation for more information
		fuzzy = { implementation = 'prefer_rust_with_warning' },
	},
	opts_extend = { 'sources.default' },
}

NikolaM-Dev avatar Apr 27 '25 15:04 NikolaM-Dev

try providers.snippets.min_keyword_length = 1

sharpchen avatar Apr 29 '25 09:04 sharpchen

@sharpchen It didn't work for me.

...share/nvim/lazy/blink.cmp/lua/blink/cmp/config/utils.lua:37: config.providers: unexpected field found in configuration

NikolaM-Dev avatar Apr 29 '25 21:04 NikolaM-Dev

Oops it should be sources.providers.snippets.min_keyword_length = 1

sharpchen avatar Apr 30 '25 09:04 sharpchen

The issue is we only show the menu on alphanumeric characters and dashes/underscores. The source can send "trigger characters" which are extra characters that make the menu popup. The solution seems to be scanning the available snippets and including trigger characters for first characters that aren't alphanumeric (; in this case)

saghen avatar Apr 30 '25 12:04 saghen

@Saghen I use single-character triggers for snippets, including ,, =, \, etc.. And alphanumeric characters. This is so important to me because it helps avoid uncomfortable key combinations when typing common syntax in the languages I use. That's the main reason I prioritize snippet sources

sources = {
			-- default = { 'lsp', 'path', 'snippets', 'buffer' },
			default = { 'snippets', 'lsp', 'path', 'buffer' },
		},

NikolaM-Dev avatar Apr 30 '25 13:04 NikolaM-Dev

That doesn't control priority, you might want to change snippets.score_offset to prioritize them (defaults to -3)

saghen avatar Apr 30 '25 13:04 saghen

The solution seems to be scanning the available snippets and including trigger characters for first characters that aren't alphanumeric (; in this case)

Alternatively, you can define them manually, as I explained in this discussion.

For example, to trigger snippets that start with either ; or #:

providers = {
    snippets = {
      override = {
        get_trigger_characters = function(_) return {';', '#'} end,
      },
    },
  },

I find this configurable approach simpler, as it gives the user complete control rather than relying on scanning and guessing.

soifou avatar Jul 01 '25 18:07 soifou