Skip to content

Commit 0a4b841

Browse files
authored
Refactor treesitter filetype detection (#281)
* feat: refactor treesitter filetype detection * feat: refactor treesitter filetype detection * feat: refactor treesitter filetype detection * feat: refactor treesitter filetype detection * feat: refactor treesitter filetype detection * feat: refactor treesitter filetype detection * chore: update docs * chore: check filetype separator to '.' * chore: revert filetype separator to '/' * chore: revert filetype separator to '/'
1 parent b7445b3 commit 0a4b841

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

autoload/vsnip/source.vim

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,26 @@ endfunction
2323
"
2424
function! vsnip#source#filetypes( bufnr ) abort
2525
if has( "nvim" )
26-
let l:filetype = v:lua.require'vsnip.treesitter'.get_ft_at_cursor( a:bufnr )
26+
let l:filetypes = v:lua.require'vsnip.treesitter'.get_ft_at_cursor( a:bufnr )
27+
28+
" buffer has no filetype defined
29+
if l:filetypes.filetype == ""
30+
return [ "global" ]
31+
32+
" buffer has filetype
33+
else
34+
return
35+
\ get( g:vsnip_filetypes, l:filetypes.injected_filetype,
36+
\ get( g:vsnip_filetypes, l:filetypes.filetype,
37+
\ [ l:filetypes.filetype ]
38+
\ ) )
39+
\ + [ "global" ]
40+
endif
2741
else
2842
let l:filetype = getbufvar( a:bufnr, "&filetype", "" )
29-
endif
3043

31-
return split( l:filetype, '\.' ) + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ]
44+
return split( l:filetype, '\.' ) + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ]
45+
endif
3246
endfunction
3347

3448
"

doc/vsnip.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ VARIABLE *vsnip-variable*
7171
let g:vsnip_filetypes = {}
7272
let g:vsnip_filetypes.javascriptreact = ['javascript']
7373
<
74+
75+
If you are using `treesitter` you can define snippets for injected
76+
languages like this:
77+
78+
>
79+
let g:vsnip_filetypes['vim/lua'] = ['lua', 'vim/lua']
80+
let g:vsnip_filetypes['vue'] = ['html']
81+
let g:vsnip_filetypes['vue/javascript'] = ['javascript', 'vue/javascript']
82+
<
83+
7484
let g:vsnip_deactivate_on = g:vsnip#DeactivateOn.OutsideOfSnippet~
7585
Specify when to deactivate the current snippet.
7686

lua/vsnip/treesitter.lua

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,56 @@ if not ok_utils then
1010
ts_utils = nil
1111
end
1212

13-
function M.is_available ()
13+
local function get_parser_filetype ( lang )
14+
if lang and ts_parsers.list[ lang ] then
15+
return ts_parsers.list[ lang ].filetype or lang
16+
else
17+
return ""
18+
end
19+
end
20+
21+
local function is_available ()
1422
return ok_parsers and ok_utils
1523
end
1624

1725
function M.get_ft_at_cursor ( bufnr )
18-
if M.is_available() then
26+
local filetypes = {
27+
filetype = "",
28+
injected_filetype = "",
29+
}
30+
31+
if is_available() then
1932
local cur_node = ts_utils.get_node_at_cursor( vim.fn.bufwinid( bufnr ) )
2033

2134
if cur_node then
2235
local parser = ts_parsers.get_parser( bufnr )
23-
local lang = parser:language_for_range( { cur_node:range() } ):lang()
36+
local language_tree_at_cursor = parser:language_for_range( { cur_node:range() } )
37+
local language_at_cursor = language_tree_at_cursor:lang()
38+
39+
local filetype = get_parser_filetype( language_at_cursor )
2440

25-
if ts_parsers.list[ lang ] ~= nil then
26-
return ts_parsers.list[ lang ].filetype or lang
41+
if filetype ~= "" then
42+
filetypes.filetype = filetype
43+
44+
local parent_language_tree = language_tree_at_cursor:parent()
45+
46+
if parent_language_tree then
47+
local parent_language = parent_language_tree:lang()
48+
local parent_filetype = get_parser_filetype( parent_language )
49+
50+
if parent_filetype ~= "" then
51+
filetypes.injected_filetype = parent_filetype .. "/" .. filetype
52+
end
53+
end
54+
55+
return filetypes
2756
end
2857
end
2958
end
3059

31-
return vim.bo[ bufnr ].filetype or ""
60+
filetypes.filetype = vim.bo[ bufnr ].filetype or ""
61+
62+
return filetypes
3263
end
3364

3465
return M

0 commit comments

Comments
 (0)