mirror of
https://github.com/nvim-treesitter/nvim-treesitter
synced 2024-09-16 14:34:05 +02:00
Use stylua for autoformat code (#1480)
This commit is contained in:
parent
90f15d9bf7
commit
be8f656087
32 changed files with 1181 additions and 979 deletions
11
.github/workflows/lint.yml
vendored
11
.github/workflows/lint.yml
vendored
|
@ -18,3 +18,14 @@ jobs:
|
|||
|
||||
- name: Run Luacheck
|
||||
run: sudo ./scripts/style-check.sh
|
||||
|
||||
stylua:
|
||||
name: StyLua
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Lint with stylua
|
||||
uses: JohnnyMorganz/stylua-action@1.0.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --check .
|
||||
|
|
3
.stylua.toml
Normal file
3
.stylua.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
no_call_parentheses = true
|
1
.styluaignore
Normal file
1
.styluaignore
Normal file
|
@ -0,0 +1 @@
|
|||
tests/indent/lua/
|
|
@ -15,12 +15,13 @@ Depending on which part of the plugin you want to contribute to, please read the
|
|||
## Style Checks and Tests
|
||||
|
||||
We haven't implemented any functional tests yet. Feel free to contribute.
|
||||
However, we check code style with `luacheck`!
|
||||
However, we check code style with `luacheck` and `stylua`!
|
||||
Please install luacheck and activate our `pre-push` hook to automatically check style before
|
||||
every push:
|
||||
|
||||
```bash
|
||||
luarocks install luacheck
|
||||
cargo install stylua
|
||||
ln -s ../../scripts/pre-push .git/hooks/pre-push
|
||||
```
|
||||
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
if not pcall(require,"vim.treesitter.languagetree") then
|
||||
error("nvim-treesitter requires a more recent Neovim nightly version!")
|
||||
if not pcall(require, "vim.treesitter.languagetree") then
|
||||
error "nvim-treesitter requires a more recent Neovim nightly version!"
|
||||
end
|
||||
|
||||
local install = require'nvim-treesitter.install'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local info = require'nvim-treesitter.info'
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
|
||||
local install = require "nvim-treesitter.install"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local info = require "nvim-treesitter.info"
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
|
||||
-- Registers all query predicates
|
||||
require"nvim-treesitter.query_predicates"
|
||||
require "nvim-treesitter.query_predicates"
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.setup()
|
||||
utils.setup_commands('install', install.commands)
|
||||
utils.setup_commands('info', info.commands)
|
||||
utils.setup_commands('configs', configs.commands)
|
||||
utils.setup_commands("install", install.commands)
|
||||
utils.setup_commands("info", info.commands)
|
||||
utils.setup_commands("configs", configs.commands)
|
||||
configs.init()
|
||||
end
|
||||
|
||||
|
@ -35,37 +34,43 @@ local get_line_for_node = function(node, type_patterns, transform_fn)
|
|||
break
|
||||
end
|
||||
end
|
||||
if not is_valid then return '' end
|
||||
local line = transform_fn(vim.trim(ts_utils.get_node_text(node)[1] or ''))
|
||||
if not is_valid then
|
||||
return ""
|
||||
end
|
||||
local line = transform_fn(vim.trim(ts_utils.get_node_text(node)[1] or ""))
|
||||
-- Escape % to avoid statusline to evaluate content as expression
|
||||
return line:gsub('%%', '%%%%')
|
||||
return line:gsub("%%", "%%%%")
|
||||
end
|
||||
|
||||
-- Trim spaces and opening brackets from end
|
||||
local transform_line = function(line)
|
||||
return line:gsub('%s*[%[%(%{]*%s*$', '')
|
||||
return line:gsub("%s*[%[%(%{]*%s*$", "")
|
||||
end
|
||||
|
||||
function M.statusline(opts)
|
||||
if not parsers.has_parser() then return end
|
||||
if not parsers.has_parser() then
|
||||
return
|
||||
end
|
||||
local options = opts or {}
|
||||
if type(opts) == 'number' then
|
||||
options = {indicator_size = opts}
|
||||
if type(opts) == "number" then
|
||||
options = { indicator_size = opts }
|
||||
end
|
||||
local indicator_size = options.indicator_size or 100
|
||||
local type_patterns = options.type_patterns or {'class', 'function', 'method'}
|
||||
local type_patterns = options.type_patterns or { "class", "function", "method" }
|
||||
local transform_fn = options.transform_fn or transform_line
|
||||
local separator = options.separator or ' -> '
|
||||
local separator = options.separator or " -> "
|
||||
|
||||
local current_node = ts_utils.get_node_at_cursor()
|
||||
if not current_node then return "" end
|
||||
if not current_node then
|
||||
return ""
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
local expr = current_node
|
||||
|
||||
while expr do
|
||||
local line = get_line_for_node(expr, type_patterns, transform_fn)
|
||||
if line ~= '' and not vim.tbl_contains(lines, line) then
|
||||
if line ~= "" and not vim.tbl_contains(lines, line) then
|
||||
table.insert(lines, 1, line)
|
||||
end
|
||||
expr = expr:parent()
|
||||
|
@ -74,7 +79,7 @@ function M.statusline(opts)
|
|||
local text = table.concat(lines, separator)
|
||||
local text_len = #text
|
||||
if text_len > indicator_size then
|
||||
return '...'..text:sub(text_len - indicator_size, text_len)
|
||||
return "..." .. text:sub(text_len - indicator_size, text_len)
|
||||
end
|
||||
|
||||
return text
|
||||
|
|
|
@ -12,7 +12,7 @@ function M.create_buffer_cache()
|
|||
__index = function(tbl, key)
|
||||
rawset(tbl, key, {})
|
||||
return rawget(tbl, key)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
function cache.set(type_name, bufnr, value)
|
||||
|
@ -23,7 +23,7 @@ function M.create_buffer_cache()
|
|||
on_detach = function()
|
||||
cache.remove(type_name, bufnr)
|
||||
return true
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
local api = vim.api
|
||||
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local ts_query = require'vim.treesitter.query'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local caching = require'nvim-treesitter.caching'
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local ts_query = require "vim.treesitter.query"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local caching = require "nvim-treesitter.caching"
|
||||
|
||||
local M = {}
|
||||
|
||||
|
@ -12,7 +12,7 @@ local config = {
|
|||
modules = {},
|
||||
ensure_installed = {},
|
||||
ignore_install = {},
|
||||
update_strategy = 'lockfile',
|
||||
update_strategy = "lockfile",
|
||||
}
|
||||
-- List of modules that need to be setup on initialization.
|
||||
local queued_modules_defs = {}
|
||||
|
@ -20,31 +20,33 @@ local queued_modules_defs = {}
|
|||
local is_initialized = false
|
||||
local builtin_modules = {
|
||||
highlight = {
|
||||
module_path = 'nvim-treesitter.highlight',
|
||||
module_path = "nvim-treesitter.highlight",
|
||||
enable = false,
|
||||
disable = {'markdown'}, -- FIXME(vigoux): markdown highlighting breaks everything for now
|
||||
disable = { "markdown" }, -- FIXME(vigoux): markdown highlighting breaks everything for now
|
||||
custom_captures = {},
|
||||
is_supported = queries.has_highlights,
|
||||
additional_vim_regex_highlighting = false,
|
||||
},
|
||||
incremental_selection = {
|
||||
module_path = 'nvim-treesitter.incremental_selection',
|
||||
module_path = "nvim-treesitter.incremental_selection",
|
||||
enable = false,
|
||||
disable = {},
|
||||
keymaps = {
|
||||
init_selection="gnn",
|
||||
node_incremental="grn",
|
||||
scope_incremental="grc",
|
||||
node_decremental="grm"
|
||||
init_selection = "gnn",
|
||||
node_incremental = "grn",
|
||||
scope_incremental = "grc",
|
||||
node_decremental = "grm",
|
||||
},
|
||||
is_supported = function() return true end
|
||||
is_supported = function()
|
||||
return true
|
||||
end,
|
||||
},
|
||||
indent = {
|
||||
module_path = 'nvim-treesitter.indent',
|
||||
module_path = "nvim-treesitter.indent",
|
||||
enable = false,
|
||||
disable = {},
|
||||
is_supported = queries.has_indents
|
||||
}
|
||||
is_supported = queries.has_indents,
|
||||
},
|
||||
}
|
||||
|
||||
local attached_buffers_by_module = caching.create_buffer_cache()
|
||||
|
@ -53,11 +55,13 @@ local attached_buffers_by_module = caching.create_buffer_cache()
|
|||
local function resolve_module(mod_name)
|
||||
local config_mod = M.get_module(mod_name)
|
||||
|
||||
if not config_mod then return end
|
||||
if not config_mod then
|
||||
return
|
||||
end
|
||||
|
||||
if type(config_mod.attach) == 'function' and type(config_mod.detach) == 'function' then
|
||||
if type(config_mod.attach) == "function" and type(config_mod.detach) == "function" then
|
||||
return config_mod
|
||||
elseif type(config_mod.module_path) == 'string' then
|
||||
elseif type(config_mod.module_path) == "string" then
|
||||
return require(config_mod.module_path)
|
||||
end
|
||||
end
|
||||
|
@ -92,7 +96,9 @@ end
|
|||
-- @param mod path to module
|
||||
local function enable_all(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod then return end
|
||||
if not config_mod then
|
||||
return
|
||||
end
|
||||
|
||||
for _, bufnr in pairs(api.nvim_list_bufs()) do
|
||||
enable_module(mod, bufnr)
|
||||
|
@ -120,7 +126,7 @@ local function disable_mod_conf_autocmd(mod)
|
|||
end
|
||||
-- TODO(kyazdani): detach the correct autocmd... doesn't work when using %s, cmd.
|
||||
-- This will remove all autocomands!
|
||||
api.nvim_command("autocmd! NvimTreesitter FileType *")
|
||||
api.nvim_command "autocmd! NvimTreesitter FileType *"
|
||||
config_mod.loaded = false
|
||||
end
|
||||
|
||||
|
@ -129,7 +135,9 @@ end
|
|||
-- @param mod path to module
|
||||
local function disable_all(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod or not config_mod.enable then return end
|
||||
if not config_mod or not config_mod.enable then
|
||||
return
|
||||
end
|
||||
|
||||
for _, bufnr in pairs(api.nvim_list_bufs()) do
|
||||
disable_module(mod, bufnr)
|
||||
|
@ -158,7 +166,9 @@ end
|
|||
-- @param mod path to module
|
||||
local function toggle_all(mod)
|
||||
local config_mod = M.get_module(mod)
|
||||
if not config_mod then return end
|
||||
if not config_mod then
|
||||
return
|
||||
end
|
||||
|
||||
if config_mod.enable then
|
||||
disable_all(mod)
|
||||
|
@ -175,11 +185,11 @@ local function recurse_modules(accumulator, root, path)
|
|||
local root = root or config.modules
|
||||
|
||||
for name, module in pairs(root) do
|
||||
local new_path = path and (path..'.'..name) or name
|
||||
local new_path = path and (path .. "." .. name) or name
|
||||
|
||||
if M.is_module(module) then
|
||||
accumulator(name, module, new_path, root)
|
||||
elseif type(module) == 'table' then
|
||||
elseif type(module) == "table" then
|
||||
recurse_modules(accumulator, module, new_path)
|
||||
end
|
||||
end
|
||||
|
@ -189,53 +199,56 @@ end
|
|||
-- @param process_function function used as the `process` parameter
|
||||
-- for vim.inspect (https://github.com/kikito/inspect.lua#optionsprocess)
|
||||
local function config_info(process_function)
|
||||
process_function = process_function or function(item, path)
|
||||
if path[#path] == vim.inspect.METATABLE then return end
|
||||
if path[#path] == "is_supported" then return end
|
||||
return item
|
||||
end
|
||||
print(vim.inspect(config, {process = process_function}))
|
||||
process_function = process_function
|
||||
or function(item, path)
|
||||
if path[#path] == vim.inspect.METATABLE then
|
||||
return
|
||||
end
|
||||
if path[#path] == "is_supported" then
|
||||
return
|
||||
end
|
||||
return item
|
||||
end
|
||||
print(vim.inspect(config, { process = process_function }))
|
||||
end
|
||||
|
||||
function M.edit_query_file(query_group, lang)
|
||||
lang = lang or parsers.get_buf_lang()
|
||||
local files = ts_query.get_query_files(lang, query_group, true)
|
||||
if #files == 0 then
|
||||
vim.notify('No query file found! Creating a new one!')
|
||||
vim.notify "No query file found! Creating a new one!"
|
||||
M.edit_query_file_user_after(query_group, lang)
|
||||
elseif #files == 1 then
|
||||
vim.cmd(':edit '..files[1])
|
||||
vim.cmd(":edit " .. files[1])
|
||||
else
|
||||
local counter = 0
|
||||
local choices = {
|
||||
'Select a file:',
|
||||
"Select a file:",
|
||||
unpack(vim.tbl_map(function(f)
|
||||
counter = counter + 1
|
||||
return counter..'. '..f
|
||||
end,
|
||||
files
|
||||
))
|
||||
counter = counter + 1
|
||||
return counter .. ". " .. f
|
||||
end, files)),
|
||||
}
|
||||
local choice = vim.fn.inputlist(choices)
|
||||
if choice > 0 and choice <= #files then
|
||||
vim.cmd(':edit '..files[choice])
|
||||
vim.cmd(":edit " .. files[choice])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.edit_query_file_user_after(query_group, lang)
|
||||
lang = lang or parsers.get_buf_lang()
|
||||
local folder = utils.join_path(vim.fn.stdpath('config'), 'after', 'queries', lang)
|
||||
local file = utils.join_path(folder, query_group..'.scm')
|
||||
local folder = utils.join_path(vim.fn.stdpath "config", "after", "queries", lang)
|
||||
local file = utils.join_path(folder, query_group .. ".scm")
|
||||
if vim.fn.isdirectory(folder) ~= 1 then
|
||||
local choice = vim.fn.inputlist({'"'..folder.." does not exist. Create it?", "1. Yes", "2. No"})
|
||||
local choice = vim.fn.inputlist { '"' .. folder .. " does not exist. Create it?", "1. Yes", "2. No" }
|
||||
if choice == 1 then
|
||||
vim.fn.mkdir(folder, "p", "0755")
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
vim.cmd(':edit '..file)
|
||||
vim.cmd(":edit " .. file)
|
||||
end
|
||||
|
||||
M.commands = {
|
||||
|
@ -311,14 +324,18 @@ function M.is_enabled(mod, lang)
|
|||
end
|
||||
|
||||
local module_config = M.get_module(mod)
|
||||
if not module_config then return false end
|
||||
if not module_config then
|
||||
return false
|
||||
end
|
||||
|
||||
if not module_config.enable or not module_config.is_supported(lang) then
|
||||
return false
|
||||
end
|
||||
|
||||
for _, parser in pairs(module_config.disable) do
|
||||
if lang == parser then return false end
|
||||
if lang == parser then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
|
@ -327,12 +344,12 @@ end
|
|||
-- Setup call for users to override module configurations.
|
||||
-- @param user_data module overrides
|
||||
function M.setup(user_data)
|
||||
config.modules = vim.tbl_deep_extend('force', config.modules, user_data)
|
||||
config.modules = vim.tbl_deep_extend("force", config.modules, user_data)
|
||||
config.ignore_install = user_data.ignore_install or {}
|
||||
|
||||
local ensure_installed = user_data.ensure_installed or {}
|
||||
if #ensure_installed > 0 then
|
||||
require'nvim-treesitter.install'.ensure_installed(ensure_installed)
|
||||
require("nvim-treesitter.install").ensure_installed(ensure_installed)
|
||||
end
|
||||
|
||||
config.modules.ensure_installed = nil
|
||||
|
@ -381,7 +398,9 @@ function M.define_modules(mod_defs)
|
|||
group[key] = vim.tbl_extend("keep", mod, {
|
||||
enable = false,
|
||||
disable = {},
|
||||
is_supported = function() return true end
|
||||
is_supported = function()
|
||||
return true
|
||||
end,
|
||||
})
|
||||
end, mod_defs)
|
||||
|
||||
|
@ -404,9 +423,7 @@ function M.attach_module(mod_name, bufnr, lang)
|
|||
local lang = lang or parsers.get_buf_lang(bufnr)
|
||||
local resolved_mod = resolve_module(mod_name)
|
||||
|
||||
if resolved_mod
|
||||
and not attached_buffers_by_module.has(mod_name, bufnr)
|
||||
and M.is_enabled(mod_name, lang) then
|
||||
if resolved_mod and not attached_buffers_by_module.has(mod_name, bufnr) and M.is_enabled(mod_name, lang) then
|
||||
attached_buffers_by_module.set(mod_name, bufnr, true)
|
||||
resolved_mod.attach(bufnr, lang)
|
||||
end
|
||||
|
@ -450,9 +467,9 @@ end
|
|||
-- A module should contain an attach and detach function.
|
||||
-- @param mod the module table
|
||||
function M.is_module(mod)
|
||||
return type(mod) == 'table'
|
||||
and ((type(mod.attach) == 'function' and type(mod.detach) == 'function')
|
||||
or type(mod.module_path) == 'string')
|
||||
return type(mod) == "table" and ((type(mod.attach) == "function" and type(mod.detach) == "function") or type(
|
||||
mod.module_path
|
||||
) == "string")
|
||||
end
|
||||
|
||||
-- Initializes built-in modules and any queued modules
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
local api = vim.api
|
||||
local tsutils = require'nvim-treesitter.ts_utils'
|
||||
local query = require'nvim-treesitter.query'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local tsutils = require "nvim-treesitter.ts_utils"
|
||||
local query = require "nvim-treesitter.query"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
|
||||
local M = {}
|
||||
|
||||
-- This is cached on buf tick to avoid computing that multiple times
|
||||
-- Especially not for every line in the file when `zx` is hit
|
||||
local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
|
||||
local max_fold_level = api.nvim_win_get_option(0, 'foldnestmax')
|
||||
local max_fold_level = api.nvim_win_get_option(0, "foldnestmax")
|
||||
local parser = parsers.get_parser(bufnr)
|
||||
|
||||
if not parser then return {} end
|
||||
if not parser then
|
||||
return {}
|
||||
end
|
||||
|
||||
local matches = query.get_capture_matches_recursively(bufnr, function(lang)
|
||||
if query.has_folds(lang) then
|
||||
|
@ -44,13 +46,13 @@ local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
|
|||
local current_level = 0
|
||||
|
||||
-- We now have the list of fold opening and closing, fill the gaps and mark where fold start
|
||||
for lnum=0, api.nvim_buf_line_count(bufnr) do
|
||||
local prefix = ''
|
||||
for lnum = 0, api.nvim_buf_line_count(bufnr) do
|
||||
local prefix = ""
|
||||
local shift = levels_tmp[lnum] or 0
|
||||
|
||||
-- Determine if it's the start of a fold
|
||||
if levels_tmp[lnum] and shift >= 0 then
|
||||
prefix = '>'
|
||||
prefix = ">"
|
||||
end
|
||||
|
||||
current_level = current_level + shift
|
||||
|
@ -67,13 +69,15 @@ local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
|
|||
end)
|
||||
|
||||
function M.get_fold_indic(lnum)
|
||||
if not parsers.has_parser() or not lnum then return '0' end
|
||||
if not parsers.has_parser() or not lnum then
|
||||
return "0"
|
||||
end
|
||||
|
||||
local buf = api.nvim_get_current_buf()
|
||||
|
||||
local levels = folds_levels(buf) or {}
|
||||
|
||||
return levels[lnum] or '0'
|
||||
return levels[lnum] or "0"
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -1,75 +1,92 @@
|
|||
local api = vim.api
|
||||
local fn = vim.fn
|
||||
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local info = require'nvim-treesitter.info'
|
||||
local shell = require'nvim-treesitter.shell_command_selectors'
|
||||
local install = require'nvim-treesitter.install'
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local info = require "nvim-treesitter.info"
|
||||
local shell = require "nvim-treesitter.shell_command_selectors"
|
||||
local install = require "nvim-treesitter.install"
|
||||
|
||||
local health_start = vim.fn["health#report_start"]
|
||||
local health_ok = vim.fn['health#report_ok']
|
||||
local health_error = vim.fn['health#report_error']
|
||||
local health_warn = vim.fn['health#report_warn']
|
||||
local health_ok = vim.fn["health#report_ok"]
|
||||
local health_error = vim.fn["health#report_error"]
|
||||
local health_warn = vim.fn["health#report_warn"]
|
||||
|
||||
local M = {}
|
||||
|
||||
local NVIM_TREESITTER_MINIMUM_ABI = 13
|
||||
|
||||
local function install_health()
|
||||
health_start('Installation')
|
||||
health_start "Installation"
|
||||
|
||||
if fn.executable('tree-sitter') == 0 then
|
||||
health_warn('`tree-sitter` executable not found (parser generator, only needed for :TSInstallFromGrammar,'..
|
||||
' not required for :TSInstall)')
|
||||
if fn.executable "tree-sitter" == 0 then
|
||||
health_warn(
|
||||
"`tree-sitter` executable not found (parser generator, only needed for :TSInstallFromGrammar,"
|
||||
.. " not required for :TSInstall)"
|
||||
)
|
||||
else
|
||||
local handle = io.popen('tree-sitter -V')
|
||||
local result = handle:read("*a")
|
||||
local handle = io.popen "tree-sitter -V"
|
||||
local result = handle:read "*a"
|
||||
handle:close()
|
||||
local version = vim.split(result,'\n')[1]:match('[^tree%psitter].*')
|
||||
local version = vim.split(result, "\n")[1]:match "[^tree%psitter].*"
|
||||
health_ok(
|
||||
"`tree-sitter` found " ..
|
||||
(version or "(unknown version)") .. " (parser generator, only needed for :TSInstallFromGrammar)"
|
||||
"`tree-sitter` found "
|
||||
.. (version or "(unknown version)")
|
||||
.. " (parser generator, only needed for :TSInstallFromGrammar)"
|
||||
)
|
||||
end
|
||||
|
||||
if fn.executable('node') == 0 then
|
||||
health_warn('`node` executable not found (only needed for :TSInstallFromGrammar,'..
|
||||
' not required for :TSInstall)')
|
||||
if fn.executable "node" == 0 then
|
||||
health_warn(
|
||||
"`node` executable not found (only needed for :TSInstallFromGrammar," .. " not required for :TSInstall)"
|
||||
)
|
||||
else
|
||||
local handle = io.popen('node --version')
|
||||
local result = handle:read("*a")
|
||||
local handle = io.popen "node --version"
|
||||
local result = handle:read "*a"
|
||||
handle:close()
|
||||
local version = vim.split(result,'\n')[1]
|
||||
health_ok('`node` found '..version..' (only needed for :TSInstallFromGrammar)')
|
||||
local version = vim.split(result, "\n")[1]
|
||||
health_ok("`node` found " .. version .. " (only needed for :TSInstallFromGrammar)")
|
||||
end
|
||||
|
||||
if fn.executable('git') == 0 then
|
||||
health_error('`git` executable not found.', {
|
||||
'Install it with your package manager.',
|
||||
'Check that your `$PATH` is set correctly.'
|
||||
if fn.executable "git" == 0 then
|
||||
health_error("`git` executable not found.", {
|
||||
"Install it with your package manager.",
|
||||
"Check that your `$PATH` is set correctly.",
|
||||
})
|
||||
else
|
||||
health_ok('`git` executable found.')
|
||||
health_ok "`git` executable found."
|
||||
end
|
||||
|
||||
local cc = shell.select_executable(install.compilers)
|
||||
if not cc then
|
||||
health_error('`cc` executable not found.', {
|
||||
'Check that any of '..vim.inspect(install.compilers)..' is in your $PATH'
|
||||
..' or set the environment variable CC or `require"nvim-treesitter.install".compilers` explicitly!'
|
||||
health_error("`cc` executable not found.", {
|
||||
"Check that any of "
|
||||
.. vim.inspect(install.compilers)
|
||||
.. " is in your $PATH"
|
||||
.. ' or set the environment variable CC or `require"nvim-treesitter.install".compilers` explicitly!',
|
||||
})
|
||||
else
|
||||
health_ok('`'..cc..'` executable found. Selected from '..vim.inspect(install.compilers))
|
||||
health_ok("`" .. cc .. "` executable found. Selected from " .. vim.inspect(install.compilers))
|
||||
end
|
||||
if vim.treesitter.language_version then
|
||||
if vim.treesitter.language_version >= NVIM_TREESITTER_MINIMUM_ABI then
|
||||
health_ok('Neovim was compiled with tree-sitter runtime ABI version '..vim.treesitter.language_version
|
||||
..' (required >='..NVIM_TREESITTER_MINIMUM_ABI..'). Parsers must be compatible with runtime ABI.')
|
||||
health_ok(
|
||||
"Neovim was compiled with tree-sitter runtime ABI version "
|
||||
.. vim.treesitter.language_version
|
||||
.. " (required >="
|
||||
.. NVIM_TREESITTER_MINIMUM_ABI
|
||||
.. "). Parsers must be compatible with runtime ABI."
|
||||
)
|
||||
else
|
||||
health_error('Neovim was compiled with tree-sitter runtime ABI version '..vim.treesitter.language_version..'.\n'
|
||||
..'nvim-treesitter expects at least ABI version '..NVIM_TREESITTER_MINIMUM_ABI..'\n'
|
||||
..'Please make sure that Neovim is linked against are recent tree-sitter runtime when building'
|
||||
..' or raise an issue at your Neovim packager. Parsers must be compatible with runtime ABI.')
|
||||
health_error(
|
||||
"Neovim was compiled with tree-sitter runtime ABI version "
|
||||
.. vim.treesitter.language_version
|
||||
.. ".\n"
|
||||
.. "nvim-treesitter expects at least ABI version "
|
||||
.. NVIM_TREESITTER_MINIMUM_ABI
|
||||
.. "\n"
|
||||
.. "Please make sure that Neovim is linked against are recent tree-sitter runtime when building"
|
||||
.. " or raise an issue at your Neovim packager. Parsers must be compatible with runtime ABI."
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -90,35 +107,35 @@ function M.checkhealth()
|
|||
-- Installation dependency checks
|
||||
install_health()
|
||||
queries.invalidate_query_cache()
|
||||
health_start("Parser/Features H L F I")
|
||||
health_start "Parser/Features H L F I"
|
||||
-- Parser installation checks
|
||||
for _, parser_name in pairs(info.installed_parsers()) do
|
||||
local installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false)
|
||||
local installed = #api.nvim_get_runtime_file("parser/" .. parser_name .. ".so", false)
|
||||
|
||||
-- Only print informations about installed parsers
|
||||
if installed >= 1 then
|
||||
local multiple_parsers = installed > 1 and "+" or ""
|
||||
local out = " - "..parser_name..multiple_parsers..string.rep(" ", 15 - (#parser_name + #multiple_parsers))
|
||||
local out = " - " .. parser_name .. multiple_parsers .. string.rep(" ", 15 - (#parser_name + #multiple_parsers))
|
||||
for _, query_group in pairs(queries.built_in_query_groups) do
|
||||
local status, err = query_status(parser_name, query_group)
|
||||
out = out..status.." "
|
||||
out = out .. status .. " "
|
||||
if err then
|
||||
table.insert(error_collection, {parser_name, query_group, err})
|
||||
table.insert(error_collection, { parser_name, query_group, err })
|
||||
end
|
||||
end
|
||||
print(out)
|
||||
end
|
||||
end
|
||||
print([[
|
||||
print [[
|
||||
|
||||
Legend: H[ighlight], L[ocals], F[olds], I[ndents]
|
||||
+) multiple parsers found, only one will be used
|
||||
x) errors found in the query, try to run :TSUpdate {lang}]])
|
||||
x) errors found in the query, try to run :TSUpdate {lang}]]
|
||||
if #error_collection > 0 then
|
||||
print('\nThe following errors have been detected:')
|
||||
print "\nThe following errors have been detected:"
|
||||
for _, p in ipairs(error_collection) do
|
||||
local lang, type, err = unpack(p)
|
||||
health_error(lang..'('..type..'): '..err)
|
||||
health_error(lang .. "(" .. type .. "): " .. err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
local api = vim.api
|
||||
local ts = vim.treesitter
|
||||
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
|
||||
local M = {
|
||||
}
|
||||
local M = {}
|
||||
|
||||
local hlmap = vim.treesitter.highlighter.hl_map
|
||||
|
||||
|
@ -104,7 +103,7 @@ hlmap["variable.builtin"] = "TSVariableBuiltin"
|
|||
|
||||
function M.attach(bufnr, lang)
|
||||
local parser = parsers.get_parser(bufnr, lang)
|
||||
local config = configs.get_module('highlight')
|
||||
local config = configs.get_module "highlight"
|
||||
|
||||
for k, v in pairs(config.custom_captures) do
|
||||
hlmap[k] = v
|
||||
|
@ -112,9 +111,9 @@ function M.attach(bufnr, lang)
|
|||
|
||||
ts.highlighter.new(parser, {})
|
||||
|
||||
local is_table = type(config.additional_vim_regex_highlighting) == 'table'
|
||||
local is_table = type(config.additional_vim_regex_highlighting) == "table"
|
||||
if config.additional_vim_regex_highlighting and (not is_table or config.additional_vim_regex_highlighting[lang]) then
|
||||
api.nvim_buf_set_option(bufnr, 'syntax', 'ON')
|
||||
api.nvim_buf_set_option(bufnr, "syntax", "ON")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -122,7 +121,7 @@ function M.detach(bufnr)
|
|||
if ts.highlighter.active[bufnr] then
|
||||
ts.highlighter.active[bufnr]:destroy()
|
||||
end
|
||||
api.nvim_buf_set_option(bufnr, 'syntax', 'ON')
|
||||
api.nvim_buf_set_option(bufnr, "syntax", "ON")
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
local api = vim.api
|
||||
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local locals = require'nvim-treesitter.locals'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local locals = require "nvim-treesitter.locals"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local queries = require "nvim-treesitter.query"
|
||||
|
||||
local M = {}
|
||||
|
||||
|
@ -21,8 +21,8 @@ end
|
|||
--
|
||||
-- The range of ts nodes start with 0 and the ending range is exclusive.
|
||||
local function visual_selection_range()
|
||||
local _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
|
||||
local _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))
|
||||
local _, csrow, cscol, _ = unpack(vim.fn.getpos "'<")
|
||||
local _, cerow, cecol, _ = unpack(vim.fn.getpos "'>")
|
||||
|
||||
local start_row, start_col, end_row, end_col
|
||||
|
||||
|
@ -39,8 +39,8 @@ local function visual_selection_range()
|
|||
end
|
||||
|
||||
-- The last char in ts is equivalent to the EOF in another line.
|
||||
local last_row = vim.fn.line("$")
|
||||
local last_col = vim.fn.col({last_row, "$"})
|
||||
local last_row = vim.fn.line "$"
|
||||
local last_col = vim.fn.col { last_row, "$" }
|
||||
last_row = last_row - 1
|
||||
last_col = last_col - 1
|
||||
if end_row == last_row and end_col == last_col then
|
||||
|
@ -92,12 +92,7 @@ local function select_incremental(get_parent)
|
|||
end
|
||||
node = parent
|
||||
local srow, scol, erow, ecol = node:range()
|
||||
local same_range = (
|
||||
srow == csrow
|
||||
and scol == cscol
|
||||
and erow == cerow
|
||||
and ecol == cecol
|
||||
)
|
||||
local same_range = (srow == csrow and scol == cscol and erow == cerow and ecol == cecol)
|
||||
if not same_range then
|
||||
table.insert(selections[buf], node)
|
||||
if node ~= nodes[#nodes] then
|
||||
|
@ -126,7 +121,9 @@ end)
|
|||
function M.node_decremental()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local nodes = selections[buf]
|
||||
if not nodes or #nodes < 2 then return end
|
||||
if not nodes or #nodes < 2 then
|
||||
return
|
||||
end
|
||||
|
||||
table.remove(selections[buf])
|
||||
local node = nodes[#nodes]
|
||||
|
@ -134,13 +131,13 @@ function M.node_decremental()
|
|||
end
|
||||
|
||||
function M.attach(bufnr)
|
||||
local config = configs.get_module('incremental_selection')
|
||||
local config = configs.get_module "incremental_selection"
|
||||
for funcname, mapping in pairs(config.keymaps) do
|
||||
local mode
|
||||
if funcname == "init_selection" then
|
||||
mode = 'n'
|
||||
mode = "n"
|
||||
else
|
||||
mode = 'x'
|
||||
mode = "x"
|
||||
end
|
||||
local cmd = string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname)
|
||||
api.nvim_buf_set_keymap(bufnr, mode, mapping, cmd, { silent = true, noremap = true })
|
||||
|
@ -148,12 +145,12 @@ function M.attach(bufnr)
|
|||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
local config = configs.get_module('incremental_selection')
|
||||
local config = configs.get_module "incremental_selection"
|
||||
for f, mapping in pairs(config.keymaps) do
|
||||
if f == "init_selection" then
|
||||
api.nvim_buf_del_keymap(bufnr, 'n', mapping)
|
||||
api.nvim_buf_del_keymap(bufnr, "n", mapping)
|
||||
else
|
||||
api.nvim_buf_del_keymap(bufnr, 'x', mapping)
|
||||
api.nvim_buf_del_keymap(bufnr, "x", mapping)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local parsers = require'nvim-treesitter.parsers'
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local tsutils = require'nvim-treesitter.ts_utils'
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local tsutils = require "nvim-treesitter.ts_utils"
|
||||
|
||||
local M = {}
|
||||
|
||||
|
@ -8,7 +8,9 @@ local M = {}
|
|||
local function get_node_at_line(root, lnum)
|
||||
for node in root:iter_children() do
|
||||
local srow, _, erow = node:range()
|
||||
if srow == lnum then return node end
|
||||
if srow == lnum then
|
||||
return node
|
||||
end
|
||||
|
||||
if node:child_count() > 0 and srow < lnum and lnum <= erow then
|
||||
return get_node_at_line(node, lnum)
|
||||
|
@ -17,13 +19,15 @@ local function get_node_at_line(root, lnum)
|
|||
end
|
||||
|
||||
local function node_fmt(node)
|
||||
if not node then return nil end
|
||||
if not node then
|
||||
return nil
|
||||
end
|
||||
return tostring(node)
|
||||
end
|
||||
|
||||
local get_indents = tsutils.memoize_by_buf_tick(function(bufnr, root, lang)
|
||||
local get_map = function(capture)
|
||||
local matches = queries.get_capture_matches(bufnr, capture, 'indents', root, lang) or {}
|
||||
local matches = queries.get_capture_matches(bufnr, capture, "indents", root, lang) or {}
|
||||
local map = {}
|
||||
for _, node in ipairs(matches) do
|
||||
map[tostring(node)] = true
|
||||
|
@ -32,29 +36,33 @@ local get_indents = tsutils.memoize_by_buf_tick(function(bufnr, root, lang)
|
|||
end
|
||||
|
||||
return {
|
||||
indents = get_map('@indent.node'),
|
||||
branches = get_map('@branch.node'),
|
||||
returns = get_map('@return.node'),
|
||||
ignores = get_map('@ignore.node'),
|
||||
indents = get_map "@indent.node",
|
||||
branches = get_map "@branch.node",
|
||||
returns = get_map "@return.node",
|
||||
ignores = get_map "@ignore.node",
|
||||
}
|
||||
end, {
|
||||
-- Memoize by bufnr and lang together.
|
||||
key = function(bufnr, _, lang)
|
||||
return tostring(bufnr) .. '_' .. lang
|
||||
end
|
||||
return tostring(bufnr) .. "_" .. lang
|
||||
end,
|
||||
})
|
||||
|
||||
function M.get_indent(lnum)
|
||||
local parser = parsers.get_parser()
|
||||
if not parser or not lnum then return -1 end
|
||||
if not parser or not lnum then
|
||||
return -1
|
||||
end
|
||||
|
||||
local root, _, lang_tree = tsutils.get_root_for_position(lnum, 0, parser)
|
||||
|
||||
-- Not likely, but just in case...
|
||||
if not root then return 0 end
|
||||
if not root then
|
||||
return 0
|
||||
end
|
||||
|
||||
local q = get_indents(vim.api.nvim_get_current_buf(), root, lang_tree:lang())
|
||||
local node = get_node_at_line(root, lnum-1)
|
||||
local node = get_node_at_line(root, lnum - 1)
|
||||
|
||||
local indent = 0
|
||||
local indent_size = vim.fn.shiftwidth()
|
||||
|
@ -65,11 +73,11 @@ function M.get_indent(lnum)
|
|||
if not node then
|
||||
local prevnonblank = vim.fn.prevnonblank(lnum)
|
||||
if prevnonblank ~= lnum then
|
||||
local prev_node = get_node_at_line(root, prevnonblank-1)
|
||||
local prev_node = get_node_at_line(root, prevnonblank - 1)
|
||||
-- get previous node in any case to avoid erroring
|
||||
while not prev_node and prevnonblank-1 > 0 do
|
||||
prevnonblank = vim.fn.prevnonblank(prevnonblank-1)
|
||||
prev_node = get_node_at_line(root, prevnonblank-1)
|
||||
while not prev_node and prevnonblank - 1 > 0 do
|
||||
prevnonblank = vim.fn.prevnonblank(prevnonblank - 1)
|
||||
prev_node = get_node_at_line(root, prevnonblank - 1)
|
||||
end
|
||||
|
||||
-- nodes can be marked @return to prevent using them
|
||||
|
@ -91,7 +99,7 @@ function M.get_indent(lnum)
|
|||
-- if the prevnonblank fails (prev_node wraps our line) we need to fall back to taking
|
||||
-- the first child of the node that wraps the current line, or the wrapper itself
|
||||
if not node then
|
||||
local wrapper = root:descendant_for_range(lnum-1, 0, lnum-1, -1)
|
||||
local wrapper = root:descendant_for_range(lnum - 1, 0, lnum - 1, -1)
|
||||
node = wrapper:child(0) or wrapper
|
||||
if q.indents[node_fmt(wrapper)] ~= nil and wrapper ~= root then
|
||||
indent = indent_size
|
||||
|
@ -107,7 +115,7 @@ function M.get_indent(lnum)
|
|||
|
||||
while node do
|
||||
-- do not indent if we are inside an @ignore block
|
||||
if q.ignores[node_fmt(node)] and node:start() < lnum-1 and node:end_() > lnum-1 then
|
||||
if q.ignores[node_fmt(node)] and node:start() < lnum - 1 and node:end_() > lnum - 1 then
|
||||
return -1
|
||||
end
|
||||
|
||||
|
@ -129,8 +137,8 @@ local indent_funcs = {}
|
|||
|
||||
function M.attach(bufnr)
|
||||
indent_funcs[bufnr] = vim.bo.indentexpr
|
||||
vim.bo.indentexpr = 'nvim_treesitter#indent()'
|
||||
vim.api.nvim_command("au Filetype "..vim.bo.filetype.." setlocal indentexpr=nvim_treesitter#indent()")
|
||||
vim.bo.indentexpr = "nvim_treesitter#indent()"
|
||||
vim.api.nvim_command("au Filetype " .. vim.bo.filetype .. " setlocal indentexpr=nvim_treesitter#indent()")
|
||||
end
|
||||
|
||||
function M.detach(bufnr)
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
local api = vim.api
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
|
||||
local M = {}
|
||||
|
||||
local function install_info()
|
||||
local max_len = 0
|
||||
for _, ft in pairs(parsers.available_parsers()) do
|
||||
if #ft > max_len then max_len = #ft end
|
||||
if #ft > max_len then
|
||||
max_len = #ft
|
||||
end
|
||||
end
|
||||
|
||||
local parser_list = parsers.available_parsers()
|
||||
table.sort(parser_list)
|
||||
for _, ft in pairs(parser_list) do
|
||||
local is_installed = #api.nvim_get_runtime_file('parser/'..ft..'.so', false) > 0
|
||||
api.nvim_out_write(ft..string.rep(' ', max_len - #ft + 1))
|
||||
local is_installed = #api.nvim_get_runtime_file("parser/" .. ft .. ".so", false) > 0
|
||||
api.nvim_out_write(ft .. string.rep(" ", max_len - #ft + 1))
|
||||
if is_installed then
|
||||
api.nvim_out_write("[✓] installed\n")
|
||||
api.nvim_out_write "[✓] installed\n"
|
||||
else
|
||||
api.nvim_out_write("[✗] not installed\n")
|
||||
api.nvim_out_write "[✗] not installed\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -30,8 +32,8 @@ end
|
|||
local function namespace_modules(modulelist)
|
||||
local modules = {}
|
||||
for _, module in ipairs(modulelist) do
|
||||
if module:find('%.') then
|
||||
local namespace, submodule = module:match('^(.*)%.(.*)$')
|
||||
if module:find "%." then
|
||||
local namespace, submodule = module:match "^(.*)%.(.*)$"
|
||||
if not modules[namespace] then
|
||||
modules[namespace] = {}
|
||||
end
|
||||
|
@ -61,46 +63,48 @@ local function append_module_table(curbuf, parserlist, namespace, modulelist)
|
|||
table.sort(modulelist)
|
||||
|
||||
-- header
|
||||
local header = '>> ' .. namespace .. string.rep(' ', maxlen_parser - #namespace - 1)
|
||||
local header = ">> " .. namespace .. string.rep(" ", maxlen_parser - #namespace - 1)
|
||||
for _, module in pairs(modulelist) do
|
||||
header = header .. module .. ' '
|
||||
header = header .. module .. " "
|
||||
end
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, {header})
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, { header })
|
||||
|
||||
-- actual table
|
||||
for _, parser in ipairs(parserlist) do
|
||||
local padding = string.rep(' ', maxlen_parser - #parser + 2)
|
||||
local line = parser .. padding
|
||||
local namespace_prefix = (namespace == 'default') and '' or namespace .. '.'
|
||||
local padding = string.rep(" ", maxlen_parser - #parser + 2)
|
||||
local line = parser .. padding
|
||||
local namespace_prefix = (namespace == "default") and "" or namespace .. "."
|
||||
for _, module in pairs(modulelist) do
|
||||
local modlen = #module
|
||||
module = namespace_prefix .. module
|
||||
if configs.is_enabled(module, parser) then
|
||||
line = line .. '✓'
|
||||
line = line .. "✓"
|
||||
else
|
||||
line = line .. '✗'
|
||||
line = line .. "✗"
|
||||
end
|
||||
line = line .. string.rep(' ', modlen + 1)
|
||||
line = line .. string.rep(" ", modlen + 1)
|
||||
end
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, {line})
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, { line })
|
||||
end
|
||||
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, {''})
|
||||
api.nvim_buf_set_lines(curbuf, -1, -1, true, { "" })
|
||||
end
|
||||
|
||||
local function print_info_modules(parserlist, module)
|
||||
api.nvim_command('enew')
|
||||
api.nvim_command "enew"
|
||||
local curbuf = api.nvim_get_current_buf()
|
||||
|
||||
local modules
|
||||
if module then
|
||||
modules = namespace_modules({module})
|
||||
modules = namespace_modules { module }
|
||||
else
|
||||
modules = namespace_modules(configs.available_modules())
|
||||
end
|
||||
|
||||
local namespaces = {}
|
||||
for k, _ in pairs(modules) do table.insert(namespaces, k) end
|
||||
for k, _ in pairs(modules) do
|
||||
table.insert(namespaces, k)
|
||||
end
|
||||
table.sort(namespaces)
|
||||
|
||||
table.sort(parserlist)
|
||||
|
@ -108,9 +112,10 @@ local function print_info_modules(parserlist, module)
|
|||
append_module_table(curbuf, parserlist, namespace, modules[namespace])
|
||||
end
|
||||
|
||||
api.nvim_buf_set_option(curbuf, 'modified', false)
|
||||
api.nvim_buf_set_option(curbuf, 'buftype', 'nofile')
|
||||
api.nvim_exec([[
|
||||
api.nvim_buf_set_option(curbuf, "modified", false)
|
||||
api.nvim_buf_set_option(curbuf, "buftype", "nofile")
|
||||
api.nvim_exec(
|
||||
[[
|
||||
syntax match TSModuleInfoGood /✓/
|
||||
syntax match TSModuleInfoBad /✗/
|
||||
syntax match TSModuleInfoHeader /^>>.*$/ contains=TSModuleInfoNamespace
|
||||
|
@ -121,11 +126,15 @@ local function print_info_modules(parserlist, module)
|
|||
highlight default link TSModuleInfoHeader Type
|
||||
highlight default link TSModuleInfoNamespace Statement
|
||||
highlight default link TSModuleInfoParser Identifier
|
||||
]], false)
|
||||
]],
|
||||
false
|
||||
)
|
||||
end
|
||||
|
||||
local function module_info(module)
|
||||
if module and not configs.get_module(module) then return end
|
||||
if module and not configs.get_module(module) then
|
||||
return
|
||||
end
|
||||
|
||||
local parserlist = parsers.available_parsers()
|
||||
if module then
|
||||
|
|
|
@ -2,16 +2,16 @@ local api = vim.api
|
|||
local fn = vim.fn
|
||||
local luv = vim.loop
|
||||
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local info = require'nvim-treesitter.info'
|
||||
local configs = require'nvim-treesitter.configs'
|
||||
local shell = require'nvim-treesitter.shell_command_selectors'
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local info = require "nvim-treesitter.info"
|
||||
local configs = require "nvim-treesitter.configs"
|
||||
local shell = require "nvim-treesitter.shell_command_selectors"
|
||||
|
||||
local M = {}
|
||||
local lockfile = {}
|
||||
|
||||
M.compilers = { vim.fn.getenv('CC'), "cc", "gcc", "clang", "cl" }
|
||||
M.compilers = { vim.fn.getenv "CC", "cc", "gcc", "clang", "cl" }
|
||||
|
||||
local started_commands = 0
|
||||
local finished_commands = 0
|
||||
|
@ -31,27 +31,31 @@ local function reset_progress_counter()
|
|||
end
|
||||
|
||||
local function get_job_status()
|
||||
return "[nvim-treesitter] ["..finished_commands.."/"..started_commands
|
||||
..(failed_commands > 0 and ", failed: "..failed_commands or "").."]"
|
||||
return "[nvim-treesitter] ["
|
||||
.. finished_commands
|
||||
.. "/"
|
||||
.. started_commands
|
||||
.. (failed_commands > 0 and ", failed: " .. failed_commands or "")
|
||||
.. "]"
|
||||
end
|
||||
|
||||
local function get_revision(lang)
|
||||
if #lockfile == 0 then
|
||||
local filename = utils.join_path(utils.get_package_path(), 'lockfile.json')
|
||||
local filename = utils.join_path(utils.get_package_path(), "lockfile.json")
|
||||
lockfile = vim.fn.filereadable(filename) == 1 and vim.fn.json_decode(vim.fn.readfile(filename)) or {}
|
||||
end
|
||||
return (lockfile[lang] and lockfile[lang].revision)
|
||||
end
|
||||
|
||||
local function get_installed_revision(lang)
|
||||
local lang_file = utils.join_path(utils.get_parser_info_dir(), lang..'.revision')
|
||||
local lang_file = utils.join_path(utils.get_parser_info_dir(), lang .. ".revision")
|
||||
if vim.fn.filereadable(lang_file) == 1 then
|
||||
return vim.fn.readfile(lang_file)[1]
|
||||
end
|
||||
end
|
||||
|
||||
local function is_installed(lang)
|
||||
return #api.nvim_get_runtime_file('parser/'..lang..'.so', false) > 0
|
||||
return #api.nvim_get_runtime_file("parser/" .. lang .. ".so", false) > 0
|
||||
end
|
||||
|
||||
local function needs_update(lang)
|
||||
|
@ -61,17 +65,16 @@ end
|
|||
local function outdated_parsers()
|
||||
return vim.tbl_filter(function(lang)
|
||||
return needs_update(lang)
|
||||
end,
|
||||
info.installed_parsers())
|
||||
end, info.installed_parsers())
|
||||
end
|
||||
|
||||
local function onread(handle, is_stderr)
|
||||
return function(err, data)
|
||||
if data then
|
||||
if is_stderr then
|
||||
complete_error_output[handle] = (complete_error_output[handle] or '')..data
|
||||
complete_error_output[handle] = (complete_error_output[handle] or "") .. data
|
||||
else
|
||||
complete_std_output[handle] = (complete_std_output[handle] or '')..data
|
||||
complete_std_output[handle] = (complete_std_output[handle] or "") .. data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -83,52 +86,62 @@ function M.iter_cmd(cmd_list, i, lang, success_message)
|
|||
end
|
||||
if i == #cmd_list + 1 then
|
||||
finished_commands = finished_commands + 1
|
||||
return print(get_job_status().." "..success_message)
|
||||
return print(get_job_status() .. " " .. success_message)
|
||||
end
|
||||
|
||||
local attr = cmd_list[i]
|
||||
if attr.info then print(get_job_status().." "..attr.info) end
|
||||
if attr.info then
|
||||
print(get_job_status() .. " " .. attr.info)
|
||||
end
|
||||
|
||||
if type(attr.cmd) == 'function' then
|
||||
if type(attr.cmd) == "function" then
|
||||
local ok, err = pcall(attr.cmd)
|
||||
if ok then
|
||||
M.iter_cmd(cmd_list, i + 1, lang, success_message)
|
||||
else
|
||||
failed_commands = failed_commands + 1
|
||||
finished_commands = finished_commands + 1
|
||||
return api.nvim_err_writeln((attr.err or ("Failed to execute the following command:\n"..vim.inspect(attr)))
|
||||
..'\n'..vim.inspect(err))
|
||||
return api.nvim_err_writeln(
|
||||
(attr.err or ("Failed to execute the following command:\n" .. vim.inspect(attr))) .. "\n" .. vim.inspect(err)
|
||||
)
|
||||
end
|
||||
else
|
||||
local handle
|
||||
local stdout = luv.new_pipe(false)
|
||||
local stderr = luv.new_pipe(false)
|
||||
attr.opts.stdio = {nil, stdout, stderr}
|
||||
handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code)
|
||||
if code ~= 0 then
|
||||
stdout:read_stop()
|
||||
stderr:read_stop()
|
||||
end
|
||||
stdout:close()
|
||||
stderr:close()
|
||||
handle:close()
|
||||
if code ~= 0 then
|
||||
failed_commands = failed_commands + 1
|
||||
finished_commands = finished_commands + 1
|
||||
if complete_std_output[handle] and complete_std_output[handle] ~= '' then
|
||||
print(complete_std_output[handle])
|
||||
attr.opts.stdio = { nil, stdout, stderr }
|
||||
handle = luv.spawn(
|
||||
attr.cmd,
|
||||
attr.opts,
|
||||
vim.schedule_wrap(function(code)
|
||||
if code ~= 0 then
|
||||
stdout:read_stop()
|
||||
stderr:read_stop()
|
||||
end
|
||||
stdout:close()
|
||||
stderr:close()
|
||||
handle:close()
|
||||
if code ~= 0 then
|
||||
failed_commands = failed_commands + 1
|
||||
finished_commands = finished_commands + 1
|
||||
if complete_std_output[handle] and complete_std_output[handle] ~= "" then
|
||||
print(complete_std_output[handle])
|
||||
end
|
||||
|
||||
local err_msg = complete_error_output[handle] or ''
|
||||
api.nvim_err_writeln(
|
||||
'nvim-treesitter['..lang..']: '
|
||||
..(attr.err or ("Failed to execute the following command:\n"..vim.inspect(attr)))
|
||||
..'\n'
|
||||
..err_msg)
|
||||
return
|
||||
end
|
||||
M.iter_cmd(cmd_list, i + 1, lang, success_message)
|
||||
end))
|
||||
local err_msg = complete_error_output[handle] or ""
|
||||
api.nvim_err_writeln(
|
||||
"nvim-treesitter["
|
||||
.. lang
|
||||
.. "]: "
|
||||
.. (attr.err or ("Failed to execute the following command:\n" .. vim.inspect(attr)))
|
||||
.. "\n"
|
||||
.. err_msg
|
||||
)
|
||||
return
|
||||
end
|
||||
M.iter_cmd(cmd_list, i + 1, lang, success_message)
|
||||
end)
|
||||
)
|
||||
luv.read_start(stdout, onread(handle, false))
|
||||
luv.read_start(stderr, onread(handle, true))
|
||||
end
|
||||
|
@ -142,7 +155,7 @@ local function get_command(cmd)
|
|||
end
|
||||
end
|
||||
|
||||
local final = string.format('%s %s', cmd.cmd, options)
|
||||
local final = string.format("%s %s", cmd.cmd, options)
|
||||
if cmd.opts and cmd.opts.cwd then
|
||||
final = shell.make_directory_change_for_command(cmd.opts.cwd, final)
|
||||
end
|
||||
|
@ -155,19 +168,18 @@ local function iter_cmd_sync(cmd_list)
|
|||
print(cmd.info)
|
||||
end
|
||||
|
||||
if type(cmd.cmd) == 'function' then
|
||||
if type(cmd.cmd) == "function" then
|
||||
cmd.cmd()
|
||||
else
|
||||
local ret = vim.fn.system(get_command(cmd))
|
||||
if vim.v.shell_error ~= 0 then
|
||||
print(ret)
|
||||
api.nvim_err_writeln((cmd.err and cmd.err..'\n' or '')
|
||||
.."Failed to execute the following command:\n"
|
||||
..vim.inspect(cmd))
|
||||
api.nvim_err_writeln(
|
||||
(cmd.err and cmd.err .. "\n" or "") .. "Failed to execute the following command:\n" .. vim.inspect(cmd)
|
||||
)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
|
@ -178,7 +190,7 @@ local function run_install(cache_folder, install_folder, lang, repo, with_sync,
|
|||
|
||||
local path_sep = utils.get_path_sep()
|
||||
|
||||
local project_name = 'tree-sitter-'..lang
|
||||
local project_name = "tree-sitter-" .. lang
|
||||
local maybe_local_path = vim.fn.expand(repo.url)
|
||||
local from_local_path = vim.fn.isdirectory(maybe_local_path) == 1
|
||||
if from_local_path then
|
||||
|
@ -190,33 +202,40 @@ local function run_install(cache_folder, install_folder, lang, repo, with_sync,
|
|||
if from_local_path then
|
||||
compile_location = repo.url
|
||||
else
|
||||
local repo_location = string.gsub(repo.location or project_name, '/', path_sep)
|
||||
compile_location = cache_folder..path_sep..repo_location
|
||||
local repo_location = string.gsub(repo.location or project_name, "/", path_sep)
|
||||
compile_location = cache_folder .. path_sep .. repo_location
|
||||
end
|
||||
local parser_lib_name = install_folder..path_sep..lang..".so"
|
||||
local parser_lib_name = install_folder .. path_sep .. lang .. ".so"
|
||||
|
||||
generate_from_grammar = repo.requires_generate_from_grammar or generate_from_grammar
|
||||
|
||||
if generate_from_grammar and vim.fn.executable('tree-sitter') ~= 1 then
|
||||
api.nvim_err_writeln('tree-sitter CLI not found: `tree-sitter` is not executable!')
|
||||
if generate_from_grammar and vim.fn.executable "tree-sitter" ~= 1 then
|
||||
api.nvim_err_writeln "tree-sitter CLI not found: `tree-sitter` is not executable!"
|
||||
if repo.requires_generate_from_grammar then
|
||||
api.nvim_err_writeln('tree-sitter CLI is needed because `'..lang..'` is marked that it needs '
|
||||
..'to be generated from the grammar definitions to be compatible with nvim!')
|
||||
api.nvim_err_writeln(
|
||||
"tree-sitter CLI is needed because `"
|
||||
.. lang
|
||||
.. "` is marked that it needs "
|
||||
.. "to be generated from the grammar definitions to be compatible with nvim!"
|
||||
)
|
||||
end
|
||||
return
|
||||
end
|
||||
if generate_from_grammar and vim.fn.executable('node') ~= 1 then
|
||||
api.nvim_err_writeln('Node JS not found: `node` is not executable!')
|
||||
if generate_from_grammar and vim.fn.executable "node" ~= 1 then
|
||||
api.nvim_err_writeln "Node JS not found: `node` is not executable!"
|
||||
return
|
||||
end
|
||||
local cc = shell.select_executable(M.compilers)
|
||||
if not cc then
|
||||
api.nvim_err_writeln('No C compiler found! "'
|
||||
..table.concat(vim.tbl_filter(function(c) return type(c) == 'string' end, M.compilers), '", "')
|
||||
..'" are not executable.')
|
||||
api.nvim_err_writeln('No C compiler found! "' .. table.concat(
|
||||
vim.tbl_filter(function(c)
|
||||
return type(c) == "string"
|
||||
end, M.compilers),
|
||||
'", "'
|
||||
) .. '" are not executable.')
|
||||
return
|
||||
end
|
||||
local revision = configs.get_update_strategy() == 'lockfile' and get_revision(lang)
|
||||
local revision = configs.get_update_strategy() == "lockfile" and get_revision(lang)
|
||||
|
||||
local command_list = {}
|
||||
if not from_local_path then
|
||||
|
@ -225,83 +244,86 @@ local function run_install(cache_folder, install_folder, lang, repo, with_sync,
|
|||
end
|
||||
if generate_from_grammar then
|
||||
if repo.generate_requires_npm then
|
||||
if vim.fn.executable('npm') ~= 1 then
|
||||
api.nvim_err_writeln('`'..lang..'` requires NPM to be installed from grammar.js')
|
||||
if vim.fn.executable "npm" ~= 1 then
|
||||
api.nvim_err_writeln("`" .. lang .. "` requires NPM to be installed from grammar.js")
|
||||
return
|
||||
end
|
||||
vim.list_extend(command_list, {
|
||||
{
|
||||
cmd = 'npm',
|
||||
info = 'Installing NPM dependencies of '..lang..' parser',
|
||||
err = 'Error during `npm install` (required for parser generation of '..lang..' with npm dependencies)',
|
||||
cmd = "npm",
|
||||
info = "Installing NPM dependencies of " .. lang .. " parser",
|
||||
err = "Error during `npm install` (required for parser generation of " .. lang .. " with npm dependencies)",
|
||||
opts = {
|
||||
args = {'install'},
|
||||
cwd = compile_location
|
||||
}
|
||||
}
|
||||
args = { "install" },
|
||||
cwd = compile_location,
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
vim.list_extend(command_list, {
|
||||
{
|
||||
cmd = vim.fn.exepath('tree-sitter'),
|
||||
info = 'Generating source files from grammar.js...',
|
||||
cmd = vim.fn.exepath "tree-sitter",
|
||||
info = "Generating source files from grammar.js...",
|
||||
err = 'Error during "tree-sitter generate"',
|
||||
opts = {
|
||||
args = {'generate'},
|
||||
cwd = compile_location
|
||||
}
|
||||
}
|
||||
args = { "generate" },
|
||||
cwd = compile_location,
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
vim.list_extend(command_list, {
|
||||
{
|
||||
cmd = cc,
|
||||
info = 'Compiling...',
|
||||
err = 'Error during compilation',
|
||||
info = "Compiling...",
|
||||
err = "Error during compilation",
|
||||
opts = {
|
||||
args = vim.tbl_flatten(shell.select_compiler_args(repo, cc)),
|
||||
cwd = compile_location
|
||||
}
|
||||
cwd = compile_location,
|
||||
},
|
||||
},
|
||||
shell.select_mv_cmd('parser.so', parser_lib_name, compile_location),
|
||||
shell.select_mv_cmd("parser.so", parser_lib_name, compile_location),
|
||||
{
|
||||
cmd = function()
|
||||
vim.fn.writefile({revision or ''}, utils.join_path(utils.get_parser_info_dir(), lang..'.revision'))
|
||||
end
|
||||
}
|
||||
vim.fn.writefile({ revision or "" }, utils.join_path(utils.get_parser_info_dir(), lang .. ".revision"))
|
||||
end,
|
||||
},
|
||||
})
|
||||
if not from_local_path then
|
||||
vim.list_extend(command_list, {shell.select_install_rm_cmd(cache_folder, project_name)})
|
||||
vim.list_extend(command_list, { shell.select_install_rm_cmd(cache_folder, project_name) })
|
||||
end
|
||||
|
||||
if with_sync then
|
||||
if iter_cmd_sync(command_list) == true then
|
||||
print('Treesitter parser for '..lang..' has been installed')
|
||||
print("Treesitter parser for " .. lang .. " has been installed")
|
||||
end
|
||||
else
|
||||
M.iter_cmd(command_list, 1, lang, 'Treesitter parser for '..lang..' has been installed')
|
||||
M.iter_cmd(command_list, 1, lang, "Treesitter parser for " .. lang .. " has been installed")
|
||||
end
|
||||
end
|
||||
|
||||
local function install_lang(lang, ask_reinstall, cache_folder, install_folder, with_sync, generate_from_grammar)
|
||||
if is_installed(lang) and ask_reinstall ~= "force" then
|
||||
if not ask_reinstall then
|
||||
return
|
||||
end
|
||||
|
||||
if is_installed(lang) and ask_reinstall ~= 'force' then
|
||||
if not ask_reinstall then return end
|
||||
|
||||
local yesno = fn.input(lang .. ' parser already available: would you like to reinstall ? y/n: ')
|
||||
print('\n ') -- mandatory to avoid messing up command line
|
||||
if not string.match(yesno, '^y.*') then return end
|
||||
local yesno = fn.input(lang .. " parser already available: would you like to reinstall ? y/n: ")
|
||||
print "\n "
|
||||
if not string.match(yesno, "^y.*") then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local parser_config = parsers.get_parser_configs()[lang]
|
||||
if not parser_config then
|
||||
return api.nvim_err_writeln('Parser not available for language '..lang)
|
||||
return api.nvim_err_writeln("Parser not available for language " .. lang)
|
||||
end
|
||||
|
||||
local install_info = parser_config.install_info
|
||||
vim.validate {
|
||||
url={ install_info.url, 'string' },
|
||||
files={ install_info.files, 'table' }
|
||||
url = { install_info.url, "string" },
|
||||
files = { install_info.files, "table" },
|
||||
}
|
||||
|
||||
run_install(cache_folder, install_folder, lang, install_info, with_sync, generate_from_grammar)
|
||||
|
@ -314,27 +336,31 @@ local function install(options)
|
|||
local generate_from_grammar = options.generate_from_grammar
|
||||
local exclude_configured_parsers = options.exclude_configured_parsers
|
||||
|
||||
return function (...)
|
||||
if fn.executable('git') == 0 then
|
||||
return api.nvim_err_writeln('Git is required on your system to run this command')
|
||||
return function(...)
|
||||
if fn.executable "git" == 0 then
|
||||
return api.nvim_err_writeln "Git is required on your system to run this command"
|
||||
end
|
||||
|
||||
local cache_folder, err = utils.get_cache_dir()
|
||||
if err then return api.nvim_err_writeln(err) end
|
||||
if err then
|
||||
return api.nvim_err_writeln(err)
|
||||
end
|
||||
|
||||
local install_folder, err = utils.get_parser_install_dir()
|
||||
if err then return api.nvim_err_writeln(err) end
|
||||
if err then
|
||||
return api.nvim_err_writeln(err)
|
||||
end
|
||||
|
||||
local languages
|
||||
local ask
|
||||
if ... == 'all' then
|
||||
if ... == "all" then
|
||||
languages = parsers.available_parsers()
|
||||
ask = false
|
||||
elseif ... == 'maintained' then
|
||||
elseif ... == "maintained" then
|
||||
languages = parsers.maintained_parsers()
|
||||
ask = false
|
||||
else
|
||||
languages = vim.tbl_flatten({...})
|
||||
languages = vim.tbl_flatten { ... }
|
||||
ask = ask_reinstall
|
||||
end
|
||||
|
||||
|
@ -354,69 +380,73 @@ end
|
|||
|
||||
function M.update(options)
|
||||
options = options or {}
|
||||
return function (...)
|
||||
return function(...)
|
||||
M.lockfile = {}
|
||||
reset_progress_counter()
|
||||
if ... and ... ~= 'all' then
|
||||
local languages = vim.tbl_flatten({...})
|
||||
if ... and ... ~= "all" then
|
||||
local languages = vim.tbl_flatten { ... }
|
||||
local installed = 0
|
||||
for _, lang in ipairs(languages) do
|
||||
if (not is_installed(lang)) or (needs_update(lang)) then
|
||||
installed = installed + 1
|
||||
install({
|
||||
ask_reinstall = 'force',
|
||||
with_sync = options.with_sync })(lang)
|
||||
end
|
||||
if (not is_installed(lang)) or (needs_update(lang)) then
|
||||
installed = installed + 1
|
||||
install {
|
||||
ask_reinstall = "force",
|
||||
with_sync = options.with_sync,
|
||||
}(lang)
|
||||
end
|
||||
end
|
||||
if installed == 0 then
|
||||
print('Parsers are up-to-date!')
|
||||
print "Parsers are up-to-date!"
|
||||
end
|
||||
else
|
||||
local parsers_to_update = configs.get_update_strategy() == 'lockfile'
|
||||
and outdated_parsers()
|
||||
local parsers_to_update = configs.get_update_strategy() == "lockfile" and outdated_parsers()
|
||||
or info.installed_parsers()
|
||||
if #parsers_to_update == 0 then
|
||||
print('All parsers are up-to-date!')
|
||||
print "All parsers are up-to-date!"
|
||||
end
|
||||
for _, lang in pairs(parsers_to_update) do
|
||||
install({
|
||||
ask_reinstall = 'force',
|
||||
install {
|
||||
ask_reinstall = "force",
|
||||
exclude_configured_parsers = true,
|
||||
with_sync = options.with_sync
|
||||
})(lang)
|
||||
with_sync = options.with_sync,
|
||||
}(lang)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.uninstall(...)
|
||||
local path_sep = '/'
|
||||
if fn.has('win32') == 1 then
|
||||
path_sep = '\\'
|
||||
local path_sep = "/"
|
||||
if fn.has "win32" == 1 then
|
||||
path_sep = "\\"
|
||||
end
|
||||
|
||||
if vim.tbl_contains({'all', 'maintained'}, ...) then
|
||||
if vim.tbl_contains({ "all", "maintained" }, ...) then
|
||||
reset_progress_counter()
|
||||
local installed = info.installed_parsers()
|
||||
if ... == "maintained" then
|
||||
local maintained = parsers.maintained_parsers()
|
||||
installed = vim.tbl_filter(function(l) return vim.tbl_contains(maintained, l) end, installed)
|
||||
installed = vim.tbl_filter(function(l)
|
||||
return vim.tbl_contains(maintained, l)
|
||||
end, installed)
|
||||
end
|
||||
for _, langitem in pairs(installed) do
|
||||
M.uninstall(langitem)
|
||||
end
|
||||
elseif ... then
|
||||
local languages = vim.tbl_flatten({...})
|
||||
local languages = vim.tbl_flatten { ... }
|
||||
for _, lang in ipairs(languages) do
|
||||
local install_dir, err = utils.get_parser_install_dir()
|
||||
if err then return api.nvim_err_writeln(err) end
|
||||
if err then
|
||||
return api.nvim_err_writeln(err)
|
||||
end
|
||||
|
||||
local parser_lib = install_dir..path_sep..lang..".so"
|
||||
local parser_lib = install_dir .. path_sep .. lang .. ".so"
|
||||
|
||||
local command_list = {
|
||||
shell.select_rm_file_cmd(parser_lib, "Uninstalling parser for "..lang)
|
||||
shell.select_rm_file_cmd(parser_lib, "Uninstalling parser for " .. lang),
|
||||
}
|
||||
M.iter_cmd(command_list, 1, lang, 'Treesitter parser for '..lang..' has been uninstalled')
|
||||
M.iter_cmd(command_list, 1, lang, "Treesitter parser for " .. lang .. " has been uninstalled")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -428,38 +458,41 @@ function M.write_lockfile(verbose, skip_langs)
|
|||
skip_langs = skip_langs or {}
|
||||
|
||||
for k, v in pairs(parsers.get_parser_configs()) do
|
||||
table.insert(sorted_parsers, {name = k, parser = v})
|
||||
table.insert(sorted_parsers, { name = k, parser = v })
|
||||
end
|
||||
|
||||
table.sort(sorted_parsers, function(a, b) return a.name < b.name end)
|
||||
table.sort(sorted_parsers, function(a, b)
|
||||
return a.name < b.name
|
||||
end)
|
||||
|
||||
for _, v in ipairs(sorted_parsers) do
|
||||
|
||||
if not vim.tbl_contains(skip_langs, v.name) then
|
||||
-- I'm sure this can be done in aync way with iter_cmd
|
||||
local sha = vim.split(vim.fn.systemlist('git ls-remote '..v.parser.install_info.url)[1], '\t')[1]
|
||||
local sha = vim.split(vim.fn.systemlist("git ls-remote " .. v.parser.install_info.url)[1], "\t")[1]
|
||||
lockfile[v.name] = { revision = sha }
|
||||
if verbose then
|
||||
print(v.name..': '..sha)
|
||||
print(v.name .. ": " .. sha)
|
||||
end
|
||||
else
|
||||
print('Skipping '..v.name)
|
||||
print("Skipping " .. v.name)
|
||||
end
|
||||
end
|
||||
|
||||
if verbose then
|
||||
print(vim.inspect(lockfile))
|
||||
end
|
||||
vim.fn.writefile(vim.fn.split(vim.fn.json_encode(lockfile), '\n'),
|
||||
utils.join_path(utils.get_package_path(), "lockfile.json"))
|
||||
vim.fn.writefile(
|
||||
vim.fn.split(vim.fn.json_encode(lockfile), "\n"),
|
||||
utils.join_path(utils.get_package_path(), "lockfile.json")
|
||||
)
|
||||
end
|
||||
|
||||
M.ensure_installed = install({ exclude_configured_parsers = true })
|
||||
M.ensure_installed = install { exclude_configured_parsers = true }
|
||||
|
||||
M.commands = {
|
||||
TSInstall = {
|
||||
run = install({ ask_reinstall = true }),
|
||||
['run!'] = install({ ask_reinstall = 'force' }),
|
||||
run = install { ask_reinstall = true },
|
||||
["run!"] = install { ask_reinstall = "force" },
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-bang",
|
||||
|
@ -467,8 +500,8 @@ M.commands = {
|
|||
},
|
||||
},
|
||||
TSInstallFromGrammar = {
|
||||
run = install({ generate_from_grammar = true, ask_reinstall = true }),
|
||||
['run!'] = install({ generate_from_grammar = true, ask_reinstall = 'force' }),
|
||||
run = install { generate_from_grammar = true, ask_reinstall = true },
|
||||
["run!"] = install { generate_from_grammar = true, ask_reinstall = "force" },
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-bang",
|
||||
|
@ -476,8 +509,8 @@ M.commands = {
|
|||
},
|
||||
},
|
||||
TSInstallSync = {
|
||||
run = install( { with_sync = true, ask_reinstall = true }),
|
||||
['run!'] = install( { with_sync = true, ask_reinstall = 'force' }),
|
||||
run = install { with_sync = true, ask_reinstall = true },
|
||||
["run!"] = install { with_sync = true, ask_reinstall = "force" },
|
||||
args = {
|
||||
"-nargs=+",
|
||||
"-bang",
|
||||
|
@ -485,14 +518,14 @@ M.commands = {
|
|||
},
|
||||
},
|
||||
TSUpdate = {
|
||||
run = M.update({}),
|
||||
run = M.update {},
|
||||
args = {
|
||||
"-nargs=*",
|
||||
"-complete=custom,nvim_treesitter#installed_parsers",
|
||||
},
|
||||
},
|
||||
TSUpdateSync = {
|
||||
run = M.update({ with_sync = true }),
|
||||
run = M.update { with_sync = true },
|
||||
args = {
|
||||
"-nargs=*",
|
||||
"-complete=custom,nvim_treesitter#installed_parsers",
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
-- Locals are a generalization of definition and scopes
|
||||
-- its the way nvim-treesitter uses to "understand" the code
|
||||
|
||||
local queries = require'nvim-treesitter.query'
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.collect_locals(bufnr)
|
||||
return queries.collect_group_results(bufnr, 'locals')
|
||||
return queries.collect_group_results(bufnr, "locals")
|
||||
end
|
||||
|
||||
-- Iterates matches from a locals query file.
|
||||
-- @param bufnr the buffer
|
||||
-- @param root the root node
|
||||
function M.iter_locals(bufnr, root)
|
||||
return queries.iter_group_results(bufnr, 'locals', root)
|
||||
return queries.iter_group_results(bufnr, "locals", root)
|
||||
end
|
||||
|
||||
function M.get_locals(bufnr)
|
||||
return queries.get_matches(bufnr, 'locals')
|
||||
return queries.get_matches(bufnr, "locals")
|
||||
end
|
||||
|
||||
--- Creates unique id for a node based on text and range
|
||||
|
@ -30,7 +30,7 @@ end
|
|||
-- @returns a string id
|
||||
function M.get_definition_id(scope, node_text)
|
||||
-- Add a vaild starting character in case node text doesn't start with a valid one.
|
||||
return table.concat({ 'k', node_text or '', scope:range() }, '_')
|
||||
return table.concat({ "k", node_text or "", scope:range() }, "_")
|
||||
end
|
||||
|
||||
function M.get_definitions(bufnr)
|
||||
|
@ -131,11 +131,7 @@ function M.recurse_local_nodes(local_def, accumulator, full_match, last_match)
|
|||
accumulator(local_def, local_def.node, full_match, last_match)
|
||||
else
|
||||
for match_key, def in pairs(local_def) do
|
||||
M.recurse_local_nodes(
|
||||
def,
|
||||
accumulator,
|
||||
full_match and (full_match..'.'..match_key) or match_key,
|
||||
match_key)
|
||||
M.recurse_local_nodes(def, accumulator, full_match and (full_match .. "." .. match_key) or match_key, match_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -188,10 +184,10 @@ function M.get_definition_scopes(node, bufnr, scope_type)
|
|||
|
||||
-- Definition is valid for the containing scope
|
||||
-- and the containing scope of that scope
|
||||
if scope_type == 'parent' then
|
||||
if scope_type == "parent" then
|
||||
scope_count = 2
|
||||
-- Definition is valid in all parent scopes
|
||||
elseif scope_type == 'global' then
|
||||
elseif scope_type == "global" then
|
||||
scope_count = nil
|
||||
end
|
||||
|
||||
|
@ -200,7 +196,9 @@ function M.get_definition_scopes(node, bufnr, scope_type)
|
|||
table.insert(scopes, scope)
|
||||
i = i + 1
|
||||
|
||||
if scope_count and i >= scope_count then break end
|
||||
if scope_count and i >= scope_count then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return scopes
|
||||
|
@ -231,13 +229,16 @@ function M.find_usages(node, scope_node, bufnr)
|
|||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local node_text = ts_utils.get_node_text(node, bufnr)[1]
|
||||
|
||||
if not node_text or #node_text < 1 then return {} end
|
||||
if not node_text or #node_text < 1 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local scope_node = scope_node or ts_utils.get_root_for_node(node)
|
||||
local usages = {}
|
||||
|
||||
for match in M.iter_locals(bufnr, scope_node) do
|
||||
if match.reference
|
||||
if
|
||||
match.reference
|
||||
and match.reference.node
|
||||
and ts_utils.get_node_text(match.reference.node, bufnr)[1] == node_text
|
||||
then
|
||||
|
@ -257,7 +258,9 @@ function M.containing_scope(node, bufnr, allow_scope)
|
|||
local allow_scope = allow_scope == nil or allow_scope == true
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then return end
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local iter_node = node
|
||||
|
||||
|
@ -272,7 +275,9 @@ function M.nested_scope(node, cursor_pos)
|
|||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then return end
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local row = cursor_pos.row
|
||||
local col = cursor_pos.col
|
||||
|
@ -280,7 +285,7 @@ function M.nested_scope(node, cursor_pos)
|
|||
|
||||
for _, child in ipairs(ts_utils.get_named_children(scope)) do
|
||||
local row_, col_ = child:start()
|
||||
if vim.tbl_contains(scopes, child) and ((row_+1 == row and col_ > col) or row_+1 > row) then
|
||||
if vim.tbl_contains(scopes, child) and ((row_ + 1 == row and col_ > col) or row_ + 1 > row) then
|
||||
return child
|
||||
end
|
||||
end
|
||||
|
@ -290,12 +295,16 @@ function M.next_scope(node)
|
|||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then return end
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local scope = M.containing_scope(node)
|
||||
|
||||
local parent = scope:parent()
|
||||
if not parent then return end
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
|
||||
local is_prev = true
|
||||
for _, child in ipairs(ts_utils.get_named_children(parent)) do
|
||||
|
@ -311,16 +320,20 @@ function M.previous_scope(node)
|
|||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
local scopes = M.get_scopes(bufnr)
|
||||
if not node or not scopes then return end
|
||||
if not node or not scopes then
|
||||
return
|
||||
end
|
||||
|
||||
local scope = M.containing_scope(node)
|
||||
|
||||
local parent = scope:parent()
|
||||
if not parent then return end
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
|
||||
local is_prev = true
|
||||
local children = ts_utils.get_named_children(parent)
|
||||
for i=#children,1,-1 do
|
||||
for i = #children, 1, -1 do
|
||||
if children[i] == scope then
|
||||
is_prev = false
|
||||
elseif not is_prev and vim.tbl_contains(scopes, children[i]) then
|
||||
|
|
|
@ -4,7 +4,7 @@ local ts = vim.treesitter
|
|||
local ft_to_parsername = {}
|
||||
|
||||
local function update_ft_to_parsername(name, parser)
|
||||
if type(parser.used_by) == 'table' then
|
||||
if type(parser.used_by) == "table" then
|
||||
for _, ft in pairs(parser.used_by) do
|
||||
ft_to_parsername[ft] = name
|
||||
end
|
||||
|
@ -14,19 +14,22 @@ end
|
|||
|
||||
local list = setmetatable({}, {
|
||||
__newindex = function(table, parsername, parserconfig)
|
||||
|
||||
rawset(table, parsername, setmetatable(parserconfig, {
|
||||
__newindex = function(parserconfigtable, key, value)
|
||||
if key == "used_by" then
|
||||
ft_to_parsername[value] = parsername
|
||||
else
|
||||
rawset(parserconfigtable, key, value)
|
||||
end
|
||||
end
|
||||
}))
|
||||
rawset(
|
||||
table,
|
||||
parsername,
|
||||
setmetatable(parserconfig, {
|
||||
__newindex = function(parserconfigtable, key, value)
|
||||
if key == "used_by" then
|
||||
ft_to_parsername[value] = parsername
|
||||
else
|
||||
rawset(parserconfigtable, key, value)
|
||||
end
|
||||
end,
|
||||
})
|
||||
)
|
||||
|
||||
update_ft_to_parsername(parsername, parserconfig)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
list.javascript = {
|
||||
|
@ -34,16 +37,16 @@ list.javascript = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
used_by = { 'javascriptreact' },
|
||||
maintainers = {"@steelsojka"},
|
||||
used_by = { "javascriptreact" },
|
||||
maintainers = { "@steelsojka" },
|
||||
}
|
||||
|
||||
list.c = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-c",
|
||||
files = { "src/parser.c" }
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@vigoux"},
|
||||
maintainers = { "@vigoux" },
|
||||
}
|
||||
|
||||
list.clojure = {
|
||||
|
@ -51,7 +54,7 @@ list.clojure = {
|
|||
url = "https://github.com/sogaiu/tree-sitter-clojure",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@sogaiu"},
|
||||
maintainers = { "@sogaiu" },
|
||||
}
|
||||
|
||||
list.commonlisp = {
|
||||
|
@ -60,8 +63,8 @@ list.commonlisp = {
|
|||
files = { "src/parser.c" },
|
||||
generate_requires_npm = true,
|
||||
},
|
||||
filetype = 'lisp',
|
||||
maintainers = {"@theHamsta"},
|
||||
filetype = "lisp",
|
||||
maintainers = { "@theHamsta" },
|
||||
}
|
||||
|
||||
list.cpp = {
|
||||
|
@ -70,16 +73,16 @@ list.cpp = {
|
|||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
generate_requires_npm = true,
|
||||
},
|
||||
maintainers = {"@theHamsta"},
|
||||
maintainers = { "@theHamsta" },
|
||||
}
|
||||
|
||||
list.cuda = {
|
||||
install_info = {
|
||||
url = "https://github.com/theHamsta/tree-sitter-cuda",
|
||||
files = {"src/parser.c", "src/scanner.cc"},
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
generate_requires_npm = true,
|
||||
},
|
||||
maintainers = {"@theHamsta"},
|
||||
maintainers = { "@theHamsta" },
|
||||
}
|
||||
|
||||
list.dockerfile = {
|
||||
|
@ -88,7 +91,7 @@ list.dockerfile = {
|
|||
branch = "main",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@camdencheek"},
|
||||
maintainers = { "@camdencheek" },
|
||||
}
|
||||
|
||||
list.rust = {
|
||||
|
@ -96,7 +99,7 @@ list.rust = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@vigoux"},
|
||||
maintainers = { "@vigoux" },
|
||||
}
|
||||
|
||||
list.ledger = {
|
||||
|
@ -104,15 +107,15 @@ list.ledger = {
|
|||
url = "https://github.com/cbarrete/tree-sitter-ledger",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@cbarrete"},
|
||||
maintainers = { "@cbarrete" },
|
||||
}
|
||||
|
||||
list.lua = {
|
||||
install_info = {
|
||||
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
||||
files = { "src/parser.c", "src/scanner.cc" }
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = {"@vigoux"},
|
||||
maintainers = { "@vigoux" },
|
||||
}
|
||||
|
||||
list.python = {
|
||||
|
@ -120,7 +123,7 @@ list.python = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-python",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = {'@stsewd', "@theHamsta"},
|
||||
maintainers = { "@stsewd", "@theHamsta" },
|
||||
}
|
||||
|
||||
list.go = {
|
||||
|
@ -128,7 +131,7 @@ list.go = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-go",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@theHamsta", "@WinWisely268"},
|
||||
maintainers = { "@theHamsta", "@WinWisely268" },
|
||||
}
|
||||
|
||||
list.gomod = {
|
||||
|
@ -137,7 +140,7 @@ list.gomod = {
|
|||
branch = "main",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@camdencheek"},
|
||||
maintainers = { "@camdencheek" },
|
||||
filetype = "gomod",
|
||||
}
|
||||
|
||||
|
@ -146,7 +149,7 @@ list.graphql = {
|
|||
url = "https://github.com/bkegley/tree-sitter-graphql",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@bkegley"},
|
||||
maintainers = { "@bkegley" },
|
||||
}
|
||||
|
||||
list.ruby = {
|
||||
|
@ -154,7 +157,7 @@ list.ruby = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = {'@TravonteD'},
|
||||
maintainers = { "@TravonteD" },
|
||||
}
|
||||
|
||||
list.bash = {
|
||||
|
@ -163,8 +166,8 @@ list.bash = {
|
|||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
used_by = { "zsh", "PKGBUILD" },
|
||||
filetype = 'sh',
|
||||
maintainers = {"@TravonteD"},
|
||||
filetype = "sh",
|
||||
maintainers = { "@TravonteD" },
|
||||
}
|
||||
|
||||
list.fish = {
|
||||
|
@ -172,7 +175,7 @@ list.fish = {
|
|||
url = "https://github.com/krnik/tree-sitter-fish",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@krnik", "@ram02z"},
|
||||
maintainers = { "@krnik", "@ram02z" },
|
||||
}
|
||||
|
||||
list.php = {
|
||||
|
@ -180,7 +183,7 @@ list.php = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-php",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = {"@tk-shirasaka"},
|
||||
maintainers = { "@tk-shirasaka" },
|
||||
}
|
||||
|
||||
list.java = {
|
||||
|
@ -188,7 +191,7 @@ list.java = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-java",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@p00f"},
|
||||
maintainers = { "@p00f" },
|
||||
}
|
||||
|
||||
list.kotlin = {
|
||||
|
@ -196,7 +199,7 @@ list.kotlin = {
|
|||
url = "https://github.com/tormodatt/tree-sitter-kotlin",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@tormodatt"},
|
||||
maintainers = { "@tormodatt" },
|
||||
}
|
||||
|
||||
list.html = {
|
||||
|
@ -204,7 +207,7 @@ list.html = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-html",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = {"@TravonteD"},
|
||||
maintainers = { "@TravonteD" },
|
||||
}
|
||||
|
||||
list.julia = {
|
||||
|
@ -212,7 +215,7 @@ list.julia = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@mroavi", "@theHamsta"},
|
||||
maintainers = { "@mroavi", "@theHamsta" },
|
||||
}
|
||||
|
||||
list.json = {
|
||||
|
@ -220,7 +223,7 @@ list.json = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-json",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@steelsojka"},
|
||||
maintainers = { "@steelsojka" },
|
||||
}
|
||||
|
||||
list.css = {
|
||||
|
@ -228,15 +231,15 @@ list.css = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-css",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@TravonteD"},
|
||||
maintainers = { "@TravonteD" },
|
||||
}
|
||||
|
||||
list.scss = {
|
||||
install_info = {
|
||||
url = "https://github.com/serenadeai/tree-sitter-scss",
|
||||
files = { "src/parser.c", "src/scanner.c" }
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@elianiva"},
|
||||
maintainers = { "@elianiva" },
|
||||
}
|
||||
|
||||
list.erlang = {
|
||||
|
@ -245,16 +248,16 @@ list.erlang = {
|
|||
files = { "src/parser.c" },
|
||||
branch = "main",
|
||||
},
|
||||
maintainers = { '@ostera' },
|
||||
maintainers = { "@ostera" },
|
||||
}
|
||||
|
||||
list.elixir = {
|
||||
install_info = {
|
||||
url = "https://github.com/ananthakumaran/tree-sitter-elixir",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
requires_generate_from_grammar = true,
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
requires_generate_from_grammar = true,
|
||||
},
|
||||
maintainers = { '@nifoc' },
|
||||
maintainers = { "@nifoc" },
|
||||
}
|
||||
|
||||
list.ocaml = {
|
||||
|
@ -263,7 +266,7 @@ list.ocaml = {
|
|||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
location = "tree-sitter-ocaml/ocaml",
|
||||
},
|
||||
maintainers = {'@undu'},
|
||||
maintainers = { "@undu" },
|
||||
}
|
||||
|
||||
list.ocaml_interface = {
|
||||
|
@ -272,25 +275,25 @@ list.ocaml_interface = {
|
|||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
location = "tree-sitter-ocaml_interface/interface",
|
||||
},
|
||||
maintainers = {'@undu'},
|
||||
filetype = 'ocamlinterface'
|
||||
maintainers = { "@undu" },
|
||||
filetype = "ocamlinterface",
|
||||
}
|
||||
|
||||
list.ocamllex = {
|
||||
install_info = {
|
||||
url = "https://github.com/atom-ocaml/tree-sitter-ocamllex",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
requires_generate_from_grammar = true,
|
||||
requires_generate_from_grammar = true,
|
||||
},
|
||||
maintainers = {'@undu'},
|
||||
maintainers = { "@undu" },
|
||||
}
|
||||
|
||||
list.swift = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
||||
files = { "src/parser.c" },
|
||||
requires_generate_from_grammar = true,
|
||||
}
|
||||
requires_generate_from_grammar = true,
|
||||
},
|
||||
}
|
||||
|
||||
list.c_sharp = {
|
||||
|
@ -298,8 +301,8 @@ list.c_sharp = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
filetype = 'cs',
|
||||
maintainers = {'@Luxed'},
|
||||
filetype = "cs",
|
||||
maintainers = { "@Luxed" },
|
||||
}
|
||||
|
||||
list.typescript = {
|
||||
|
@ -309,7 +312,7 @@ list.typescript = {
|
|||
location = "tree-sitter-typescript/typescript",
|
||||
generate_requires_npm = true,
|
||||
},
|
||||
maintainers = {"@steelsojka"},
|
||||
maintainers = { "@steelsojka" },
|
||||
}
|
||||
|
||||
list.tsx = {
|
||||
|
@ -320,24 +323,24 @@ list.tsx = {
|
|||
generate_requires_npm = true,
|
||||
},
|
||||
used_by = { "typescript.tsx" },
|
||||
filetype = 'typescriptreact',
|
||||
maintainers = {'@steelsojka'}
|
||||
filetype = "typescriptreact",
|
||||
maintainers = { "@steelsojka" },
|
||||
}
|
||||
|
||||
list.scala = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-scala",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
list.supercollider = {
|
||||
install_info = {
|
||||
url = "https://github.com/madskjeldgaard/tree-sitter-supercollider",
|
||||
files = {"src/parser.c", "src/scanner.c"},
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
branch = "main",
|
||||
},
|
||||
maintainers = {"@madskjeldgaard"},
|
||||
maintainers = { "@madskjeldgaard" },
|
||||
filetype = "supercollider",
|
||||
}
|
||||
|
||||
|
@ -345,16 +348,16 @@ list.haskell = {
|
|||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-haskell",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
list.hcl = {
|
||||
install_info = {
|
||||
url = "https://github.com/MichaHoffmann/tree-sitter-hcl",
|
||||
files = {"src/parser.c", "src/scanner.cc"},
|
||||
branch = "main"
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
branch = "main",
|
||||
},
|
||||
maintainers = {"@MichaHoffmann"},
|
||||
maintainers = { "@MichaHoffmann" },
|
||||
filetype = "hcl",
|
||||
used_by = { "terraform", "packer", "nomad" },
|
||||
}
|
||||
|
@ -373,18 +376,18 @@ list.toml = {
|
|||
files = { "src/parser.c", "src/scanner.c" },
|
||||
generate_requires_npm = true,
|
||||
},
|
||||
maintainers = {"@tk-shirasaka"},
|
||||
maintainers = { "@tk-shirasaka" },
|
||||
}
|
||||
|
||||
list.glimmer = {
|
||||
install_info = {
|
||||
url = "https://github.com/alexlafroscia/tree-sitter-glimmer",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
branch = 'main',
|
||||
branch = "main",
|
||||
},
|
||||
readme_name = "Glimmer and Ember",
|
||||
maintainers = { "@alexlafroscia" },
|
||||
filetype = "handlebars"
|
||||
filetype = "handlebars",
|
||||
}
|
||||
|
||||
list.vue = {
|
||||
|
@ -392,7 +395,7 @@ list.vue = {
|
|||
url = "https://github.com/ikatyang/tree-sitter-vue",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = {"@WhyNotHugo"},
|
||||
maintainers = { "@WhyNotHugo" },
|
||||
}
|
||||
|
||||
list.jsonc = {
|
||||
|
@ -402,14 +405,14 @@ list.jsonc = {
|
|||
generate_requires_npm = true,
|
||||
},
|
||||
readme_name = "JSON with comments",
|
||||
maintainers = {"@WhyNotHugo"},
|
||||
maintainers = { "@WhyNotHugo" },
|
||||
}
|
||||
|
||||
list.elm = {
|
||||
install_info = {
|
||||
url = "https://github.com/elm-tooling/tree-sitter-elm",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
list.yaml = {
|
||||
|
@ -417,7 +420,7 @@ list.yaml = {
|
|||
url = "https://github.com/ikatyang/tree-sitter-yaml",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = {"@stsewd"},
|
||||
maintainers = { "@stsewd" },
|
||||
}
|
||||
|
||||
list.nix = {
|
||||
|
@ -425,7 +428,7 @@ list.nix = {
|
|||
url = "https://github.com/cstrahan/tree-sitter-nix",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@leo60228"},
|
||||
maintainers = { "@leo60228" },
|
||||
}
|
||||
|
||||
list.dart = {
|
||||
|
@ -433,7 +436,7 @@ list.dart = {
|
|||
url = "https://github.com/UserNobody14/tree-sitter-dart",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@Akin909"},
|
||||
maintainers = { "@Akin909" },
|
||||
}
|
||||
|
||||
list.rst = {
|
||||
|
@ -441,7 +444,7 @@ list.rst = {
|
|||
url = "https://github.com/stsewd/tree-sitter-rst",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@stsewd"},
|
||||
maintainers = { "@stsewd" },
|
||||
}
|
||||
|
||||
list.fennel = {
|
||||
|
@ -449,7 +452,7 @@ list.fennel = {
|
|||
url = "https://github.com/travonted/tree-sitter-fennel",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {'@TravonteD'},
|
||||
maintainers = { "@TravonteD" },
|
||||
}
|
||||
|
||||
list.teal = {
|
||||
|
@ -457,7 +460,7 @@ list.teal = {
|
|||
url = "https://github.com/euclidianAce/tree-sitter-teal",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {'@euclidianAce'},
|
||||
maintainers = { "@euclidianAce" },
|
||||
}
|
||||
|
||||
list.ql = {
|
||||
|
@ -465,7 +468,7 @@ list.ql = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-ql",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {'@pwntester'},
|
||||
maintainers = { "@pwntester" },
|
||||
}
|
||||
|
||||
list.verilog = {
|
||||
|
@ -482,9 +485,9 @@ list.verilog = {
|
|||
list.regex = {
|
||||
install_info = {
|
||||
url = "https://github.com/tree-sitter/tree-sitter-regex",
|
||||
files = { "src/parser.c" }
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@theHamsta"},
|
||||
maintainers = { "@theHamsta" },
|
||||
}
|
||||
|
||||
list.comment = {
|
||||
|
@ -492,7 +495,7 @@ list.comment = {
|
|||
url = "https://github.com/stsewd/tree-sitter-comment",
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
},
|
||||
maintainers = {"@stsewd"},
|
||||
maintainers = { "@stsewd" },
|
||||
}
|
||||
|
||||
list.jsdoc = {
|
||||
|
@ -500,16 +503,16 @@ list.jsdoc = {
|
|||
url = "https://github.com/tree-sitter/tree-sitter-jsdoc",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = {"@steelsojka"},
|
||||
maintainers = { "@steelsojka" },
|
||||
}
|
||||
|
||||
list.query = {
|
||||
install_info = {
|
||||
url = "https://github.com/nvim-treesitter/tree-sitter-query",
|
||||
files = { "src/parser.c" }
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
readme_name = "Tree-sitter query language",
|
||||
maintainers = {"@steelsojka"},
|
||||
maintainers = { "@steelsojka" },
|
||||
}
|
||||
|
||||
list.sparql = {
|
||||
|
@ -525,10 +528,10 @@ list.gdscript = {
|
|||
install_info = {
|
||||
url = "https://github.com/PrestonKnopp/tree-sitter-gdscript",
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
requires_generate_from_grammar = true,
|
||||
requires_generate_from_grammar = true,
|
||||
},
|
||||
readme_name = "Godot (gdscript)",
|
||||
maintainers = {"@Shatur95"},
|
||||
maintainers = { "@Shatur95" },
|
||||
}
|
||||
|
||||
list.turtle = {
|
||||
|
@ -545,9 +548,9 @@ list.devicetree = {
|
|||
url = "https://github.com/joelspadin/tree-sitter-devicetree",
|
||||
files = { "src/parser.c" },
|
||||
branch = "main",
|
||||
requires_generate_from_grammar = true,
|
||||
requires_generate_from_grammar = true,
|
||||
},
|
||||
filetype = 'dts',
|
||||
filetype = "dts",
|
||||
maintainers = { "@jedrzejboczar" },
|
||||
}
|
||||
|
||||
|
@ -563,7 +566,7 @@ list.svelte = {
|
|||
list.r = {
|
||||
install_info = {
|
||||
url = "https://github.com/r-lib/tree-sitter-r",
|
||||
files = { "src/parser.c" }
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
maintainers = { "@jimhester" },
|
||||
}
|
||||
|
@ -582,8 +585,8 @@ list.latex = {
|
|||
url = "https://github.com/latex-lsp/tree-sitter-latex",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
filetype = 'tex',
|
||||
used_by = {'cls', 'sty'},
|
||||
filetype = "tex",
|
||||
used_by = { "cls", "sty" },
|
||||
maintainers = { "@theHamsta by asking @clason" },
|
||||
}
|
||||
|
||||
|
@ -592,36 +595,36 @@ list.bibtex = {
|
|||
url = "https://github.com/latex-lsp/tree-sitter-bibtex",
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
filetype = 'bib',
|
||||
filetype = "bib",
|
||||
maintainers = { "@theHamsta by asking @clason" },
|
||||
}
|
||||
|
||||
list.zig = {
|
||||
install_info = {
|
||||
url = "https://github.com/Himujjal/tree-sitter-zig",
|
||||
files = { "src/parser.c" }
|
||||
files = { "src/parser.c" },
|
||||
},
|
||||
filetype = "zig",
|
||||
maintainers = { "@Himujjal" }
|
||||
maintainers = { "@Himujjal" },
|
||||
}
|
||||
|
||||
list.fortran = {
|
||||
install_info = {
|
||||
url = "https://github.com/stadelmanma/tree-sitter-fortran",
|
||||
files = { "src/parser.c", "src/scanner.cc", },
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
}
|
||||
|
||||
list.cmake = {
|
||||
install_info = {
|
||||
url = "https://github.com/uyha/tree-sitter-cmake",
|
||||
files = { "src/parser.c", "src/scanner.cc"},
|
||||
files = { "src/parser.c", "src/scanner.cc" },
|
||||
},
|
||||
maintainers = { "@uyha" },
|
||||
}
|
||||
|
||||
local M = {
|
||||
list = list
|
||||
list = list,
|
||||
}
|
||||
|
||||
function M.ft_to_lang(ft)
|
||||
|
@ -629,20 +632,23 @@ function M.ft_to_lang(ft)
|
|||
end
|
||||
|
||||
function M.available_parsers()
|
||||
if vim.fn.executable('tree-sitter') == 1 and vim.fn.executable('node') == 1 then
|
||||
if vim.fn.executable "tree-sitter" == 1 and vim.fn.executable "node" == 1 then
|
||||
return vim.tbl_keys(M.list)
|
||||
else
|
||||
return vim.tbl_filter(function(p) return not M.list[p].install_info.requires_generate_from_grammar end,
|
||||
vim.tbl_keys(M.list))
|
||||
return vim.tbl_filter(function(p)
|
||||
return not M.list[p].install_info.requires_generate_from_grammar
|
||||
end, vim.tbl_keys(
|
||||
M.list
|
||||
))
|
||||
end
|
||||
end
|
||||
|
||||
function M.maintained_parsers()
|
||||
local has_tree_sitter_cli = vim.fn.executable('tree-sitter') == 1 and vim.fn.executable('node') == 1
|
||||
local has_tree_sitter_cli = vim.fn.executable "tree-sitter" == 1 and vim.fn.executable "node" == 1
|
||||
return vim.tbl_filter(function(lang)
|
||||
return M.list[lang].maintainers
|
||||
and (has_tree_sitter_cli or not M.list[lang].install_info.requires_generate_from_grammar) end,
|
||||
M.available_parsers())
|
||||
and (has_tree_sitter_cli or not M.list[lang].install_info.requires_generate_from_grammar)
|
||||
end, M.available_parsers())
|
||||
end
|
||||
|
||||
function M.get_parser_configs()
|
||||
|
@ -654,9 +660,9 @@ local parser_files
|
|||
function M.reset_cache()
|
||||
parser_files = setmetatable({}, {
|
||||
__index = function(tbl, key)
|
||||
rawset(tbl, key, api.nvim_get_runtime_file('parser/' .. key .. '.*', false))
|
||||
rawset(tbl, key, api.nvim_get_runtime_file("parser/" .. key .. ".*", false))
|
||||
return rawget(tbl, key)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -665,9 +671,13 @@ M.reset_cache()
|
|||
function M.has_parser(lang)
|
||||
local lang = lang or M.get_buf_lang(api.nvim_get_current_buf())
|
||||
|
||||
if not lang or #lang == 0 then return false end
|
||||
if not lang or #lang == 0 then
|
||||
return false
|
||||
end
|
||||
-- HACK: nvim internal API
|
||||
if vim._ts_has_language(lang) then return true end
|
||||
if vim._ts_has_language(lang) then
|
||||
return true
|
||||
end
|
||||
return #parser_files[lang] > 0
|
||||
end
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
local api = vim.api
|
||||
local tsq = require'vim.treesitter.query'
|
||||
local tsrange = require'nvim-treesitter.tsrange'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local caching = require'nvim-treesitter.caching'
|
||||
local tsq = require "vim.treesitter.query"
|
||||
local tsrange = require "nvim-treesitter.tsrange"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local caching = require "nvim-treesitter.caching"
|
||||
|
||||
local M = {}
|
||||
|
||||
local EMPTY_ITER = function() end
|
||||
|
||||
M.built_in_query_groups = {'highlights', 'locals', 'folds', 'indents', 'injections'}
|
||||
M.built_in_query_groups = { "highlights", "locals", "folds", "indents", "injections" }
|
||||
|
||||
-- Creates a function that checks whether a given query exists
|
||||
-- for a specific language.
|
||||
|
@ -24,10 +24,10 @@ for _, query in ipairs(M.built_in_query_groups) do
|
|||
end
|
||||
|
||||
function M.available_query_groups()
|
||||
local query_files = api.nvim_get_runtime_file('queries/*/*.scm', true)
|
||||
local query_files = api.nvim_get_runtime_file("queries/*/*.scm", true)
|
||||
local groups = {}
|
||||
for _, f in ipairs(query_files) do
|
||||
groups[vim.fn.fnamemodify(f, ':t:r')] = true
|
||||
groups[vim.fn.fnamemodify(f, ":t:r")] = true
|
||||
end
|
||||
local list = {}
|
||||
for k, _ in pairs(groups) do
|
||||
|
@ -42,7 +42,7 @@ do
|
|||
local function update_cached_matches(bufnr, changed_tick, query_group)
|
||||
query_cache.set(query_group, bufnr, {
|
||||
tick = changed_tick,
|
||||
cache= M.collect_group_results(bufnr, query_group) or {}
|
||||
cache = M.collect_group_results(bufnr, query_group) or {},
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -50,7 +50,7 @@ do
|
|||
bufnr = bufnr or api.nvim_get_current_buf()
|
||||
local cached_local = query_cache.get(query_group, bufnr)
|
||||
if not cached_local or api.nvim_buf_get_changedtick(bufnr) > cached_local.tick then
|
||||
update_cached_matches(bufnr,api.nvim_buf_get_changedtick(bufnr), query_group)
|
||||
update_cached_matches(bufnr, api.nvim_buf_get_changedtick(bufnr), query_group)
|
||||
end
|
||||
|
||||
return query_cache.get(query_group, bufnr).cache
|
||||
|
@ -58,7 +58,7 @@ do
|
|||
end
|
||||
|
||||
local function runtime_queries(lang, query_name)
|
||||
return api.nvim_get_runtime_file(string.format('queries/%s/%s.scm', lang, query_name), true) or {}
|
||||
return api.nvim_get_runtime_file(string.format("queries/%s/%s.scm", lang, query_name), true) or {}
|
||||
end
|
||||
|
||||
local query_files_cache = {}
|
||||
|
@ -66,11 +66,11 @@ function M.has_query_files(lang, query_name)
|
|||
if not query_files_cache[lang] then
|
||||
query_files_cache[lang] = {}
|
||||
end
|
||||
if query_files_cache[lang][query_name] == nil then
|
||||
local files = runtime_queries(lang, query_name)
|
||||
query_files_cache[lang][query_name] = files and #files > 0
|
||||
end
|
||||
return query_files_cache[lang][query_name]
|
||||
if query_files_cache[lang][query_name] == nil then
|
||||
local files = runtime_queries(lang, query_name)
|
||||
query_files_cache[lang][query_name] = files and #files > 0
|
||||
end
|
||||
return query_files_cache[lang][query_name]
|
||||
end
|
||||
|
||||
do
|
||||
|
@ -117,7 +117,7 @@ do
|
|||
end
|
||||
end
|
||||
else
|
||||
error("Cannot have query_name by itself!")
|
||||
error "Cannot have query_name by itself!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -125,7 +125,7 @@ end
|
|||
--- This function is meant for an autocommand and not to be used. Only use if file is a query file.
|
||||
function M.invalidate_query_file(fname)
|
||||
local fnamemodify = vim.fn.fnamemodify
|
||||
M.invalidate_query_cache(fnamemodify(fname, ':p:h:t'), fnamemodify(fname, ':t:r'))
|
||||
M.invalidate_query_cache(fnamemodify(fname, ":p:h:t"), fnamemodify(fname, ":t:r"))
|
||||
end
|
||||
|
||||
function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
|
||||
|
@ -142,7 +142,7 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
|
|||
local function insert_to_path(object, path, value)
|
||||
local curr_obj = object
|
||||
|
||||
for index=1,(#path -1) do
|
||||
for index = 1, (#path - 1) do
|
||||
if curr_obj[path[index]] == nil then
|
||||
curr_obj[path[index]] = {}
|
||||
end
|
||||
|
@ -164,7 +164,7 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
|
|||
for id, node in pairs(match) do
|
||||
local name = query.captures[id] -- name of the capture in the query
|
||||
if name ~= nil then
|
||||
local path = split(name..'.node')
|
||||
local path = split(name .. ".node")
|
||||
insert_to_path(prepared_match, path, node)
|
||||
end
|
||||
end
|
||||
|
@ -178,8 +178,11 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
|
|||
insert_to_path(prepared_match, split(pred[2]), pred[3])
|
||||
end
|
||||
if pred[1] == "make-range!" and type(pred[2]) == "string" and #pred == 4 then
|
||||
insert_to_path(prepared_match, split(pred[2]..'.node'),
|
||||
tsrange.TSRange.from_nodes(bufnr, match[pred[3]], match[pred[4]]))
|
||||
insert_to_path(
|
||||
prepared_match,
|
||||
split(pred[2] .. ".node"),
|
||||
tsrange.TSRange.from_nodes(bufnr, match[pred[3]], match[pred[4]])
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -194,8 +197,8 @@ end
|
|||
-- Works like M.get_references or M.get_scopes except you can choose the capture
|
||||
-- Can also be a nested capture like @definition.function to get all nodes defining a function
|
||||
function M.get_capture_matches(bufnr, capture_string, query_group, root, lang)
|
||||
if not string.sub(capture_string, 1, 1) == '@' then
|
||||
print('capture_string must start with "@"')
|
||||
if not string.sub(capture_string, 1, 1) == "@" then
|
||||
print 'capture_string must start with "@"'
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -214,7 +217,7 @@ function M.get_capture_matches(bufnr, capture_string, query_group, root, lang)
|
|||
end
|
||||
|
||||
function M.find_best_match(bufnr, capture_string, query_group, filter_predicate, scoring_function, root)
|
||||
if string.sub(capture_string, 1, 1) == '@' then
|
||||
if string.sub(capture_string, 1, 1) == "@" then
|
||||
--remove leading "@"
|
||||
capture_string = string.sub(capture_string, 2)
|
||||
end
|
||||
|
@ -248,10 +251,14 @@ end
|
|||
function M.iter_group_results(bufnr, query_group, root, root_lang)
|
||||
local buf_lang = parsers.get_buf_lang(bufnr)
|
||||
|
||||
if not buf_lang then return EMPTY_ITER end
|
||||
if not buf_lang then
|
||||
return EMPTY_ITER
|
||||
end
|
||||
|
||||
local parser = parsers.get_parser(bufnr, buf_lang)
|
||||
if not parser then return EMPTY_ITER end
|
||||
if not parser then
|
||||
return EMPTY_ITER
|
||||
end
|
||||
|
||||
if not root then
|
||||
local first_tree = parser:trees()[1]
|
||||
|
@ -261,9 +268,11 @@ function M.iter_group_results(bufnr, query_group, root, root_lang)
|
|||
end
|
||||
end
|
||||
|
||||
if not root then return EMPTY_ITER end
|
||||
if not root then
|
||||
return EMPTY_ITER
|
||||
end
|
||||
|
||||
local range = {root:range()}
|
||||
local range = { root:range() }
|
||||
|
||||
if not root_lang then
|
||||
local lang_tree = parser:language_for_range(range)
|
||||
|
@ -273,10 +282,14 @@ function M.iter_group_results(bufnr, query_group, root, root_lang)
|
|||
end
|
||||
end
|
||||
|
||||
if not root_lang then return EMPTY_ITER end
|
||||
if not root_lang then
|
||||
return EMPTY_ITER
|
||||
end
|
||||
|
||||
local query = M.get_query(root_lang, query_group)
|
||||
if not query then return EMPTY_ITER end
|
||||
if not query then
|
||||
return EMPTY_ITER
|
||||
end
|
||||
|
||||
-- The end row is exclusive so we need to add 1 to it.
|
||||
return M.iter_prepared_matches(query, root, bufnr, range[1], range[3] + 1)
|
||||
|
@ -300,8 +313,7 @@ end
|
|||
-- @param query_type The query to get the capture from. This is ignore if a function is provided
|
||||
-- for the captuer argument.
|
||||
function M.get_capture_matches_recursively(bufnr, capture_or_fn, query_type)
|
||||
local type_fn = type(capture_or_fn) == 'function'
|
||||
and capture_or_fn
|
||||
local type_fn = type(capture_or_fn) == "function" and capture_or_fn
|
||||
or function()
|
||||
return capture_or_fn, query_type
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local query = require"vim.treesitter.query"
|
||||
local query = require "vim.treesitter.query"
|
||||
|
||||
local function error(str)
|
||||
vim.api.nvim_err_writeln(str)
|
||||
|
@ -21,7 +21,9 @@ local function valid_args(name, pred, count, strict_count)
|
|||
end
|
||||
|
||||
query.add_predicate("nth?", function(match, pattern, bufnr, pred)
|
||||
if not valid_args("nth?", pred, 2, true) then return end
|
||||
if not valid_args("nth?", pred, 2, true) then
|
||||
return
|
||||
end
|
||||
|
||||
local node = match[pred[2]]
|
||||
local n = pred[3]
|
||||
|
@ -33,13 +35,17 @@ query.add_predicate("nth?", function(match, pattern, bufnr, pred)
|
|||
end)
|
||||
|
||||
local function has_ancestor(match, pattern, bufnr, pred)
|
||||
if not valid_args(pred[1], pred, 2) then return end
|
||||
if not valid_args(pred[1], pred, 2) then
|
||||
return
|
||||
end
|
||||
|
||||
local node = match[pred[2]]
|
||||
local ancestor_types = {unpack(pred, 3)}
|
||||
if not node then return true end
|
||||
local ancestor_types = { unpack(pred, 3) }
|
||||
if not node then
|
||||
return true
|
||||
end
|
||||
|
||||
local just_direct_parent = pred[1]:find('has-parent', 1, true)
|
||||
local just_direct_parent = pred[1]:find("has-parent", 1, true)
|
||||
|
||||
node = node:parent()
|
||||
while node do
|
||||
|
@ -55,40 +61,48 @@ local function has_ancestor(match, pattern, bufnr, pred)
|
|||
return false
|
||||
end
|
||||
|
||||
query.add_predicate('has-ancestor?', has_ancestor)
|
||||
query.add_predicate("has-ancestor?", has_ancestor)
|
||||
|
||||
query.add_predicate('has-parent?', has_ancestor)
|
||||
query.add_predicate("has-parent?", has_ancestor)
|
||||
|
||||
query.add_predicate('is?', function(match, pattern, bufnr, pred)
|
||||
if not valid_args("is?", pred, 2) then return end
|
||||
query.add_predicate("is?", function(match, pattern, bufnr, pred)
|
||||
if not valid_args("is?", pred, 2) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Avoid circular dependencies
|
||||
local locals = require"nvim-treesitter.locals"
|
||||
local locals = require "nvim-treesitter.locals"
|
||||
local node = match[pred[2]]
|
||||
local types = {unpack(pred, 3)}
|
||||
local types = { unpack(pred, 3) }
|
||||
|
||||
if not node then return true end
|
||||
if not node then
|
||||
return true
|
||||
end
|
||||
|
||||
local _, _, kind = locals.find_definition(node, bufnr)
|
||||
|
||||
return vim.tbl_contains(types, kind)
|
||||
end)
|
||||
|
||||
query.add_predicate('has-type?', function(match, pattern, bufnr, pred)
|
||||
if not valid_args(pred[1], pred, 2) then return end
|
||||
query.add_predicate("has-type?", function(match, pattern, bufnr, pred)
|
||||
if not valid_args(pred[1], pred, 2) then
|
||||
return
|
||||
end
|
||||
|
||||
local node = match[pred[2]]
|
||||
local types = {unpack(pred, 3)}
|
||||
local types = { unpack(pred, 3) }
|
||||
|
||||
if not node then return true end
|
||||
if not node then
|
||||
return true
|
||||
end
|
||||
|
||||
return vim.tbl_contains(types, node:type())
|
||||
end)
|
||||
|
||||
-- Just avoid some anoying warnings for this directive
|
||||
query.add_directive('make-range!', function() end)
|
||||
query.add_directive("make-range!", function() end)
|
||||
|
||||
query.add_directive('downcase!', function(match, _, bufnr, pred, metadata)
|
||||
query.add_directive("downcase!", function(match, _, bufnr, pred, metadata)
|
||||
local text, key, value
|
||||
|
||||
if #pred == 3 then
|
||||
|
|
|
@ -1,116 +1,118 @@
|
|||
local fn = vim.fn
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.select_mkdir_cmd(directory, cwd, info_msg)
|
||||
if fn.has('win32') == 1 then
|
||||
if fn.has "win32" == 1 then
|
||||
return {
|
||||
cmd = 'cmd',
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { '/C', 'mkdir', directory},
|
||||
args = { "/C", "mkdir", directory },
|
||||
cwd = cwd,
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not create "..directory,
|
||||
err = "Could not create " .. directory,
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = 'mkdir',
|
||||
cmd = "mkdir",
|
||||
opts = {
|
||||
args = { directory },
|
||||
cwd = cwd,
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not create "..directory,
|
||||
err = "Could not create " .. directory,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_rm_file_cmd(file, info_msg)
|
||||
if fn.has('win32') == 1 then
|
||||
if fn.has "win32" == 1 then
|
||||
return {
|
||||
cmd = 'cmd',
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { '/C', 'if', 'exist', file, 'del', file },
|
||||
args = { "/C", "if", "exist", file, "del", file },
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not delete "..file,
|
||||
err = "Could not delete " .. file,
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = 'rm',
|
||||
cmd = "rm",
|
||||
opts = {
|
||||
args = { file },
|
||||
},
|
||||
info = info_msg,
|
||||
err = "Could not delete "..file,
|
||||
err = "Could not delete " .. file,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_executable(executables)
|
||||
return vim.tbl_filter(function(c) return c ~= vim.NIL and fn.executable(c) == 1 end, executables)[1]
|
||||
return vim.tbl_filter(function(c)
|
||||
return c ~= vim.NIL and fn.executable(c) == 1
|
||||
end, executables)[1]
|
||||
end
|
||||
|
||||
function M.select_compiler_args(repo, compiler)
|
||||
if (string.match(compiler, 'cl$') or string.match(compiler, 'cl.exe$')) then
|
||||
if string.match(compiler, "cl$") or string.match(compiler, "cl.exe$") then
|
||||
return {
|
||||
'/Fe:',
|
||||
'parser.so',
|
||||
'/Isrc',
|
||||
"/Fe:",
|
||||
"parser.so",
|
||||
"/Isrc",
|
||||
repo.files,
|
||||
'-Os',
|
||||
'/LD',
|
||||
"-Os",
|
||||
"/LD",
|
||||
}
|
||||
else
|
||||
local args = {
|
||||
'-o',
|
||||
'parser.so',
|
||||
'-I./src',
|
||||
"-o",
|
||||
"parser.so",
|
||||
"-I./src",
|
||||
repo.files,
|
||||
'-shared',
|
||||
'-Os',
|
||||
'-lstdc++',
|
||||
"-shared",
|
||||
"-Os",
|
||||
"-lstdc++",
|
||||
}
|
||||
if fn.has('win32') == 0 then
|
||||
table.insert(args, '-fPIC')
|
||||
if fn.has "win32" == 0 then
|
||||
table.insert(args, "-fPIC")
|
||||
end
|
||||
return args
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_install_rm_cmd(cache_folder, project_name)
|
||||
if fn.has('win32') == 1 then
|
||||
local dir = cache_folder ..'\\'.. project_name
|
||||
if fn.has "win32" == 1 then
|
||||
local dir = cache_folder .. "\\" .. project_name
|
||||
return {
|
||||
cmd = 'cmd',
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { '/C', 'if', 'exist', dir, 'rmdir', '/s', '/q', dir },
|
||||
}
|
||||
args = { "/C", "if", "exist", dir, "rmdir", "/s", "/q", dir },
|
||||
},
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = 'rm',
|
||||
cmd = "rm",
|
||||
opts = {
|
||||
args = { '-rf', cache_folder..'/'..project_name },
|
||||
}
|
||||
args = { "-rf", cache_folder .. "/" .. project_name },
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.select_mv_cmd(from, to, cwd)
|
||||
if fn.has('win32') == 1 then
|
||||
if fn.has "win32" == 1 then
|
||||
return {
|
||||
cmd = 'cmd',
|
||||
cmd = "cmd",
|
||||
opts = {
|
||||
args = { '/C', 'move', '/Y', from, to },
|
||||
args = { "/C", "move", "/Y", from, to },
|
||||
cwd = cwd,
|
||||
}
|
||||
},
|
||||
}
|
||||
else
|
||||
return {
|
||||
cmd = 'mv',
|
||||
cmd = "mv",
|
||||
opts = {
|
||||
args = { from, to },
|
||||
cwd = cwd,
|
||||
|
@ -120,93 +122,94 @@ function M.select_mv_cmd(from, to, cwd)
|
|||
end
|
||||
|
||||
function M.select_download_commands(repo, project_name, cache_folder, revision)
|
||||
|
||||
local can_use_tar = vim.fn.executable('tar') == 1 and vim.fn.executable('curl') == 1
|
||||
local can_use_tar = vim.fn.executable "tar" == 1 and vim.fn.executable "curl" == 1
|
||||
local is_github = repo.url:find("github.com", 1, true)
|
||||
local is_gitlab = repo.url:find("gitlab.com", 1, true)
|
||||
|
||||
local is_windows = fn.has('win32') == 1
|
||||
local is_windows = fn.has "win32" == 1
|
||||
|
||||
revision = revision or repo.branch or "master"
|
||||
|
||||
if can_use_tar and (is_github or is_gitlab) and not is_windows then
|
||||
|
||||
local path_sep = utils.get_path_sep()
|
||||
local url = repo.url:gsub('.git$', '')
|
||||
local url = repo.url:gsub(".git$", "")
|
||||
|
||||
return {
|
||||
M.select_install_rm_cmd(cache_folder, project_name..'-tmp'),
|
||||
M.select_install_rm_cmd(cache_folder, project_name .. "-tmp"),
|
||||
{
|
||||
cmd = 'curl',
|
||||
info = 'Downloading...',
|
||||
err = 'Error during download, please verify your internet connection',
|
||||
cmd = "curl",
|
||||
info = "Downloading...",
|
||||
err = "Error during download, please verify your internet connection",
|
||||
opts = {
|
||||
args = {
|
||||
'-L', -- follow redirects
|
||||
is_github and url.."/archive/"..revision..".tar.gz"
|
||||
or url.."/-/archive/"..revision.."/"..project_name.."-"..revision..".tar.gz",
|
||||
'--output',
|
||||
project_name..".tar.gz"
|
||||
"-L", -- follow redirects
|
||||
is_github and url .. "/archive/" .. revision .. ".tar.gz"
|
||||
or url .. "/-/archive/" .. revision .. "/" .. project_name .. "-" .. revision .. ".tar.gz",
|
||||
"--output",
|
||||
project_name .. ".tar.gz",
|
||||
},
|
||||
cwd = cache_folder,
|
||||
},
|
||||
},
|
||||
M.select_mkdir_cmd(project_name..'-tmp', cache_folder, 'Creating temporary directory'),
|
||||
M.select_mkdir_cmd(project_name .. "-tmp", cache_folder, "Creating temporary directory"),
|
||||
{
|
||||
cmd = 'tar',
|
||||
info = 'Extracting...',
|
||||
err = 'Error during tarball extraction.',
|
||||
cmd = "tar",
|
||||
info = "Extracting...",
|
||||
err = "Error during tarball extraction.",
|
||||
opts = {
|
||||
args = {
|
||||
'-xvf',
|
||||
project_name..".tar.gz",
|
||||
'-C',
|
||||
project_name..'-tmp',
|
||||
"-xvf",
|
||||
project_name .. ".tar.gz",
|
||||
"-C",
|
||||
project_name .. "-tmp",
|
||||
},
|
||||
cwd = cache_folder,
|
||||
},
|
||||
},
|
||||
M.select_rm_file_cmd(cache_folder..path_sep..project_name..".tar.gz"),
|
||||
M.select_mv_cmd(utils.join_path(project_name..'-tmp', url:match('[^/]-$')..'-'..revision),
|
||||
M.select_rm_file_cmd(cache_folder .. path_sep .. project_name .. ".tar.gz"),
|
||||
M.select_mv_cmd(
|
||||
utils.join_path(project_name .. "-tmp", url:match "[^/]-$" .. "-" .. revision),
|
||||
project_name,
|
||||
cache_folder),
|
||||
M.select_install_rm_cmd(cache_folder, project_name..'-tmp')
|
||||
cache_folder
|
||||
),
|
||||
M.select_install_rm_cmd(cache_folder, project_name .. "-tmp"),
|
||||
}
|
||||
else
|
||||
local git_folder = utils.join_path(cache_folder, project_name)
|
||||
local clone_error = 'Error during download, please verify your internet connection'
|
||||
local clone_error = "Error during download, please verify your internet connection"
|
||||
|
||||
return {
|
||||
{
|
||||
cmd = 'git',
|
||||
info = 'Downloading...',
|
||||
cmd = "git",
|
||||
info = "Downloading...",
|
||||
err = clone_error,
|
||||
opts = {
|
||||
args = {
|
||||
'clone',
|
||||
"clone",
|
||||
repo.url,
|
||||
project_name
|
||||
project_name,
|
||||
},
|
||||
cwd = cache_folder,
|
||||
},
|
||||
},
|
||||
{
|
||||
cmd = 'git',
|
||||
info = 'Checking out locked revision',
|
||||
err = 'Error while checking out revision',
|
||||
cmd = "git",
|
||||
info = "Checking out locked revision",
|
||||
err = "Error while checking out revision",
|
||||
opts = {
|
||||
args = {
|
||||
'checkout', revision,
|
||||
"checkout",
|
||||
revision,
|
||||
},
|
||||
cwd = git_folder
|
||||
}
|
||||
}
|
||||
cwd = git_folder,
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function M.make_directory_change_for_command(dir, command)
|
||||
if fn.has('win32') == 1 then
|
||||
if fn.has "win32" == 1 then
|
||||
return string.format("pushd %s & %s & popd", dir, command)
|
||||
else
|
||||
return string.format("cd %s;\n %s", dir, command)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local api = vim.api
|
||||
|
||||
local parsers = require'nvim-treesitter.parsers'
|
||||
local utils = require'nvim-treesitter.utils'
|
||||
local parsers = require "nvim-treesitter.parsers"
|
||||
local utils = require "nvim-treesitter.utils"
|
||||
|
||||
local M = {}
|
||||
|
||||
|
@ -11,20 +11,22 @@ local M = {}
|
|||
-- @return list of lines of text of the node
|
||||
function M.get_node_text(node, bufnr)
|
||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||
if not node then return {} end
|
||||
if not node then
|
||||
return {}
|
||||
end
|
||||
|
||||
-- We have to remember that end_col is end-exclusive
|
||||
local start_row, start_col, end_row, end_col = M.get_node_range(node)
|
||||
|
||||
if start_row ~= end_row then
|
||||
local lines = api.nvim_buf_get_lines(bufnr, start_row, end_row+1, false)
|
||||
lines[1] = string.sub(lines[1], start_col+1)
|
||||
local lines = api.nvim_buf_get_lines(bufnr, start_row, end_row + 1, false)
|
||||
lines[1] = string.sub(lines[1], start_col + 1)
|
||||
lines[#lines] = string.sub(lines[#lines], 1, end_col)
|
||||
return lines
|
||||
else
|
||||
local line = api.nvim_buf_get_lines(bufnr, start_row, start_row+1, false)[1]
|
||||
local line = api.nvim_buf_get_lines(bufnr, start_row, start_row + 1, false)[1]
|
||||
-- If line is nil then the line is empty
|
||||
return line and { string.sub(line, start_col+1, end_col) } or {}
|
||||
return line and { string.sub(line, start_col + 1, end_col) } or {}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -32,7 +34,9 @@ end
|
|||
-- @param dest the possible parent
|
||||
-- @param source the possible child node
|
||||
function M.is_parent(dest, source)
|
||||
if not (dest and source) then return false end
|
||||
if not (dest and source) then
|
||||
return false
|
||||
end
|
||||
|
||||
local current = source
|
||||
while current ~= nil do
|
||||
|
@ -54,9 +58,11 @@ function M.get_next_node(node, allow_switch_parents, allow_next_parent)
|
|||
local destination_node
|
||||
local parent = node:parent()
|
||||
|
||||
if not parent then return end
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
local found_pos = 0
|
||||
for i = 0,parent:named_child_count()-1,1 do
|
||||
for i = 0, parent:named_child_count() - 1, 1 do
|
||||
if parent:named_child(i) == node then
|
||||
found_pos = i
|
||||
break
|
||||
|
@ -83,10 +89,12 @@ end
|
|||
function M.get_previous_node(node, allow_switch_parents, allow_previous_parent)
|
||||
local destination_node
|
||||
local parent = node:parent()
|
||||
if not parent then return end
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
|
||||
local found_pos = 0
|
||||
for i = 0,parent:named_child_count()-1,1 do
|
||||
for i = 0, parent:named_child_count() - 1, 1 do
|
||||
if parent:named_child(i) == node then
|
||||
found_pos = i
|
||||
break
|
||||
|
@ -107,8 +115,8 @@ end
|
|||
|
||||
function M.get_named_children(node)
|
||||
local nodes = {}
|
||||
for i=0,node:named_child_count() - 1,1 do
|
||||
nodes[i+1] = node:named_child(i)
|
||||
for i = 0, node:named_child_count() - 1, 1 do
|
||||
nodes[i + 1] = node:named_child(i)
|
||||
end
|
||||
return nodes
|
||||
end
|
||||
|
@ -118,19 +126,23 @@ function M.get_node_at_cursor(winnr)
|
|||
local cursor_range = { cursor[1] - 1, cursor[2] }
|
||||
local root = M.get_root_for_position(unpack(cursor_range))
|
||||
|
||||
if not root then return end
|
||||
if not root then
|
||||
return
|
||||
end
|
||||
|
||||
return root:named_descendant_for_range(cursor_range[1], cursor_range[2], cursor_range[1], cursor_range[2])
|
||||
end
|
||||
|
||||
function M.get_root_for_position(line, col, root_lang_tree)
|
||||
if not root_lang_tree then
|
||||
if not parsers.has_parser() then return end
|
||||
if not parsers.has_parser() then
|
||||
return
|
||||
end
|
||||
|
||||
root_lang_tree = parsers.get_parser()
|
||||
end
|
||||
|
||||
local lang_tree = root_lang_tree:language_for_range({ line, col, line, col })
|
||||
local lang_tree = root_lang_tree:language_for_range { line, col, line, col }
|
||||
|
||||
for _, tree in ipairs(lang_tree:trees()) do
|
||||
local root = tree:root()
|
||||
|
@ -157,13 +169,15 @@ function M.get_root_for_node(node)
|
|||
end
|
||||
|
||||
function M.highlight_node(node, buf, hl_namespace, hl_group)
|
||||
if not node then return end
|
||||
M.highlight_range({node:range()}, buf, hl_namespace, hl_group)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
M.highlight_range({ node:range() }, buf, hl_namespace, hl_group)
|
||||
end
|
||||
|
||||
function M.highlight_range(range, buf, hl_namespace, hl_group)
|
||||
local start_row, start_col, end_row, end_col = unpack(range)
|
||||
vim.highlight.range(buf, hl_namespace, hl_group, {start_row, start_col}, {end_row, end_col})
|
||||
vim.highlight.range(buf, hl_namespace, hl_group, { start_row, start_col }, { end_row, end_col })
|
||||
end
|
||||
|
||||
-- Set visual selection to node
|
||||
|
@ -173,8 +187,8 @@ function M.update_selection(buf, node, selection_mode)
|
|||
selection_mode = selection_mode or "charwise"
|
||||
local start_row, start_col, end_row, end_col = M.get_node_range(node)
|
||||
|
||||
if end_row == vim.fn.line('$') then
|
||||
end_col = #vim.fn.getline('$')
|
||||
if end_row == vim.fn.line "$" then
|
||||
end_col = #vim.fn.getline "$"
|
||||
end
|
||||
|
||||
-- Convert to 1-based indices
|
||||
|
@ -186,12 +200,10 @@ function M.update_selection(buf, node, selection_mode)
|
|||
vim.fn.setpos(".", { buf, start_row, start_col, 0 })
|
||||
|
||||
-- Start visual selection in appropriate mode
|
||||
local v_table = {charwise = "v", linewise = "V", blockwise = "<C-v>"}
|
||||
local v_table = { charwise = "v", linewise = "V", blockwise = "<C-v>" }
|
||||
---- Call to `nvim_replace_termcodes()` is needed for sending appropriate
|
||||
---- command to enter blockwise mode
|
||||
local mode_string = vim.api.nvim_replace_termcodes(
|
||||
v_table[selection_mode] or selection_mode, true, true, true
|
||||
)
|
||||
local mode_string = vim.api.nvim_replace_termcodes(v_table[selection_mode] or selection_mode, true, true, true)
|
||||
vim.cmd("normal! " .. mode_string)
|
||||
|
||||
-- Convert exclusive end position to inclusive
|
||||
|
@ -231,7 +243,7 @@ function M.is_in_node_range(node, line, col)
|
|||
end
|
||||
|
||||
function M.get_node_range(node_or_range)
|
||||
if type(node_or_range) == 'table' then
|
||||
if type(node_or_range) == "table" then
|
||||
return unpack(node_or_range)
|
||||
else
|
||||
return node_or_range:range()
|
||||
|
@ -242,7 +254,7 @@ function M.node_to_lsp_range(node)
|
|||
local start_line, start_col, end_line, end_col = M.get_node_range(node)
|
||||
local rtn = {}
|
||||
rtn.start = { line = start_line, character = start_col }
|
||||
rtn['end'] = { line = end_line, character = end_col }
|
||||
rtn["end"] = { line = end_line, character = end_col }
|
||||
return rtn
|
||||
end
|
||||
|
||||
|
@ -277,13 +289,13 @@ function M.memoize_by_buf_tick(fn, options)
|
|||
-- Clean up logic only!
|
||||
api.nvim_buf_attach(bufnr, false, {
|
||||
on_detach = detach_handler,
|
||||
on_reload = detach_handler
|
||||
on_reload = detach_handler,
|
||||
})
|
||||
end
|
||||
|
||||
cache[key] = {
|
||||
result = fn(...),
|
||||
last_tick = tick
|
||||
last_tick = tick,
|
||||
}
|
||||
|
||||
return cache[key].result
|
||||
|
@ -291,24 +303,28 @@ function M.memoize_by_buf_tick(fn, options)
|
|||
end
|
||||
|
||||
function M.swap_nodes(node_or_range1, node_or_range2, bufnr, cursor_to_second)
|
||||
if not node_or_range1 or not node_or_range2 then return end
|
||||
if not node_or_range1 or not node_or_range2 then
|
||||
return
|
||||
end
|
||||
local range1 = M.node_to_lsp_range(node_or_range1)
|
||||
local range2 = M.node_to_lsp_range(node_or_range2)
|
||||
|
||||
local text1 = M.get_node_text(node_or_range1)
|
||||
local text2 = M.get_node_text(node_or_range2)
|
||||
|
||||
local edit1 = { range = range1, newText = table.concat(text2, '\n') }
|
||||
local edit2 = { range = range2, newText = table.concat(text1, '\n') }
|
||||
vim.lsp.util.apply_text_edits({edit1, edit2}, bufnr)
|
||||
local edit1 = { range = range1, newText = table.concat(text2, "\n") }
|
||||
local edit2 = { range = range2, newText = table.concat(text1, "\n") }
|
||||
vim.lsp.util.apply_text_edits({ edit1, edit2 }, bufnr)
|
||||
|
||||
if cursor_to_second then
|
||||
utils.set_jump()
|
||||
|
||||
local char_delta = 0
|
||||
local line_delta = 0
|
||||
if range1["end"].line < range2.start.line
|
||||
or (range1["end"].line == range2.start.line and range1["end"].character < range2.start.character) then
|
||||
if
|
||||
range1["end"].line < range2.start.line
|
||||
or (range1["end"].line == range2.start.line and range1["end"].character < range2.start.character)
|
||||
then
|
||||
line_delta = #text2 - #text1
|
||||
end
|
||||
|
||||
|
@ -320,29 +336,32 @@ function M.swap_nodes(node_or_range1, node_or_range2, bufnr, cursor_to_second)
|
|||
--space_between_ranges = range2.start.character - range1["end"].character
|
||||
--char_delta = correction_after_line_change + text_now_before_range2 + space_between_ranges
|
||||
--- Equivalent to:
|
||||
char_delta = #(text2[#text2]) - range1["end"].character
|
||||
char_delta = #text2[#text2] - range1["end"].character
|
||||
|
||||
-- add range1.start.character if last line of range1 (now text2) does not start at 0
|
||||
if range1.start.line == range2.start.line + line_delta then
|
||||
char_delta = char_delta + range1.start.character
|
||||
end
|
||||
else
|
||||
char_delta = #(text2[#text2]) - #(text1[#text1])
|
||||
char_delta = #text2[#text2] - #text1[#text1]
|
||||
end
|
||||
end
|
||||
|
||||
api.nvim_win_set_cursor(api.nvim_get_current_win(),
|
||||
{range2.start.line + 1 + line_delta,
|
||||
range2.start.character + char_delta})
|
||||
api.nvim_win_set_cursor(
|
||||
api.nvim_get_current_win(),
|
||||
{ range2.start.line + 1 + line_delta, range2.start.character + char_delta }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function M.goto_node(node, goto_end, avoid_set_jump)
|
||||
if not node then return end
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
if not avoid_set_jump then
|
||||
utils.set_jump()
|
||||
end
|
||||
local range = {node:range()}
|
||||
local range = { node:range() }
|
||||
local position
|
||||
if not goto_end then
|
||||
position = { range[1], range[2] }
|
||||
|
|
|
@ -3,75 +3,72 @@ local TSRange = {}
|
|||
TSRange.__index = TSRange
|
||||
|
||||
local api = vim.api
|
||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||
local ts_utils = require "nvim-treesitter.ts_utils"
|
||||
|
||||
local function get_byte_offset(buf, row, col)
|
||||
return api.nvim_buf_get_offset(buf, row)
|
||||
+ vim.fn.byteidx(api.nvim_buf_get_lines(buf, row, row + 1, false), col)
|
||||
return api.nvim_buf_get_offset(buf, row) + vim.fn.byteidx(api.nvim_buf_get_lines(buf, row, row + 1, false), col)
|
||||
end
|
||||
|
||||
function TSRange.new(buf, start_row, start_col, end_row, end_col)
|
||||
return setmetatable(
|
||||
{
|
||||
start_pos = {start_row, start_col, get_byte_offset(buf, start_row, start_col)},
|
||||
end_pos = {end_row, end_col, get_byte_offset(buf, end_row, end_col)},
|
||||
buf = buf,
|
||||
[1] = start_row,
|
||||
[2] = start_col,
|
||||
[3] = end_row,
|
||||
[4] = end_col,
|
||||
},
|
||||
TSRange)
|
||||
return setmetatable({
|
||||
start_pos = { start_row, start_col, get_byte_offset(buf, start_row, start_col) },
|
||||
end_pos = { end_row, end_col, get_byte_offset(buf, end_row, end_col) },
|
||||
buf = buf,
|
||||
[1] = start_row,
|
||||
[2] = start_col,
|
||||
[3] = end_row,
|
||||
[4] = end_col,
|
||||
}, TSRange)
|
||||
end
|
||||
|
||||
function TSRange.from_nodes(buf, start_node, end_node)
|
||||
TSRange.__index = TSRange
|
||||
local start_pos = start_node and {start_node:start()} or {end_node:start()}
|
||||
local end_pos = end_node and {end_node:end_()} or {start_node:end_()}
|
||||
return setmetatable(
|
||||
{
|
||||
start_pos = {start_pos[1], start_pos[2], start_pos[3]},
|
||||
end_pos = {end_pos[1], end_pos[2], end_pos[3]},
|
||||
buf = buf,
|
||||
[1] = start_pos[1],
|
||||
[2] = start_pos[2],
|
||||
[3] = end_pos[1],
|
||||
[4] = end_pos[2],
|
||||
},
|
||||
TSRange)
|
||||
local start_pos = start_node and { start_node:start() } or { end_node:start() }
|
||||
local end_pos = end_node and { end_node:end_() } or { start_node:end_() }
|
||||
return setmetatable({
|
||||
start_pos = { start_pos[1], start_pos[2], start_pos[3] },
|
||||
end_pos = { end_pos[1], end_pos[2], end_pos[3] },
|
||||
buf = buf,
|
||||
[1] = start_pos[1],
|
||||
[2] = start_pos[2],
|
||||
[3] = end_pos[1],
|
||||
[4] = end_pos[2],
|
||||
}, TSRange)
|
||||
end
|
||||
|
||||
function TSRange.from_table(buf, range)
|
||||
return setmetatable(
|
||||
{
|
||||
start_pos = {range[1], range[2], get_byte_offset(buf, range[1], range[2])},
|
||||
end_pos = {range[3], range[4], get_byte_offset(buf, range[3], range[4])},
|
||||
buf = buf,
|
||||
[1] = range[1],
|
||||
[2] = range[2],
|
||||
[3] = range[3],
|
||||
[4] = range[4],
|
||||
},
|
||||
TSRange)
|
||||
return setmetatable({
|
||||
start_pos = { range[1], range[2], get_byte_offset(buf, range[1], range[2]) },
|
||||
end_pos = { range[3], range[4], get_byte_offset(buf, range[3], range[4]) },
|
||||
buf = buf,
|
||||
[1] = range[1],
|
||||
[2] = range[2],
|
||||
[3] = range[3],
|
||||
[4] = range[4],
|
||||
}, TSRange)
|
||||
end
|
||||
|
||||
function TSRange:parent()
|
||||
local root = ts_utils.get_root_for_position(self[1], self[2])
|
||||
|
||||
return root
|
||||
and root:named_descendant_for_range(self.start_pos[1], self.start_pos[2], self.end_pos[1], self.end_pos[2])
|
||||
or nil
|
||||
return root and root:named_descendant_for_range(
|
||||
self.start_pos[1],
|
||||
self.start_pos[2],
|
||||
self.end_pos[1],
|
||||
self.end_pos[2]
|
||||
) or nil
|
||||
end
|
||||
|
||||
function TSRange:field()
|
||||
end
|
||||
function TSRange:field() end
|
||||
|
||||
function TSRange:child_count()
|
||||
return #self:collect_children()
|
||||
end
|
||||
|
||||
function TSRange:named_child_count()
|
||||
return #self:collect_children(function(c) return c:named() end)
|
||||
return #self:collect_children(function(c)
|
||||
return c:named()
|
||||
end)
|
||||
end
|
||||
|
||||
function TSRange:iter_children()
|
||||
|
@ -79,7 +76,9 @@ function TSRange:iter_children()
|
|||
return function()
|
||||
while true do
|
||||
local node = raw_iterator()
|
||||
if not node then return end
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
local _, _, start_byte = node:start()
|
||||
local _, _, end_byte = node:end_()
|
||||
if start_byte >= self.start_pos[3] and end_byte <= self.end_pos[3] then
|
||||
|
@ -104,7 +103,9 @@ function TSRange:child(index)
|
|||
end
|
||||
|
||||
function TSRange:named_child(index)
|
||||
return self:collect_children(function(c) return c.named() end)[index + 1]
|
||||
return self:collect_children(function(c)
|
||||
return c.named()
|
||||
end)[index + 1]
|
||||
end
|
||||
|
||||
function TSRange:start()
|
||||
|
@ -120,7 +121,7 @@ function TSRange:range()
|
|||
end
|
||||
|
||||
function TSRange:type()
|
||||
return 'nvim-treesitter-range'
|
||||
return "nvim-treesitter-range"
|
||||
end
|
||||
|
||||
function TSRange:symbol()
|
||||
|
@ -136,11 +137,18 @@ function TSRange:missing()
|
|||
end
|
||||
|
||||
function TSRange:has_error()
|
||||
return #self:collect_children(function(c) return c:has_error() end) > 0 and true or false
|
||||
return #self:collect_children(function(c)
|
||||
return c:has_error()
|
||||
end) > 0 and true or false
|
||||
end
|
||||
|
||||
function TSRange:sexpr()
|
||||
return table.concat(vim.tbl_map(function(c) return c:sexpr() end, self:collect_children()), ' ')
|
||||
return table.concat(
|
||||
vim.tbl_map(function(c)
|
||||
return c:sexpr()
|
||||
end, self:collect_children()),
|
||||
" "
|
||||
)
|
||||
end
|
||||
|
||||
M.TSRange = TSRange
|
||||
|
|
|
@ -6,20 +6,23 @@ local M = {}
|
|||
|
||||
function M.setup_commands(mod, commands)
|
||||
for command_name, def in pairs(commands) do
|
||||
local call_fn = string.format("lua require'nvim-treesitter.%s'.commands.%s['run<bang>'](<f-args>)",
|
||||
mod, command_name)
|
||||
local parts = vim.tbl_flatten({
|
||||
local call_fn = string.format(
|
||||
"lua require'nvim-treesitter.%s'.commands.%s['run<bang>'](<f-args>)",
|
||||
mod,
|
||||
command_name
|
||||
)
|
||||
local parts = vim.tbl_flatten {
|
||||
"command!",
|
||||
def.args,
|
||||
command_name,
|
||||
call_fn,
|
||||
})
|
||||
}
|
||||
api.nvim_command(table.concat(parts, " "))
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_path_sep()
|
||||
return fn.has('win32') == 1 and '\\' or '/'
|
||||
return fn.has "win32" == 1 and "\\" or "/"
|
||||
end
|
||||
|
||||
-- Returns a function that joins the given arguments with separator. Arguments
|
||||
|
@ -29,40 +32,40 @@ print(M.generate_join(" ")("foo", "bar"))
|
|||
--]]
|
||||
-- prints "foo bar"
|
||||
function M.generate_join(separator)
|
||||
return function (...)
|
||||
return table.concat({...}, separator)
|
||||
return function(...)
|
||||
return table.concat({ ... }, separator)
|
||||
end
|
||||
end
|
||||
|
||||
M.join_path = M.generate_join(M.get_path_sep())
|
||||
|
||||
local join_space = M.generate_join(" ")
|
||||
local join_space = M.generate_join " "
|
||||
|
||||
function M.get_package_path()
|
||||
-- Path to this source file, removing the leading '@'
|
||||
local source = string.sub(debug.getinfo(1, 'S').source, 2)
|
||||
local source = string.sub(debug.getinfo(1, "S").source, 2)
|
||||
|
||||
-- Path to the package root
|
||||
return fn.fnamemodify(source, ":p:h:h:h")
|
||||
end
|
||||
|
||||
function M.get_cache_dir()
|
||||
local cache_dir = fn.stdpath('data')
|
||||
local cache_dir = fn.stdpath "data"
|
||||
|
||||
if luv.fs_access(cache_dir, 'RW') then
|
||||
if luv.fs_access(cache_dir, "RW") then
|
||||
return cache_dir
|
||||
elseif luv.fs_access('/tmp', 'RW') then
|
||||
return '/tmp'
|
||||
elseif luv.fs_access("/tmp", "RW") then
|
||||
return "/tmp"
|
||||
end
|
||||
|
||||
return nil, join_space('Invalid cache rights,', fn.stdpath('data'), 'or /tmp should be read/write')
|
||||
return nil, join_space("Invalid cache rights,", fn.stdpath "data", "or /tmp should be read/write")
|
||||
end
|
||||
|
||||
-- Returns $XDG_DATA_HOME/nvim/site, but could use any directory that is in
|
||||
-- runtimepath
|
||||
function M.get_site_dir()
|
||||
local path_sep = M.get_path_sep()
|
||||
return M.join_path(fn.stdpath('data'), path_sep, 'site')
|
||||
return M.join_path(fn.stdpath "data", path_sep, "site")
|
||||
end
|
||||
|
||||
-- Try the package dir of the nvim-treesitter plugin first, followed by the
|
||||
|
@ -75,7 +78,7 @@ function M.get_parser_install_dir(folder_name)
|
|||
local package_path_parser_dir = M.join_path(package_path, folder_name)
|
||||
|
||||
-- If package_path is read/write, use that
|
||||
if luv.fs_access(package_path_parser_dir, 'RW') then
|
||||
if luv.fs_access(package_path_parser_dir, "RW") then
|
||||
return package_path_parser_dir
|
||||
end
|
||||
|
||||
|
@ -87,24 +90,24 @@ function M.get_parser_install_dir(folder_name)
|
|||
if not luv.fs_stat(parser_dir) then
|
||||
local ok, error = pcall(vim.fn.mkdir, parser_dir, "p", "0755")
|
||||
if not ok then
|
||||
return nil, join_space('Couldn\'t create parser dir', parser_dir, ':', error)
|
||||
return nil, join_space("Couldn't create parser dir", parser_dir, ":", error)
|
||||
end
|
||||
|
||||
return parser_dir
|
||||
end
|
||||
|
||||
-- parser_dir exists, use it if it's read/write
|
||||
if luv.fs_access(parser_dir, 'RW') then
|
||||
if luv.fs_access(parser_dir, "RW") then
|
||||
return parser_dir
|
||||
end
|
||||
|
||||
-- package_path isn't read/write, parser_dir exists but isn't read/write
|
||||
-- either, give up
|
||||
return nil, join_space('Invalid cache rights,', package_path, 'or', parser_dir, 'should be read/write')
|
||||
return nil, join_space("Invalid cache rights,", package_path, "or", parser_dir, "should be read/write")
|
||||
end
|
||||
|
||||
function M.get_parser_info_dir()
|
||||
return M.get_parser_install_dir('parser-info')
|
||||
return M.get_parser_install_dir "parser-info"
|
||||
end
|
||||
|
||||
-- Gets a property at path
|
||||
|
@ -112,12 +115,14 @@ end
|
|||
-- @param path the '.' separated path
|
||||
-- @returns the value at path or nil
|
||||
function M.get_at_path(tbl, path)
|
||||
if path == '' then return tbl end
|
||||
local segments = vim.split(path, '.', true)
|
||||
if path == "" then
|
||||
return tbl
|
||||
end
|
||||
local segments = vim.split(path, ".", true)
|
||||
local result = tbl
|
||||
|
||||
for _, segment in ipairs(segments) do
|
||||
if type(result) == 'table' then
|
||||
if type(result) == "table" then
|
||||
result = result[segment]
|
||||
end
|
||||
end
|
||||
|
@ -173,11 +178,13 @@ function M.identity(a)
|
|||
end
|
||||
|
||||
function M.constant(a)
|
||||
return function() return a end
|
||||
return function()
|
||||
return a
|
||||
end
|
||||
end
|
||||
|
||||
function M.to_func(a)
|
||||
return type(a) == 'function' and a or M.constant(a)
|
||||
return type(a) == "function" and a or M.constant(a)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-- Execute as `nvim --headless -c "luafile ./scripts/check-queries.lua"`
|
||||
|
||||
local function extract_captures()
|
||||
local lines = vim.fn.readfile("CONTRIBUTING.md")
|
||||
local lines = vim.fn.readfile "CONTRIBUTING.md"
|
||||
local captures = {}
|
||||
local current_query
|
||||
|
||||
|
@ -18,17 +18,17 @@ local function extract_captures()
|
|||
end
|
||||
|
||||
-- Complete captures for injections.
|
||||
local parsers = require 'nvim-treesitter.info'.installed_parsers()
|
||||
local parsers = require("nvim-treesitter.info").installed_parsers()
|
||||
for _, lang in pairs(parsers) do
|
||||
table.insert(captures['injections'], lang)
|
||||
table.insert(captures["injections"], lang)
|
||||
end
|
||||
|
||||
return captures
|
||||
end
|
||||
|
||||
local function do_check()
|
||||
local parsers = require 'nvim-treesitter.info'.installed_parsers()
|
||||
local queries = require 'nvim-treesitter.query'
|
||||
local parsers = require("nvim-treesitter.info").installed_parsers()
|
||||
local queries = require "nvim-treesitter.query"
|
||||
local query_types = queries.built_in_query_groups
|
||||
|
||||
local captures = extract_captures()
|
||||
|
@ -36,7 +36,7 @@ local function do_check()
|
|||
|
||||
for _, lang in pairs(parsers) do
|
||||
for _, query_type in pairs(query_types) do
|
||||
print('Checking '..lang..' '..query_type)
|
||||
print("Checking " .. lang .. " " .. query_type)
|
||||
local ok, query = pcall(queries.get_query, lang, query_type)
|
||||
if not ok then
|
||||
vim.api.nvim_err_writeln(query)
|
||||
|
@ -45,9 +45,9 @@ local function do_check()
|
|||
if query then
|
||||
for _, capture in ipairs(query.captures) do
|
||||
local is_valid = (
|
||||
vim.startswith(capture, "_") -- Helpers.
|
||||
or vim.tbl_contains(captures[query_type], capture)
|
||||
)
|
||||
vim.startswith(capture, "_") -- Helpers.
|
||||
or vim.tbl_contains(captures[query_type], capture)
|
||||
)
|
||||
if not is_valid then
|
||||
local error = string.format("(x) Invalid capture @%s in %s for %s.", capture, query_type, lang)
|
||||
print(error)
|
||||
|
@ -60,36 +60,36 @@ local function do_check()
|
|||
end
|
||||
if last_error then
|
||||
print()
|
||||
print("Last error: ")
|
||||
print "Last error: "
|
||||
error(last_error)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local ok, err = pcall(do_check)
|
||||
local allowed_to_fail = vim.split(vim.env.ALLOWED_INSTALLATION_FAILURES or '', ",", true)
|
||||
local allowed_to_fail = vim.split(vim.env.ALLOWED_INSTALLATION_FAILURES or "", ",", true)
|
||||
|
||||
for k, v in pairs(require 'nvim-treesitter.parsers'.get_parser_configs()) do
|
||||
if not require 'nvim-treesitter.parsers'.has_parser(k) then
|
||||
for k, v in pairs(require("nvim-treesitter.parsers").get_parser_configs()) do
|
||||
if not require("nvim-treesitter.parsers").has_parser(k) then
|
||||
-- On CI all parsers that can be installed from C files should be installed
|
||||
if vim.env.CI
|
||||
if
|
||||
vim.env.CI
|
||||
and not v.install_info.requires_generate_from_grammar
|
||||
and not vim.tbl_contains(allowed_to_fail, k) then
|
||||
|
||||
print('Error: parser for '..k..' is not installed')
|
||||
vim.cmd('cq')
|
||||
and not vim.tbl_contains(allowed_to_fail, k)
|
||||
then
|
||||
print("Error: parser for " .. k .. " is not installed")
|
||||
vim.cmd "cq"
|
||||
else
|
||||
print('Warning: parser for '..k..' is not installed')
|
||||
print("Warning: parser for " .. k .. " is not installed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ok then
|
||||
print('Check successful!\n')
|
||||
vim.cmd('q')
|
||||
print "Check successful!\n"
|
||||
vim.cmd "q"
|
||||
else
|
||||
print('Check failed:')
|
||||
print "Check failed:"
|
||||
print(err)
|
||||
print('\n')
|
||||
vim.cmd('cq')
|
||||
print "\n"
|
||||
vim.cmd "cq"
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ vim.cmd [[runtime! plugin/nvim-treesitter.vim]]
|
|||
vim.o.swapfile = false
|
||||
vim.bo.swapfile = false
|
||||
|
||||
require('nvim-treesitter.configs').setup {
|
||||
ensure_installed = 'maintained',
|
||||
indent = { enable = true },
|
||||
require("nvim-treesitter.configs").setup {
|
||||
ensure_installed = "maintained",
|
||||
indent = { enable = true },
|
||||
}
|
||||
|
|
|
@ -1,41 +1,49 @@
|
|||
-- Execute as `nvim --headless -c "luafile ./scripts/update-readme.lua"`
|
||||
local parsers = require 'nvim-treesitter.parsers'.get_parser_configs()
|
||||
local parsers = require("nvim-treesitter.parsers").get_parser_configs()
|
||||
local sorted_parsers = {}
|
||||
|
||||
for k, v in pairs(parsers) do
|
||||
table.insert(sorted_parsers, {name = k, parser = v})
|
||||
table.insert(sorted_parsers, { name = k, parser = v })
|
||||
end
|
||||
|
||||
table.sort(sorted_parsers, function(a, b) return a.name < b.name end)
|
||||
table.sort(sorted_parsers, function(a, b)
|
||||
return a.name < b.name
|
||||
end)
|
||||
|
||||
local generated_text = ''
|
||||
local generated_text = ""
|
||||
|
||||
for _, v in ipairs(sorted_parsers) do
|
||||
local link = '['..(v.parser.readme_name or v.name)..']('..v.parser.install_info.url..')'
|
||||
local link = "[" .. (v.parser.readme_name or v.name) .. "](" .. v.parser.install_info.url .. ")"
|
||||
|
||||
if v.parser.maintainers then
|
||||
generated_text = generated_text..
|
||||
'- [x] '..link..' (maintained by '..table.concat(v.parser.maintainers, ', ')..')\n'
|
||||
generated_text = generated_text
|
||||
.. "- [x] "
|
||||
.. link
|
||||
.. " (maintained by "
|
||||
.. table.concat(v.parser.maintainers, ", ")
|
||||
.. ")\n"
|
||||
else
|
||||
generated_text = generated_text..
|
||||
'- [ ] '..link..'\n'
|
||||
generated_text = generated_text .. "- [ ] " .. link .. "\n"
|
||||
end
|
||||
end
|
||||
|
||||
print(generated_text)
|
||||
print("\n")
|
||||
print "\n"
|
||||
|
||||
local readme_text = table.concat(vim.fn.readfile('README.md'), '\n')
|
||||
local readme_text = table.concat(vim.fn.readfile "README.md", "\n")
|
||||
|
||||
local new_readme_text = string.gsub(readme_text, "<!%-%-parserinfo%-%->.*<!%-%-parserinfo%-%->",
|
||||
"<!--parserinfo-->\n"..generated_text.."<!--parserinfo-->")
|
||||
vim.fn.writefile(vim.fn.split(new_readme_text, '\n'), "README.md")
|
||||
local new_readme_text = string.gsub(
|
||||
readme_text,
|
||||
"<!%-%-parserinfo%-%->.*<!%-%-parserinfo%-%->",
|
||||
"<!--parserinfo-->\n" .. generated_text .. "<!--parserinfo-->"
|
||||
)
|
||||
vim.fn.writefile(vim.fn.split(new_readme_text, "\n"), "README.md")
|
||||
|
||||
if string.find(readme_text, generated_text, 1, 'plain') then
|
||||
print("README.md is up-to-date!")
|
||||
vim.cmd('q')
|
||||
if string.find(readme_text, generated_text, 1, "plain") then
|
||||
print "README.md is up-to-date!"
|
||||
vim.cmd "q"
|
||||
else
|
||||
print("New README.md was written. Please commit that change! Old text was: ")
|
||||
print "New README.md was written. Please commit that change! Old text was: "
|
||||
print(string.sub(readme_text, string.find(readme_text, "<!%-%-parserinfo%-%->.*<!%-%-parserinfo%-%->")))
|
||||
vim.cmd('cq')
|
||||
vim.cmd "cq"
|
||||
end
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
-- Execute as `nvim --headless -c "luafile ./scripts/write-lockfile.lua"`
|
||||
local skip_langs = vim.fn.getenv('SKIP_LOCKFILE_UPDATE_FOR_LANGS')
|
||||
local skip_langs = vim.fn.getenv "SKIP_LOCKFILE_UPDATE_FOR_LANGS"
|
||||
if skip_langs == vim.NIL then
|
||||
skip_langs = {}
|
||||
else
|
||||
skip_langs = vim.fn.split(skip_langs, ',')
|
||||
skip_langs = vim.fn.split(skip_langs, ",")
|
||||
end
|
||||
print("Skipping languages: "..vim.inspect(skip_langs))
|
||||
require 'nvim-treesitter.install'.write_lockfile('verbose', skip_langs)
|
||||
vim.cmd('q')
|
||||
print("Skipping languages: " .. vim.inspect(skip_langs))
|
||||
require("nvim-treesitter.install").write_lockfile("verbose", skip_langs)
|
||||
vim.cmd "q"
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
local Runner = require('tests.indent.common').Runner
|
||||
local Runner = require("tests.indent.common").Runner
|
||||
|
||||
local runner = Runner:new(it, 'tests/indent/c', {
|
||||
local runner = Runner:new(it, "tests/indent/c", {
|
||||
tabstop = 4,
|
||||
shiftwidth = 4,
|
||||
softtabstop = 0,
|
||||
expandtab = true,
|
||||
})
|
||||
|
||||
describe('indent C:', function()
|
||||
describe('whole file:', function()
|
||||
runner:whole_file('.')
|
||||
describe("indent C:", function()
|
||||
describe("whole file:", function()
|
||||
runner:whole_file "."
|
||||
end)
|
||||
|
||||
describe('new line:', function()
|
||||
runner:new_line('array.c', { on_line = 2, text = '0,', indent = 4 })
|
||||
runner:new_line('cond.c', { on_line = 3, text = 'x++;', indent = 8 })
|
||||
runner:new_line('cond.c', { on_line = 8, text = 'x++;', indent = 8 })
|
||||
runner:new_line('expr.c', { on_line = 10, text = '2 *', indent = 8 })
|
||||
runner:new_line('func.c', { on_line = 17, text = 'int z,', indent = 4 })
|
||||
runner:new_line('label.c', { on_line = 3, text = 'normal:', indent = 0 })
|
||||
runner:new_line('loop.c', { on_line = 3, text = 'x++;', indent = 8 })
|
||||
runner:new_line('preproc_cond.c', { on_line = 5, text = 'x++;', indent = 4 })
|
||||
runner:new_line('preproc_func.c', { on_line = 3, text = 'x++; \\', indent = 8 })
|
||||
runner:new_line('string.c', { on_line = 1, text = 'brave new \\', indent = 0 })
|
||||
runner:new_line('string.c', { on_line = 4, text = '"brave new "', indent = 4 })
|
||||
runner:new_line('struct.c', { on_line = 4, text = 'int y;', indent = 8 })
|
||||
runner:new_line('switch.c', { on_line = 3, text = 'x++;', indent = 12 })
|
||||
runner:new_line('ternary.c', { on_line = 4, text = ': (x == 0) : 0', indent = 8 })
|
||||
describe("new line:", function()
|
||||
runner:new_line("array.c", { on_line = 2, text = "0,", indent = 4 })
|
||||
runner:new_line("cond.c", { on_line = 3, text = "x++;", indent = 8 })
|
||||
runner:new_line("cond.c", { on_line = 8, text = "x++;", indent = 8 })
|
||||
runner:new_line("expr.c", { on_line = 10, text = "2 *", indent = 8 })
|
||||
runner:new_line("func.c", { on_line = 17, text = "int z,", indent = 4 })
|
||||
runner:new_line("label.c", { on_line = 3, text = "normal:", indent = 0 })
|
||||
runner:new_line("loop.c", { on_line = 3, text = "x++;", indent = 8 })
|
||||
runner:new_line("preproc_cond.c", { on_line = 5, text = "x++;", indent = 4 })
|
||||
runner:new_line("preproc_func.c", { on_line = 3, text = "x++; \\", indent = 8 })
|
||||
runner:new_line("string.c", { on_line = 1, text = "brave new \\", indent = 0 })
|
||||
runner:new_line("string.c", { on_line = 4, text = '"brave new "', indent = 4 })
|
||||
runner:new_line("struct.c", { on_line = 4, text = "int y;", indent = 8 })
|
||||
runner:new_line("switch.c", { on_line = 3, text = "x++;", indent = 12 })
|
||||
runner:new_line("ternary.c", { on_line = 4, text = ": (x == 0) : 0", indent = 8 })
|
||||
-- the line after inserted one will be left with wrong indent but we only care about the inserted one
|
||||
runner:new_line('no_braces.c', { on_line = 4, text = 'x++;', indent = 8 })
|
||||
runner:new_line('no_braces.c', { on_line = 7, text = 'x++;', indent = 8 })
|
||||
runner:new_line('no_braces.c', { on_line = 10, text = 'x++;', indent = 8 })
|
||||
runner:new_line("no_braces.c", { on_line = 4, text = "x++;", indent = 8 })
|
||||
runner:new_line("no_braces.c", { on_line = 7, text = "x++;", indent = 8 })
|
||||
runner:new_line("no_braces.c", { on_line = 10, text = "x++;", indent = 8 })
|
||||
end)
|
||||
end)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
local M = {}
|
||||
|
||||
local assert = require('luassert')
|
||||
local say = require('say')
|
||||
local scan_dir = require('plenary.scandir').scan_dir
|
||||
local Path = require('plenary.path')
|
||||
local assert = require "luassert"
|
||||
local say = require "say"
|
||||
local scan_dir = require("plenary.scandir").scan_dir
|
||||
local Path = require "plenary.path"
|
||||
|
||||
local function same_indent(state, arguments)
|
||||
local before = arguments[1]
|
||||
|
@ -11,11 +11,11 @@ local function same_indent(state, arguments)
|
|||
|
||||
local ok = true
|
||||
local errors = { before = {}, after = {} }
|
||||
for line = 1,#before do
|
||||
for line = 1, #before do
|
||||
if before[line] ~= after[line] then
|
||||
-- store the actual indentation length for each line
|
||||
errors.before[line] = #string.match(before[line], '^%s*')
|
||||
errors.after[line] = #string.match(after[line], '^%s*')
|
||||
errors.before[line] = #string.match(before[line], "^%s*")
|
||||
errors.after[line] = #string.match(after[line], "^%s*")
|
||||
ok = false
|
||||
end
|
||||
end
|
||||
|
@ -35,28 +35,33 @@ local function format_indent(arg, fmtargs)
|
|||
end
|
||||
|
||||
width = width + 3
|
||||
local header_fmt = '%8s %2s%-' .. tostring(width + 1) .. 's %s'
|
||||
local fmt = '%8s %2s |%-' .. tostring(width) .. 's |%s'
|
||||
local header_fmt = "%8s %2s%-" .. tostring(width + 1) .. "s %s"
|
||||
local fmt = "%8s %2s |%-" .. tostring(width) .. "s |%s"
|
||||
|
||||
local output = {header_fmt:format('', '', 'Found:', 'Expected:')}
|
||||
local output = { header_fmt:format("", "", "Found:", "Expected:") }
|
||||
|
||||
for i, line in ipairs(arg) do
|
||||
if fmtargs.errors.before[i] then
|
||||
local indents = string.format('%d vs %d', fmtargs.errors.after[i], fmtargs.errors.before[i])
|
||||
table.insert(output, fmt:format(indents, '=>', fmtargs.other[i], line))
|
||||
local indents = string.format("%d vs %d", fmtargs.errors.after[i], fmtargs.errors.before[i])
|
||||
table.insert(output, fmt:format(indents, "=>", fmtargs.other[i], line))
|
||||
else
|
||||
table.insert(output, fmt:format('', '', fmtargs.other[i], line))
|
||||
table.insert(output, fmt:format("", "", fmtargs.other[i], line))
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(output, '\n')
|
||||
return table.concat(output, "\n")
|
||||
end
|
||||
|
||||
say:set_namespace('en')
|
||||
say:set('assertion.same_indent.positive', 'Incorrect indentation\n%s')
|
||||
say:set('assertion.same_indent.negative', 'Incorrect indentation\n%s')
|
||||
assert:register('assertion', 'same_indent', same_indent,
|
||||
'assertion.same_indent.positive', 'assert.same_indent.negative')
|
||||
say:set_namespace "en"
|
||||
say:set("assertion.same_indent.positive", "Incorrect indentation\n%s")
|
||||
say:set("assertion.same_indent.negative", "Incorrect indentation\n%s")
|
||||
assert:register(
|
||||
"assertion",
|
||||
"same_indent",
|
||||
same_indent,
|
||||
"assertion.same_indent.positive",
|
||||
"assert.same_indent.negative"
|
||||
)
|
||||
|
||||
-- Custom assertion better suited for indentation diffs
|
||||
local function compare_indent(before, after)
|
||||
|
@ -66,7 +71,7 @@ local function compare_indent(before, after)
|
|||
end
|
||||
|
||||
local function set_buf_indent_opts(opts)
|
||||
local optnames = {'tabstop', 'shiftwidth', 'softtabstop', 'expandtab', 'filetype'}
|
||||
local optnames = { "tabstop", "shiftwidth", "softtabstop", "expandtab", "filetype" }
|
||||
for _, opt in ipairs(optnames) do
|
||||
if opts[opt] ~= nil then
|
||||
vim.bo[opt] = opts[opt]
|
||||
|
@ -78,10 +83,10 @@ function M.run_indent_test(file, runner, opts)
|
|||
assert.are.same(1, vim.fn.filereadable(file), string.format('File "%s" not readable', file))
|
||||
|
||||
-- load reference file
|
||||
vim.cmd(string.format('edit %s', file))
|
||||
vim.cmd(string.format("edit %s", file))
|
||||
local before = vim.api.nvim_buf_get_lines(0, 0, -1, true)
|
||||
|
||||
assert.are.same('nvim_treesitter#indent()', vim.bo.indentexpr)
|
||||
assert.are.same("nvim_treesitter#indent()", vim.bo.indentexpr)
|
||||
set_buf_indent_opts(opts)
|
||||
|
||||
-- perform the test
|
||||
|
@ -91,14 +96,14 @@ function M.run_indent_test(file, runner, opts)
|
|||
local after = vim.api.nvim_buf_get_lines(0, 0, -1, true)
|
||||
|
||||
-- clear any changes to avoid 'No write since last change (add ! to override)'
|
||||
vim.cmd 'edit!'
|
||||
vim.cmd "edit!"
|
||||
|
||||
return before, after
|
||||
end
|
||||
|
||||
function M.indent_whole_file(file, opts)
|
||||
local before, after = M.run_indent_test(file, function()
|
||||
vim.cmd 'silent normal gg=G'
|
||||
vim.cmd "silent normal gg=G"
|
||||
end, opts)
|
||||
|
||||
compare_indent(before, after)
|
||||
|
@ -114,11 +119,11 @@ end
|
|||
function M.indent_new_line(file, spec, opts)
|
||||
local before, after = M.run_indent_test(file, function()
|
||||
-- move to the line and input the new one
|
||||
vim.cmd(string.format('normal! %dG', spec.on_line))
|
||||
vim.cmd(string.format('normal! o%s', spec.text))
|
||||
vim.cmd(string.format("normal! %dG", spec.on_line))
|
||||
vim.cmd(string.format("normal! o%s", spec.text))
|
||||
end, opts)
|
||||
|
||||
local indent = type(spec.indent) == 'string' and spec.indent or string.rep(' ', spec.indent)
|
||||
local indent = type(spec.indent) == "string" and spec.indent or string.rep(" ", spec.indent)
|
||||
table.insert(before, spec.on_line + 1, indent .. spec.text)
|
||||
|
||||
compare_indent(before, after)
|
||||
|
@ -140,7 +145,7 @@ function Runner:new(it, base_dir, buf_opts)
|
|||
end
|
||||
|
||||
function Runner:whole_file(dirs)
|
||||
dirs = type(dirs) == "table" and dirs or {dirs}
|
||||
dirs = type(dirs) == "table" and dirs or { dirs }
|
||||
dirs = vim.tbl_map(function(dir)
|
||||
dir = self.base_dir / Path:new(dir)
|
||||
assert.is.same(1, vim.fn.isdirectory(dir.filename))
|
||||
|
@ -157,7 +162,7 @@ end
|
|||
|
||||
function Runner:new_line(file, spec, title)
|
||||
title = title and title or tostring(spec.on_line)
|
||||
self.it(string.format('%s[%s]', file, title), function()
|
||||
self.it(string.format("%s[%s]", file, title), function()
|
||||
local path = self.base_dir / file
|
||||
M.indent_new_line(path.filename, spec, self.buf_opts)
|
||||
end)
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
local Runner = require('tests.indent.common').Runner
|
||||
local Runner = require("tests.indent.common").Runner
|
||||
|
||||
-- will use both c/ and cpp/
|
||||
local run = Runner:new(it, 'tests/indent', {
|
||||
local run = Runner:new(it, "tests/indent", {
|
||||
tabstop = 4,
|
||||
shiftwidth = 4,
|
||||
softtabstop = 0,
|
||||
expandtab = true,
|
||||
filetype = 'cpp',
|
||||
filetype = "cpp",
|
||||
})
|
||||
|
||||
describe('indent C++:', function()
|
||||
describe('whole file:', function()
|
||||
run:whole_file({'c/', 'cpp/'})
|
||||
describe("indent C++:", function()
|
||||
describe("whole file:", function()
|
||||
run:whole_file { "c/", "cpp/" }
|
||||
end)
|
||||
|
||||
describe('new line:', function()
|
||||
run:new_line('cpp/access.cpp', { on_line = 3, text = 'protected:', indent = 0 })
|
||||
run:new_line('cpp/class.cpp', { on_line = 2, text = 'using T = int;', indent = 4 })
|
||||
run:new_line('cpp/stream.cpp', { on_line = 5, text = '<< x + 3', indent = 8 })
|
||||
describe("new line:", function()
|
||||
run:new_line("cpp/access.cpp", { on_line = 3, text = "protected:", indent = 0 })
|
||||
run:new_line("cpp/class.cpp", { on_line = 2, text = "using T = int;", indent = 4 })
|
||||
run:new_line("cpp/stream.cpp", { on_line = 5, text = "<< x + 3", indent = 8 })
|
||||
|
||||
-- TODO: find a clean way to import these from c_spec.lua
|
||||
run:new_line('c/array.c', { on_line = 2, text = '0,', indent = 4 })
|
||||
run:new_line('c/cond.c', { on_line = 3, text = 'x++;', indent = 8 })
|
||||
run:new_line('c/cond.c', { on_line = 8, text = 'x++;', indent = 8 })
|
||||
run:new_line('c/expr.c', { on_line = 10, text = '2 *', indent = 8 })
|
||||
run:new_line('c/func.c', { on_line = 17, text = 'int z,', indent = 4 })
|
||||
run:new_line('c/label.c', { on_line = 3, text = 'normal:', indent = 0 })
|
||||
run:new_line('c/loop.c', { on_line = 3, text = 'x++;', indent = 8 })
|
||||
run:new_line('c/preproc_cond.c', { on_line = 5, text = 'x++;', indent = 4 })
|
||||
run:new_line('c/preproc_func.c', { on_line = 3, text = 'x++; \\', indent = 8 })
|
||||
run:new_line('c/string.c', { on_line = 1, text = 'brave new \\', indent = 0 })
|
||||
run:new_line('c/string.c', { on_line = 4, text = '"brave new "', indent = 4 })
|
||||
run:new_line('c/struct.c', { on_line = 4, text = 'int y;', indent = 8 })
|
||||
run:new_line('c/switch.c', { on_line = 3, text = 'x++;', indent = 12 })
|
||||
run:new_line('c/ternary.c', { on_line = 4, text = ': (x == 0) : 0', indent = 8 })
|
||||
run:new_line("c/array.c", { on_line = 2, text = "0,", indent = 4 })
|
||||
run:new_line("c/cond.c", { on_line = 3, text = "x++;", indent = 8 })
|
||||
run:new_line("c/cond.c", { on_line = 8, text = "x++;", indent = 8 })
|
||||
run:new_line("c/expr.c", { on_line = 10, text = "2 *", indent = 8 })
|
||||
run:new_line("c/func.c", { on_line = 17, text = "int z,", indent = 4 })
|
||||
run:new_line("c/label.c", { on_line = 3, text = "normal:", indent = 0 })
|
||||
run:new_line("c/loop.c", { on_line = 3, text = "x++;", indent = 8 })
|
||||
run:new_line("c/preproc_cond.c", { on_line = 5, text = "x++;", indent = 4 })
|
||||
run:new_line("c/preproc_func.c", { on_line = 3, text = "x++; \\", indent = 8 })
|
||||
run:new_line("c/string.c", { on_line = 1, text = "brave new \\", indent = 0 })
|
||||
run:new_line("c/string.c", { on_line = 4, text = '"brave new "', indent = 4 })
|
||||
run:new_line("c/struct.c", { on_line = 4, text = "int y;", indent = 8 })
|
||||
run:new_line("c/switch.c", { on_line = 3, text = "x++;", indent = 12 })
|
||||
run:new_line("c/ternary.c", { on_line = 4, text = ": (x == 0) : 0", indent = 8 })
|
||||
-- the line after inserted one will be left with wrong indent but we only care about the inserted one
|
||||
run:new_line('c/no_braces.c', { on_line = 4, text = 'x++;', indent = 8 })
|
||||
run:new_line('c/no_braces.c', { on_line = 7, text = 'x++;', indent = 8 })
|
||||
run:new_line('c/no_braces.c', { on_line = 10, text = 'x++;', indent = 8 })
|
||||
run:new_line("c/no_braces.c", { on_line = 4, text = "x++;", indent = 8 })
|
||||
run:new_line("c/no_braces.c", { on_line = 7, text = "x++;", indent = 8 })
|
||||
run:new_line("c/no_braces.c", { on_line = 10, text = "x++;", indent = 8 })
|
||||
end)
|
||||
end)
|
||||
|
|
|
@ -1,35 +1,33 @@
|
|||
local Runner = require('tests.indent.common').Runner
|
||||
local Runner = require("tests.indent.common").Runner
|
||||
|
||||
local run = Runner:new(it, 'tests/indent/lua', {
|
||||
local run = Runner:new(it, "tests/indent/lua", {
|
||||
tabstop = 2,
|
||||
shiftwidth = 2,
|
||||
softtabstop = 0,
|
||||
expandtab = true,
|
||||
})
|
||||
|
||||
|
||||
describe('indent Lua:', function()
|
||||
describe('whole file:', function()
|
||||
run:whole_file('.')
|
||||
describe("indent Lua:", function()
|
||||
describe("whole file:", function()
|
||||
run:whole_file "."
|
||||
end)
|
||||
|
||||
describe('new line:', function()
|
||||
run:new_line('comment.lua', { on_line = 1, text = 'line', indent = '-- ' })
|
||||
run:new_line('comment.lua', { on_line = 5, text = 'multiline', indent = ' ' })
|
||||
run:new_line('func.lua', { on_line = 1, text = 'x = x + 1', indent = 2 })
|
||||
run:new_line('func.lua', { on_line = 2, text = 'y = y + 1', indent = 4 })
|
||||
run:new_line('func.lua', { on_line = 5, text = '3,', indent = 4 })
|
||||
run:new_line('string.lua', { on_line = 1, text = 'x', indent = 0 })
|
||||
run:new_line('string.lua', { on_line = 2, text = 'x', indent = 0 })
|
||||
run:new_line('string.lua', { on_line = 3, text = 'x', indent = 2 })
|
||||
run:new_line('string.lua', { on_line = 4, text = 'x', indent = 4 })
|
||||
run:new_line('table.lua', { on_line = 1, text = 'b = 0,', indent = 2 })
|
||||
run:new_line('table.lua', { on_line = 5, text = '4,', indent = 4 })
|
||||
run:new_line('table.lua', { on_line = 7, text = '4,', indent = 4 })
|
||||
run:new_line('loop.lua', { on_line = 4, text = 'x = x + 1', indent = 2 })
|
||||
run:new_line('cond.lua', { on_line = 5, text = 'x = x + 1', indent = 2 })
|
||||
run:new_line('cond.lua', { on_line = 7, text = 'x = x + 1', indent = 2 })
|
||||
run:new_line('cond.lua', { on_line = 8, text = 'x = x + 1', indent = 4 })
|
||||
describe("new line:", function()
|
||||
run:new_line("comment.lua", { on_line = 1, text = "line", indent = "-- " })
|
||||
run:new_line("comment.lua", { on_line = 5, text = "multiline", indent = " " })
|
||||
run:new_line("func.lua", { on_line = 1, text = "x = x + 1", indent = 2 })
|
||||
run:new_line("func.lua", { on_line = 2, text = "y = y + 1", indent = 4 })
|
||||
run:new_line("func.lua", { on_line = 5, text = "3,", indent = 4 })
|
||||
run:new_line("string.lua", { on_line = 1, text = "x", indent = 0 })
|
||||
run:new_line("string.lua", { on_line = 2, text = "x", indent = 0 })
|
||||
run:new_line("string.lua", { on_line = 3, text = "x", indent = 2 })
|
||||
run:new_line("string.lua", { on_line = 4, text = "x", indent = 4 })
|
||||
run:new_line("table.lua", { on_line = 1, text = "b = 0,", indent = 2 })
|
||||
run:new_line("table.lua", { on_line = 5, text = "4,", indent = 4 })
|
||||
run:new_line("table.lua", { on_line = 7, text = "4,", indent = 4 })
|
||||
run:new_line("loop.lua", { on_line = 4, text = "x = x + 1", indent = 2 })
|
||||
run:new_line("cond.lua", { on_line = 5, text = "x = x + 1", indent = 2 })
|
||||
run:new_line("cond.lua", { on_line = 7, text = "x = x + 1", indent = 2 })
|
||||
run:new_line("cond.lua", { on_line = 8, text = "x = x + 1", indent = 4 })
|
||||
end)
|
||||
end)
|
||||
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
local Runner = require('tests.indent.common').Runner
|
||||
local Runner = require("tests.indent.common").Runner
|
||||
|
||||
local run = Runner:new(it, 'tests/indent/python', {
|
||||
local run = Runner:new(it, "tests/indent/python", {
|
||||
tabstop = 4,
|
||||
shiftwidth = 4,
|
||||
softtabstop = 0,
|
||||
expandtab = true,
|
||||
})
|
||||
|
||||
describe('indent Python:', function()
|
||||
describe('whole file:', function()
|
||||
run:whole_file('.')
|
||||
describe("indent Python:", function()
|
||||
describe("whole file:", function()
|
||||
run:whole_file "."
|
||||
end)
|
||||
|
||||
describe('new line:', function()
|
||||
run:new_line('aligned_indent.py', { on_line = 1, text = 'arg3,', indent = 19 })
|
||||
run:new_line('basic_blocks.py', { on_line = 1, text = 'wait,', indent = 4 })
|
||||
run:new_line('basic_blocks.py', { on_line = 6, text = 'x += 1', indent = 4 })
|
||||
run:new_line('basic_blocks.py', { on_line = 10, text = 'x += 1', indent = 8 })
|
||||
run:new_line('basic_blocks.py', { on_line = 7, text = 'x += 1', indent = 4 }, '7, after last line of a block')
|
||||
run:new_line('basic_blocks.py', { on_line = 11, text = 'x += 1', indent = 8 }, '11, after last line of a block')
|
||||
run:new_line('basic_collections.py', { on_line = 3, text = '4,', indent = 4 })
|
||||
run:new_line('comprehensions.py', { on_line = 8, text = 'if x != 2', indent = 4 })
|
||||
run:new_line('control_flow.py', { on_line = 23, text = 'x = 4', indent = 4 })
|
||||
run:new_line('hanging_indent.py', { on_line = 1, text = 'arg0,', indent = 8 })
|
||||
run:new_line('hanging_indent.py', { on_line = 5, text = '0,', indent = 4 })
|
||||
run:new_line('join_lines.py', { on_line = 1, text = '+ 1 \\', indent = 4 })
|
||||
run:new_line('join_lines.py', { on_line = 4, text = '+ 1 \\', indent = 4 })
|
||||
run:new_line('join_lines.py', { on_line = 7, text = '+ 1 \\', indent = 4 })
|
||||
run:new_line('nested_collections.py', { on_line = 5, text = '0,', indent = 12 })
|
||||
run:new_line('nested_collections.py', { on_line = 6, text = ',0', indent = 12 })
|
||||
run:new_line('nested_collections.py', { on_line = 29, text = '[1, 2],', indent = 12 })
|
||||
run:new_line('nested_collections.py', { on_line = 39, text = '0,', indent = 5 })
|
||||
run:new_line('strings.py', { on_line = 14, text = 'x', indent = 4 })
|
||||
run:new_line('strings.py', { on_line = 15, text = 'x', indent = 0 })
|
||||
run:new_line('strings.py', { on_line = 16, text = 'x', indent = 8 })
|
||||
describe("new line:", function()
|
||||
run:new_line("aligned_indent.py", { on_line = 1, text = "arg3,", indent = 19 })
|
||||
run:new_line("basic_blocks.py", { on_line = 1, text = "wait,", indent = 4 })
|
||||
run:new_line("basic_blocks.py", { on_line = 6, text = "x += 1", indent = 4 })
|
||||
run:new_line("basic_blocks.py", { on_line = 10, text = "x += 1", indent = 8 })
|
||||
run:new_line("basic_blocks.py", { on_line = 7, text = "x += 1", indent = 4 }, "7, after last line of a block")
|
||||
run:new_line("basic_blocks.py", { on_line = 11, text = "x += 1", indent = 8 }, "11, after last line of a block")
|
||||
run:new_line("basic_collections.py", { on_line = 3, text = "4,", indent = 4 })
|
||||
run:new_line("comprehensions.py", { on_line = 8, text = "if x != 2", indent = 4 })
|
||||
run:new_line("control_flow.py", { on_line = 23, text = "x = 4", indent = 4 })
|
||||
run:new_line("hanging_indent.py", { on_line = 1, text = "arg0,", indent = 8 })
|
||||
run:new_line("hanging_indent.py", { on_line = 5, text = "0,", indent = 4 })
|
||||
run:new_line("join_lines.py", { on_line = 1, text = "+ 1 \\", indent = 4 })
|
||||
run:new_line("join_lines.py", { on_line = 4, text = "+ 1 \\", indent = 4 })
|
||||
run:new_line("join_lines.py", { on_line = 7, text = "+ 1 \\", indent = 4 })
|
||||
run:new_line("nested_collections.py", { on_line = 5, text = "0,", indent = 12 })
|
||||
run:new_line("nested_collections.py", { on_line = 6, text = ",0", indent = 12 })
|
||||
run:new_line("nested_collections.py", { on_line = 29, text = "[1, 2],", indent = 12 })
|
||||
run:new_line("nested_collections.py", { on_line = 39, text = "0,", indent = 5 })
|
||||
run:new_line("strings.py", { on_line = 14, text = "x", indent = 4 })
|
||||
run:new_line("strings.py", { on_line = 15, text = "x", indent = 0 })
|
||||
run:new_line("strings.py", { on_line = 16, text = "x", indent = 8 })
|
||||
end)
|
||||
end)
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
local Runner = require('tests.indent.common').Runner
|
||||
local Runner = require("tests.indent.common").Runner
|
||||
|
||||
local run = Runner:new(it, 'tests/indent/rust', {
|
||||
local run = Runner:new(it, "tests/indent/rust", {
|
||||
tabstop = 4,
|
||||
shiftwidth = 4,
|
||||
softtabstop = 0,
|
||||
expandtab = true,
|
||||
})
|
||||
|
||||
describe('indent Rust:', function()
|
||||
describe('whole file:', function()
|
||||
run:whole_file('.')
|
||||
describe("indent Rust:", function()
|
||||
describe("whole file:", function()
|
||||
run:whole_file "."
|
||||
end)
|
||||
|
||||
describe('new line:', function()
|
||||
run:new_line('array.rs', { on_line = 2, text = '0,', indent = 4 })
|
||||
run:new_line('array.rs', { on_line = 8, text = '0,', indent = 8 })
|
||||
run:new_line('comment.rs', { on_line = 3, text = 'a', indent = '/// ' })
|
||||
run:new_line('cond.rs', { on_line = 11, text = 'x += 1;', indent = 12 })
|
||||
run:new_line('cond.rs', { on_line = 2, text = 'x += 1;', indent = 8 })
|
||||
run:new_line('cond.rs', { on_line = 4, text = 'x += 1;', indent = 8 })
|
||||
run:new_line('cond.rs', { on_line = 6, text = 'x += 1;', indent = 8 })
|
||||
run:new_line('enum.rs', { on_line = 2, text = 'Q,', indent = 4 })
|
||||
run:new_line('enum.rs', { on_line = 4, text = 'i32,', indent = 8 })
|
||||
run:new_line('enum.rs', { on_line = 8, text = 'z: u32,', indent = 8 })
|
||||
run:new_line('func.rs', { on_line = 1, text = 'let _x = 1;', indent = 4 })
|
||||
run:new_line('func.rs', { on_line = 6, text = 'z: i32,', indent = 4 })
|
||||
run:new_line('impl.rs', { on_line = 3, text = 'const FOO: u32 = 1;', indent = 4 })
|
||||
run:new_line('impl.rs', { on_line = 4, text = 'let _x = 1;', indent = 8 })
|
||||
run:new_line('loop.rs', { on_line = 10, text = 'x += 1;', indent = 8 })
|
||||
run:new_line('loop.rs', { on_line = 2, text = 'x += 1;', indent = 8 })
|
||||
run:new_line('loop.rs', { on_line = 6, text = 'x += 1;', indent = 8 })
|
||||
run:new_line('macro.rs', { on_line = 1, text = '() => {},', indent = 4 })
|
||||
run:new_line('macro.rs', { on_line = 12, text = 'B C', indent = 4 })
|
||||
run:new_line('macro.rs', { on_line = 2, text = 'struct $c;', indent = 8 })
|
||||
run:new_line('match.rs', { on_line = 2, text = '-1 => -1,', indent = 8 })
|
||||
run:new_line('match.rs', { on_line = 7, text = 'let y = 1;', indent = 12 })
|
||||
run:new_line('mod.rs', { on_line = 1, text = 'const Z: i32 = 1;', indent = 4 })
|
||||
run:new_line('mod.rs', { on_line = 2, text = 'const Z: i32 = 1;', indent = 4 })
|
||||
run:new_line('mod.rs', { on_line = 6, text = 'const Z: i32 = 1;', indent = 8 })
|
||||
run:new_line('string.rs', { on_line = 2, text = 'brave new', indent = 0 })
|
||||
run:new_line('string.rs', { on_line = 5, text = 'brave new \\', indent = 8 })
|
||||
run:new_line('string.rs', { on_line = 9, text = 'brave new \\', indent = 8 })
|
||||
run:new_line('struct.rs', { on_line = 1, text = 'z: i32,', indent = 4 })
|
||||
run:new_line('struct.rs', { on_line = 2, text = 'z: i32,', indent = 4 })
|
||||
run:new_line('trait.rs', { on_line = 4, text = 'fn baz();', indent = 4 })
|
||||
run:new_line('trait.rs', { on_line = 7, text = 'fn baz();', indent = 4 })
|
||||
run:new_line('trait.rs', { on_line = 8, text = '()', indent = 8 })
|
||||
run:new_line('where.rs', { on_line = 17, text = 'T: Debug,', indent = 4 })
|
||||
run:new_line('where.rs', { on_line = 2, text = 'T: Debug,', indent = 4 })
|
||||
run:new_line('where.rs', { on_line = 9, text = 'T: Debug,', indent = 4 })
|
||||
describe("new line:", function()
|
||||
run:new_line("array.rs", { on_line = 2, text = "0,", indent = 4 })
|
||||
run:new_line("array.rs", { on_line = 8, text = "0,", indent = 8 })
|
||||
run:new_line("comment.rs", { on_line = 3, text = "a", indent = "/// " })
|
||||
run:new_line("cond.rs", { on_line = 11, text = "x += 1;", indent = 12 })
|
||||
run:new_line("cond.rs", { on_line = 2, text = "x += 1;", indent = 8 })
|
||||
run:new_line("cond.rs", { on_line = 4, text = "x += 1;", indent = 8 })
|
||||
run:new_line("cond.rs", { on_line = 6, text = "x += 1;", indent = 8 })
|
||||
run:new_line("enum.rs", { on_line = 2, text = "Q,", indent = 4 })
|
||||
run:new_line("enum.rs", { on_line = 4, text = "i32,", indent = 8 })
|
||||
run:new_line("enum.rs", { on_line = 8, text = "z: u32,", indent = 8 })
|
||||
run:new_line("func.rs", { on_line = 1, text = "let _x = 1;", indent = 4 })
|
||||
run:new_line("func.rs", { on_line = 6, text = "z: i32,", indent = 4 })
|
||||
run:new_line("impl.rs", { on_line = 3, text = "const FOO: u32 = 1;", indent = 4 })
|
||||
run:new_line("impl.rs", { on_line = 4, text = "let _x = 1;", indent = 8 })
|
||||
run:new_line("loop.rs", { on_line = 10, text = "x += 1;", indent = 8 })
|
||||
run:new_line("loop.rs", { on_line = 2, text = "x += 1;", indent = 8 })
|
||||
run:new_line("loop.rs", { on_line = 6, text = "x += 1;", indent = 8 })
|
||||
run:new_line("macro.rs", { on_line = 1, text = "() => {},", indent = 4 })
|
||||
run:new_line("macro.rs", { on_line = 12, text = "B C", indent = 4 })
|
||||
run:new_line("macro.rs", { on_line = 2, text = "struct $c;", indent = 8 })
|
||||
run:new_line("match.rs", { on_line = 2, text = "-1 => -1,", indent = 8 })
|
||||
run:new_line("match.rs", { on_line = 7, text = "let y = 1;", indent = 12 })
|
||||
run:new_line("mod.rs", { on_line = 1, text = "const Z: i32 = 1;", indent = 4 })
|
||||
run:new_line("mod.rs", { on_line = 2, text = "const Z: i32 = 1;", indent = 4 })
|
||||
run:new_line("mod.rs", { on_line = 6, text = "const Z: i32 = 1;", indent = 8 })
|
||||
run:new_line("string.rs", { on_line = 2, text = "brave new", indent = 0 })
|
||||
run:new_line("string.rs", { on_line = 5, text = "brave new \\", indent = 8 })
|
||||
run:new_line("string.rs", { on_line = 9, text = "brave new \\", indent = 8 })
|
||||
run:new_line("struct.rs", { on_line = 1, text = "z: i32,", indent = 4 })
|
||||
run:new_line("struct.rs", { on_line = 2, text = "z: i32,", indent = 4 })
|
||||
run:new_line("trait.rs", { on_line = 4, text = "fn baz();", indent = 4 })
|
||||
run:new_line("trait.rs", { on_line = 7, text = "fn baz();", indent = 4 })
|
||||
run:new_line("trait.rs", { on_line = 8, text = "()", indent = 8 })
|
||||
run:new_line("where.rs", { on_line = 17, text = "T: Debug,", indent = 4 })
|
||||
run:new_line("where.rs", { on_line = 2, text = "T: Debug,", indent = 4 })
|
||||
run:new_line("where.rs", { on_line = 9, text = "T: Debug,", indent = 4 })
|
||||
end)
|
||||
end)
|
||||
|
|
Loading…
Reference in a new issue