Syntax aware text-objects, select, move, swap, and peek support.
Warning: tree-sitter and nvim-treesitter are an experimental feature of nightly versions of Neovim. Please consider the experience with this plug-in as experimental until tree-sitter support in Neovim is stable! We recommend using the nightly builds of Neovim or the latest stable version.
You can install nvim-treesitter-textobjects with your favorite package manager, or using the default pack feature of Neovim!
If you are using vim-plug, put this in your init.vim file:
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
Plug 'nvim-treesitter/nvim-treesitter-textobjects'If you are using Packer, put it in your init.lua file:
use({
"nvim-treesitter/nvim-treesitter-textobjects",
after = "nvim-treesitter",
requires = "nvim-treesitter/nvim-treesitter",
})Define your own text objects mappings
similar to ip (inner paragraph) and ap (a paragraph).
lua <<EOF
require'nvim-treesitter.configs'.setup {
textobjects = {
select = {
enable = true,
-- Automatically jump forward to textobj, similar to targets.vim
lookahead = true,
keymaps = {
-- You can use the capture groups defined in textobjects.scm
["af"] = "@function.outer",
["if"] = "@function.inner",
["ac"] = "@class.outer",
-- You can optionally set descriptions to the mappings (used in the desc parameter of
-- nvim_buf_set_keymap) which plugins like which-key display
["ic"] = { query = "@class.inner", desc = "Select inner part of a class region" },
-- You can also use captures from other query groups like `locals.scm`
["as"] = { query = "@local.scope", query_group = "locals", desc = "Select language scope" },
},
-- You can choose the select mode (default is charwise 'v')
--
-- Can also be a function which gets passed a table with the keys
-- * query_string: eg '@function.inner'
-- * method: eg 'v' or 'o'
-- and should return the mode ('v', 'V', or '<c-v>') or a table
-- mapping query_strings to modes.
selection_modes = {
['@parameter.outer'] = 'v', -- charwise
['@function.outer'] = 'V', -- linewise
['@class.outer'] = '<c-v>', -- blockwise
},
-- If you set this to `true` (default is `false`) then any textobject is
-- extended to include preceding or succeeding whitespace. Succeeding
-- whitespace has priority in order to act similarly to eg the built-in
-- `ap`.
--
-- Can also be a function which gets passed a table with the keys
-- * query_string: eg '@function.inner'
-- * selection_mode: eg 'v'
-- and should return true or false
include_surrounding_whitespace = true,
},
},
}
EOFDefine your own mappings to swap the node under the cursor with the next or previous one, like function parameters or arguments.
lua <<EOF
require'nvim-treesitter.configs'.setup {
textobjects = {
swap = {
enable = true,
swap_next = {
["<leader>a"] = "@parameter.inner",
},
swap_previous = {
["<leader>A"] = "@parameter.inner",
},
},
},
}
EOFDefine your own mappings to jump to the next or previous text object.
This is similar to ]m, [m, ]M, [M Neovim's mappings to jump to the next
or previous function.
lua <<EOF
require'nvim-treesitter.configs'.setup {
textobjects = {
move = {
enable = true,
set_jumps = true, -- whether to set jumps in the jumplist
goto_next_start = {
["]m"] = "@function.outer",
["]]"] = { query = "@class.outer", desc = "Next class start" },
--
-- You can use regex matching (i.e. lua pattern) and/or pass a list in a "query" key to group multiple queries.
["]o"] = "@loop.*",
-- ["]o"] = { query = { "@loop.inner", "@loop.outer" } }
--
-- You can pass a query group to use query from `queries/<lang>/<query_group>.scm file in your runtime path.
-- Below example nvim-treesitter's `locals.scm` and `folds.scm`. They also provide highlights.scm and indent.scm.
["]s"] = { query = "@local.scope", query_group = "locals", desc = "Next scope" },
["]z"] = { query = "@fold", query_group = "folds", desc = "Next fold" },
},
goto_next_end = {
["]M"] = "@function.outer",
["]["] = "@class.outer",
},
goto_previous_start = {
["[m"] = "@function.outer",
["[["] = "@class.outer",
},
goto_previous_end = {
["[M"] = "@function.outer",
["[]"] = "@class.outer",
},
-- Below will go to either the start or the end, whichever is closer.
-- Use if you want more granular movements
-- Make it even more gradual by adding multiple queries and regex.
goto_next = {
["]d"] = "@conditional.outer",
},
goto_previous = {
["[d"] = "@conditional.outer",
}
},
},
}
EOFYou can make the movements repeatable like ; and ,.
local ts_repeat_move = require "nvim-treesitter.textobjects.repeatable_move"
-- Repeat movement with ; and ,
-- ensure ; goes forward and , goes backward regardless of the last direction
vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move_next)
vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_previous)
-- vim way: ; goes to the direction you were moving.
-- vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move)
-- vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_opposite)
-- Optionally, make builtin f, F, t, T also repeatable with ; and ,
vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t_expr, { expr = true })
vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T_expr, { expr = true })You can even make a custom repeat behaviour.
-- This repeats the last query with always previous direction and to the start of the range.
vim.keymap.set({ "n", "x", "o" }, "<home>", function()
ts_repeat_move.repeat_last_move({forward = false, start = true})
end)
-- This repeats the last query with always next direction and to the end of the range.
vim.keymap.set({ "n", "x", "o" }, "<end>", function()
ts_repeat_move.repeat_last_move({forward = true, start = false})
end)Furthermore, you can make any custom movements (e.g. from another plugin) repeatable with the same keys. This doesn't need to be treesitter-related.
-- example: make gitsigns.nvim movement repeatable with ; and , keys.
local gs = require("gitsigns")
-- make sure forward function comes first
local next_hunk_repeat, prev_hunk_repeat = ts_repeat_move.make_repeatable_move_pair(gs.next_hunk, gs.prev_hunk)
-- Or, use `make_repeatable_move` or `set_last_move` functions for more control. See the code for instructions.
vim.keymap.set({ "n", "x", "o" }, "]h", next_hunk_repeat)
vim.keymap.set({ "n", "x", "o" }, "[h", prev_hunk_repeat)Alternative way is to use a repeatable movement managing plugin such as nvim-next.
- peek_definition_code: show textobject surrounding definition as determined using Neovim's built-in LSP in a floating window. Press the shortcut twice to enter the floating window.
lua <<EOF
require'nvim-treesitter.configs'.setup {
textobjects = {
lsp_interop = {
enable = true,
border = 'none',
floating_preview_opts = {},
peek_definition_code = {
["<leader>df"] = "@function.outer",
["<leader>dF"] = "@class.outer",
},
},
},
}
EOFTextobjects are defined in the textobjects.scm files.
You can extend or override those files by following the instructions at
https://github.com/nvim-treesitter/nvim-treesitter#adding-queries.
You can also use a custom capture for your own textobjects,
and use it in any of the textobject modules, for example:
-- after/queries/python/textobjects.scm
; extends
(function_definition) @custom_capturelua <<EOF
require'nvim-treesitter.configs'.setup {
textobjects = {
select = {
enable = true,
keymaps = {
-- Your custom capture.
["aF"] = "@custom_capture",
-- Built-in captures.
["af"] = "@function.outer",
["if"] = "@function.inner",
},
},
},
}
EOFHere are some rules about the query names that should be noted.
- Avoid using special characters in the query name, because in
movemodule the names are read as regex (lua) patterns.
@custom-capture.inner(X)@custom_capture.inner(O)
- In
selectmodule, it will be preferred to select within the@*.outermatches. For example,
@assignment.inner,@assignment.lhs, and even@assignmentwill be selected within the@assignment.outerrange if available. This means it will sometimes look behind.- You can write something like
@function.nameor@call.nameand make sure@function.outerand@call.outercovers the range.
- @assignment.inner
- @assignment.lhs
- @assignment.outer
- @assignment.rhs
- @attribute.inner
- @attribute.outer
- @block.inner
- @block.outer
- @call.inner
- @call.outer
- @class.inner
- @class.outer
- @comment.inner
- @comment.outer
- @conditional.inner
- @conditional.outer
- @frame.inner
- @frame.outer
- @function.inner
- @function.outer
- @loop.inner
- @loop.outer
- @number.inner
- @parameter.inner
- @parameter.outer
- @regex.inner
- @regex.outer
- @return.inner
- @return.outer
- @scopename.inner
- @statement.outer
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | |
| apex | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| astro | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| bash | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ |
| bibtex | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| c | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| c_sharp | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| cmake | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| cpp | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| css | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| cuda | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| dart | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| dockerfile | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| elixir | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ |
| elm | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| enforce | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | π© | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ |
| fennel | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| fish | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | β¬ | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| foam | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| glsl | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| go | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| hack | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| haskell | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| hcl | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| heex | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| hlsl | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| html | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| inko | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ |
| java | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ |
| javascript | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | π© |
| julia | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ |
| kotlin | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| latex | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| lua | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| matlab | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| nasm | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| nim | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| nix | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| ocaml | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| odin | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ |
| perl | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ |
| php | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| php_only | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| python | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| ql | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ |
| r | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| readline | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| rst | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| ruby | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ |
| rust | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| scala | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| scss | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| slang | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| supercollider | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| svelte | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| swift | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| tact | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ |
| terraform | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| toml | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| tsx | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | π© |
| twig | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| typescript | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | π© |
| v | π© | π© | β¬ | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© |
| verilog | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| vim | π© | π© | π© | π© | β¬ | β¬ | π© | π© | β¬ | π© | β¬ | β¬ | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | π© | β¬ | π© |
| vue | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| wgsl | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| wgsl_bevy | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ |
| yaml | π© | π© | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© |
| zig | β¬ | β¬ | β¬ | β¬ | β¬ | β¬ | π© | π© | π© | π© | π© | π© | β¬ | π© | π© | π© | β¬ | β¬ | π© | π© | π© | π© | β¬ | π© | π© | β¬ | β¬ | β¬ | β¬ | β¬ | π© |