From 55260b1a75be1175cb2369f5a67b615b3fd913f3 Mon Sep 17 00:00:00 2001 From: zdm Date: Sun, 30 Mar 2025 12:37:30 +0300 Subject: [PATCH 01/10] feat: refactor treesitter filetype detection --- lua/vsnip/treesitter.lua | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/lua/vsnip/treesitter.lua b/lua/vsnip/treesitter.lua index 6a9c033..eb88c4c 100644 --- a/lua/vsnip/treesitter.lua +++ b/lua/vsnip/treesitter.lua @@ -10,6 +10,14 @@ if not ok_utils then ts_utils = nil end +local function get_parser_filetype ( lang ) + if lang and ts_parsers.list[ lang ] then + return ts_parsers.list[ lang ].filetype or lang + else + return "" + end +end + function M.is_available () return ok_parsers and ok_utils end @@ -22,8 +30,29 @@ function M.get_ft_at_cursor ( bufnr ) local parser = ts_parsers.get_parser( bufnr ) local lang = parser:language_for_range( { cur_node:range() } ):lang() - if ts_parsers.list[ lang ] ~= nil then - return ts_parsers.list[ lang ].filetype or lang + local filetype = get_parser_filetype( lang ) + + if filetype ~= "" then + + -- XXX: not works + local parent_parser = parser:parent() + + if parent_parser then + local parent_lang = parent_parser:lang() + + if parent_lang and parent_lang ~= filetype then + local parent_filetype = get_parser_filetype( parent_lang ) + + if parent_filetype ~= "" then + filetype = filetype .. "." .. parent_filetype .. "/" .. filetype + end + end + end + + -- XXX + vim.print( "--- " .. filetype ) + + return filetype end end end From d0ce943a2a08fa77618d0b8fecd657cf2e8f9228 Mon Sep 17 00:00:00 2001 From: zdm Date: Sun, 30 Mar 2025 14:02:51 +0300 Subject: [PATCH 02/10] feat: refactor treesitter filetype detection --- lua/vsnip/treesitter.lua | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/lua/vsnip/treesitter.lua b/lua/vsnip/treesitter.lua index eb88c4c..1a004e1 100644 --- a/lua/vsnip/treesitter.lua +++ b/lua/vsnip/treesitter.lua @@ -28,30 +28,23 @@ function M.get_ft_at_cursor ( bufnr ) if cur_node then local parser = ts_parsers.get_parser( bufnr ) - local lang = parser:language_for_range( { cur_node:range() } ):lang() + local language_tree_at_cursor = parser:language_for_range( { cur_node:range() } ) + local language_at_cursor = language_tree_at_cursor:lang() - local filetype = get_parser_filetype( lang ) + local filetype = get_parser_filetype( language_at_cursor ) if filetype ~= "" then + local parent_language_tree = language_tree_at_cursor:parent() - -- XXX: not works - local parent_parser = parser:parent() + if parent_language_tree then + local parent_language = parent_language_tree:lang() + local parent_filetype = get_parser_filetype( parent_language ) - if parent_parser then - local parent_lang = parent_parser:lang() - - if parent_lang and parent_lang ~= filetype then - local parent_filetype = get_parser_filetype( parent_lang ) - - if parent_filetype ~= "" then - filetype = filetype .. "." .. parent_filetype .. "/" .. filetype - end + if parent_filetype ~= "" and parent_filetype ~= filetype then + filetype = filetype .. "." .. parent_filetype .. "/" .. filetype end end - -- XXX - vim.print( "--- " .. filetype ) - return filetype end end From a75d2f2b3479b577087d7b4c585ac9208b10d48c Mon Sep 17 00:00:00 2001 From: zdm Date: Sun, 30 Mar 2025 14:18:01 +0300 Subject: [PATCH 03/10] feat: refactor treesitter filetype detection --- lua/vsnip/treesitter.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/vsnip/treesitter.lua b/lua/vsnip/treesitter.lua index 1a004e1..44e77cc 100644 --- a/lua/vsnip/treesitter.lua +++ b/lua/vsnip/treesitter.lua @@ -40,7 +40,7 @@ function M.get_ft_at_cursor ( bufnr ) local parent_language = parent_language_tree:lang() local parent_filetype = get_parser_filetype( parent_language ) - if parent_filetype ~= "" and parent_filetype ~= filetype then + if parent_filetype ~= "" then filetype = filetype .. "." .. parent_filetype .. "/" .. filetype end end From a743abf755104b105e6f0346c711ab2b226ef569 Mon Sep 17 00:00:00 2001 From: zdm Date: Sun, 30 Mar 2025 17:41:07 +0300 Subject: [PATCH 04/10] feat: refactor treesitter filetype detection --- autoload/vsnip/source.vim | 19 ++++++++++++++++--- lua/vsnip/treesitter.lua | 15 ++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/autoload/vsnip/source.vim b/autoload/vsnip/source.vim index 6ac3460..ef29637 100644 --- a/autoload/vsnip/source.vim +++ b/autoload/vsnip/source.vim @@ -23,12 +23,25 @@ endfunction " function! vsnip#source#filetypes( bufnr ) abort if has( "nvim" ) - let l:filetype = v:lua.require'vsnip.treesitter'.get_ft_at_cursor( a:bufnr ) + let l:filetypes = v:lua.require'vsnip.treesitter'.get_ft_at_cursor( a:bufnr ) + + if l:filetypes.filetype == "" + return [ "global" ] + else + return get( + \ g:vsnip_filetypes, l:filetypes.injected_filetype, + \ get( g:vsnip_filetypes, l:filetypes.filetype, + \ [ l:filetypes.filetype ] + \ ) ) + \ + [ "global" ] + endif else let l:filetype = getbufvar( a:bufnr, "&filetype", "" ) - endif - return split( l:filetype, '\.' ) + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ] + " FIXME: split( l:filetype, '\.' ) - does it has any sense, can buffer filetype contain "." character? + " return split( l:filetype, '\.' ) + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ] + return [ l:filetype ] + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ] + endif endfunction " diff --git a/lua/vsnip/treesitter.lua b/lua/vsnip/treesitter.lua index 44e77cc..b4590aa 100644 --- a/lua/vsnip/treesitter.lua +++ b/lua/vsnip/treesitter.lua @@ -23,6 +23,11 @@ function M.is_available () end function M.get_ft_at_cursor ( bufnr ) + local filetypes = { + filetype = "", + injected_filetype = "", + } + if M.is_available() then local cur_node = ts_utils.get_node_at_cursor( vim.fn.bufwinid( bufnr ) ) @@ -34,6 +39,8 @@ function M.get_ft_at_cursor ( bufnr ) local filetype = get_parser_filetype( language_at_cursor ) if filetype ~= "" then + filetypes.filetype = filetype + local parent_language_tree = language_tree_at_cursor:parent() if parent_language_tree then @@ -41,16 +48,18 @@ function M.get_ft_at_cursor ( bufnr ) local parent_filetype = get_parser_filetype( parent_language ) if parent_filetype ~= "" then - filetype = filetype .. "." .. parent_filetype .. "/" .. filetype + filetypes.injected_filetype = parent_filetype .. "/" .. filetype end end - return filetype + return filetypes end end end - return vim.bo[ bufnr ].filetype or "" + filetypes.filetype = vim.bo[ bufnr ].filetype or "" + + return filetypes end return M From e93611fe28844a09d893f71b99dbf5dbdba4c3fe Mon Sep 17 00:00:00 2001 From: zdm Date: Sun, 30 Mar 2025 17:56:57 +0300 Subject: [PATCH 05/10] feat: refactor treesitter filetype detection --- autoload/vsnip/source.vim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/autoload/vsnip/source.vim b/autoload/vsnip/source.vim index ef29637..2315774 100644 --- a/autoload/vsnip/source.vim +++ b/autoload/vsnip/source.vim @@ -25,11 +25,14 @@ function! vsnip#source#filetypes( bufnr ) abort if has( "nvim" ) let l:filetypes = v:lua.require'vsnip.treesitter'.get_ft_at_cursor( a:bufnr ) + " buffer has no filetype defined if l:filetypes.filetype == "" return [ "global" ] + + " buffer has filetype else - return get( - \ g:vsnip_filetypes, l:filetypes.injected_filetype, + return + \ get( g:vsnip_filetypes, l:filetypes.injected_filetype, \ get( g:vsnip_filetypes, l:filetypes.filetype, \ [ l:filetypes.filetype ] \ ) ) From db416f811a4353f04b65b9fc12780c4d60f09ad5 Mon Sep 17 00:00:00 2001 From: zdm Date: Sun, 30 Mar 2025 18:22:24 +0300 Subject: [PATCH 06/10] feat: refactor treesitter filetype detection --- lua/vsnip/treesitter.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/vsnip/treesitter.lua b/lua/vsnip/treesitter.lua index b4590aa..311be5a 100644 --- a/lua/vsnip/treesitter.lua +++ b/lua/vsnip/treesitter.lua @@ -18,7 +18,7 @@ local function get_parser_filetype ( lang ) end end -function M.is_available () +local function is_available () return ok_parsers and ok_utils end @@ -28,7 +28,7 @@ function M.get_ft_at_cursor ( bufnr ) injected_filetype = "", } - if M.is_available() then + if is_available() then local cur_node = ts_utils.get_node_at_cursor( vim.fn.bufwinid( bufnr ) ) if cur_node then From 2e3e70fc06c43c9b4de9e18c311ebd5865652ffb Mon Sep 17 00:00:00 2001 From: zdm Date: Sun, 30 Mar 2025 19:41:43 +0300 Subject: [PATCH 07/10] chore: update docs --- doc/vsnip.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/vsnip.txt b/doc/vsnip.txt index 2a65afa..945e5c2 100644 --- a/doc/vsnip.txt +++ b/doc/vsnip.txt @@ -71,6 +71,16 @@ VARIABLE *vsnip-variable* let g:vsnip_filetypes = {} let g:vsnip_filetypes.javascriptreact = ['javascript'] < + + If you are using `treesitter` you can define snippets for injected + languages like this: + +> + let g:vsnip_filetypes['vim/lua'] = ['lua', 'vim/lua'] + let g:vsnip_filetypes['vue'] = ['html'] + let g:vsnip_filetypes['vim/javascript'] = ['javascript', 'vue/javascript'] +< + let g:vsnip_deactivate_on = g:vsnip#DeactivateOn.OutsideOfSnippet~ Specify when to deactivate the current snippet. From 9b1fadc3aa2f1e5962cfb4a7d688745cb3f7c154 Mon Sep 17 00:00:00 2001 From: zdm Date: Mon, 31 Mar 2025 18:35:31 +0300 Subject: [PATCH 08/10] chore: check filetype separator to '.' --- autoload/vsnip/source.vim | 4 +--- doc/vsnip.txt | 4 ++-- lua/vsnip/treesitter.lua | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/autoload/vsnip/source.vim b/autoload/vsnip/source.vim index 2315774..28df252 100644 --- a/autoload/vsnip/source.vim +++ b/autoload/vsnip/source.vim @@ -41,9 +41,7 @@ function! vsnip#source#filetypes( bufnr ) abort else let l:filetype = getbufvar( a:bufnr, "&filetype", "" ) - " FIXME: split( l:filetype, '\.' ) - does it has any sense, can buffer filetype contain "." character? - " return split( l:filetype, '\.' ) + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ] - return [ l:filetype ] + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ] + return split( l:filetype, '\.' ) + get( g:vsnip_filetypes, l:filetype, [] ) + [ "global" ] endif endfunction diff --git a/doc/vsnip.txt b/doc/vsnip.txt index 945e5c2..f7b17b2 100644 --- a/doc/vsnip.txt +++ b/doc/vsnip.txt @@ -76,9 +76,9 @@ VARIABLE *vsnip-variable* languages like this: > - let g:vsnip_filetypes['vim/lua'] = ['lua', 'vim/lua'] + let g:vsnip_filetypes['vim.lua'] = ['lua', 'vim/lua'] let g:vsnip_filetypes['vue'] = ['html'] - let g:vsnip_filetypes['vim/javascript'] = ['javascript', 'vue/javascript'] + let g:vsnip_filetypes['vim.javascript'] = ['javascript', 'vue/javascript'] < let g:vsnip_deactivate_on = g:vsnip#DeactivateOn.OutsideOfSnippet~ diff --git a/lua/vsnip/treesitter.lua b/lua/vsnip/treesitter.lua index 311be5a..607ab86 100644 --- a/lua/vsnip/treesitter.lua +++ b/lua/vsnip/treesitter.lua @@ -48,7 +48,7 @@ function M.get_ft_at_cursor ( bufnr ) local parent_filetype = get_parser_filetype( parent_language ) if parent_filetype ~= "" then - filetypes.injected_filetype = parent_filetype .. "/" .. filetype + filetypes.injected_filetype = parent_filetype .. "." .. filetype end end From 013d56a61cdc1e1fad5d5e85259be8458a0ff834 Mon Sep 17 00:00:00 2001 From: zdm Date: Tue, 8 Apr 2025 16:38:30 +0300 Subject: [PATCH 09/10] chore: revert filetype separator to '/' --- doc/vsnip.txt | 4 ++-- lua/vsnip/treesitter.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vsnip.txt b/doc/vsnip.txt index f7b17b2..945e5c2 100644 --- a/doc/vsnip.txt +++ b/doc/vsnip.txt @@ -76,9 +76,9 @@ VARIABLE *vsnip-variable* languages like this: > - let g:vsnip_filetypes['vim.lua'] = ['lua', 'vim/lua'] + let g:vsnip_filetypes['vim/lua'] = ['lua', 'vim/lua'] let g:vsnip_filetypes['vue'] = ['html'] - let g:vsnip_filetypes['vim.javascript'] = ['javascript', 'vue/javascript'] + let g:vsnip_filetypes['vim/javascript'] = ['javascript', 'vue/javascript'] < let g:vsnip_deactivate_on = g:vsnip#DeactivateOn.OutsideOfSnippet~ diff --git a/lua/vsnip/treesitter.lua b/lua/vsnip/treesitter.lua index 607ab86..311be5a 100644 --- a/lua/vsnip/treesitter.lua +++ b/lua/vsnip/treesitter.lua @@ -48,7 +48,7 @@ function M.get_ft_at_cursor ( bufnr ) local parent_filetype = get_parser_filetype( parent_language ) if parent_filetype ~= "" then - filetypes.injected_filetype = parent_filetype .. "." .. filetype + filetypes.injected_filetype = parent_filetype .. "/" .. filetype end end From 176ff927e48429b3742fa1c85682d3b80c962074 Mon Sep 17 00:00:00 2001 From: zdm Date: Tue, 8 Apr 2025 16:44:20 +0300 Subject: [PATCH 10/10] chore: revert filetype separator to '/' --- doc/vsnip.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vsnip.txt b/doc/vsnip.txt index 945e5c2..c26c09f 100644 --- a/doc/vsnip.txt +++ b/doc/vsnip.txt @@ -78,7 +78,7 @@ VARIABLE *vsnip-variable* > let g:vsnip_filetypes['vim/lua'] = ['lua', 'vim/lua'] let g:vsnip_filetypes['vue'] = ['html'] - let g:vsnip_filetypes['vim/javascript'] = ['javascript', 'vue/javascript'] + let g:vsnip_filetypes['vue/javascript'] = ['javascript', 'vue/javascript'] < let g:vsnip_deactivate_on = g:vsnip#DeactivateOn.OutsideOfSnippet~