Emmet For Styled Components In Neovim
Emmet support for JSX is somewhat limited in Neovim as it is not able to
easily distinguish between when it should provide JSX completions in render
methods or CSS completions in styled components or similar CSS-in-JS
libraries. If you only care about CSS completions and you are okay with a
few config changes, you can make it work pretty easily with an
entry_filter
for your completions.
Before we add our filter, we first need to add some tree-sitter captures to identify styled component blocks. We can do this with the following code.
~/.config/nvim/queries/ecma/highlights.scm
; css`<css>`, keyframes`<css>`
(call_expression
function: (identifier) @_name
(#match? @_name "^(css|keyframes)")
arguments: ((template_string) @styled
(#offset! @styled 0 1 0 -1)))
; styled.div`<css>`
(call_expression
function: (member_expression
object: (identifier) @_name
(#eq? @_name "styled"))
arguments: ((template_string) @styled
(#offset! @styled 0 1 0 -1)))
; styled(Component)`<css>`
(call_expression
function: (call_expression
function: (identifier) @_name
(#eq? @_name "styled"))
arguments: ((template_string) @styled
(#offset! @styled 0 1 0 -1)))
With this in place, we can now update our nvim_lsp
completion source to
add an entry filter to only allow Emmet completions in CSS files or when
inside of a styled
tree-sitter capture group.
cmp.config.sources({
{
name = "nvim_lsp",
entry_filter = function(entry)
local client_name = entry.source.source.client.name
-- Only return Emmet results in styled-component template strings
return client_name ~= "emmet_language_server"
or entry.context.filetype == "css"
or context.in_treesitter_capture("styled")
end,
},
})