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

Is there a way to use snippets based on the _syntax name_, rather than the _filetype_?

Open NullVoxPopuli opened this issue 10 months ago • 4 comments

this really only matters for filetypes with multiple embedded languages, e.g.:

  • svelte
  • vue
  • angular
  • react jsx / tsx
  • glimmer gjs / gts
  • etc

Namely,

if an outer language is javascript, and an inner language is CSS, I don't want javascript snippets being suggested in the CSS block (such as <style></style> (in jsx/gjs/svelte/etc)

likewise, is there a way to configure the snippets package.json such that it only allows snippets based on the combination of the language and file type? for example: we don't want to suggest embedded-language snippets when the filetype does not support embedded languages (such as plain js and plain ts -- no embedded languages allowed usually (unless via template literal strings))

NullVoxPopuli avatar Apr 25 '25 21:04 NullVoxPopuli

For snippets.preset = 'default', you may pass sources.providers.snippets.opts.get_filetype = function() ... end. You could pass the filetype from treesitter. If you find a good solution for this, I'd love to make it the default.

saghen avatar May 01 '25 17:05 saghen

For snippets.preset = 'default', you may pass sources.providers.snippets.opts.get_filetype = function() ... end. You could pass the filetype from treesitter. If you find a good solution for this, I'd love to make it the default.

I think I found one, this worked for me in Quarto (Python embedded in Markdown).

providers = {
	-- display snippets according to embedded language
	snippets = {
		opts = {
			get_filetype = function(context)
				local curline = vim.fn.line(".")
				local lang =
					vim.treesitter.get_parser():language_for_range({ curline, 0, curline, 0 }):lang()
				return lang
			end,
		},
	},
},

To be more robust, it should fall back to vim.bo.filetype

reference: https://github.com/nvim-treesitter/nvim-treesitter/discussions/6643. It'd be great if this becomes a util function in nvim-treesitter or even vim.treesitter.

I can make a PR if this is of any interest.

sghng avatar Sep 03 '25 19:09 sghng

hm, ya, how do you handle when there isn't a language (such as when you have an ephemeral buffer (grug-far in my case, but possibly telescope, etc)

NullVoxPopuli avatar Sep 04 '25 03:09 NullVoxPopuli

hm, ya, how do you handle when there isn't a language (such as when you have an ephemeral buffer (grug-far in my case, but possibly telescope, etc)

I guess fall back to vim.bo.filetype would be safe -- that's the current default anyway, so it won't get worse.

Reference: https://cmp.saghen.dev/recipes.html#dynamically-picking-providers-by-treesitter-node-filetype

sghng avatar Sep 04 '25 03:09 sghng