neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

health.lua (3268B)


      1 local M = {}
      2 local ts = vim.treesitter
      3 local health = vim.health
      4 
      5 --- Performs a healthcheck for treesitter integration
      6 function M.check()
      7  health.start('Treesitter features')
      8 
      9  health.info(
     10    string.format(
     11      'Treesitter ABI support: min %d, max %d',
     12      ts.minimum_language_version,
     13      ts.language_version
     14    )
     15  )
     16 
     17  local can_wasm = vim._ts_add_language_from_wasm ~= nil
     18  health.info(string.format('WASM parser support: %s', tostring(can_wasm)))
     19 
     20  health.start('Treesitter parsers')
     21  local parsers = vim.api.nvim_get_runtime_file('parser/*', true)
     22 
     23  ---@class ParserEntry
     24  ---@field name string
     25  ---@field path string
     26  ---@field index integer runtime path index (unique)
     27 
     28  local sorted_parsers = {} ---@type ParserEntry[]
     29 
     30  for i, parser in ipairs(parsers) do
     31    local parsername = vim.fn.fnamemodify(parser, ':t:r')
     32    table.insert(sorted_parsers, { name = parsername, path = parser, index = i })
     33  end
     34 
     35  table.sort(sorted_parsers, function(a, b)
     36    if a.name == b.name then
     37      return a.index < b.index -- if names are the same sort by rtpath index (unique)
     38    else
     39      return a.name < b.name
     40    end
     41  end)
     42 
     43  for i, parser in ipairs(sorted_parsers) do
     44    local is_loadable, err_or_nil = pcall(ts.language.add, parser.name)
     45 
     46    if not is_loadable then
     47      health.error(
     48        string.format(
     49          'Parser "%s" failed to load (path: %s): %s',
     50          parser.name,
     51          parser.path,
     52          err_or_nil or '?'
     53        )
     54      )
     55    elseif i > 1 and sorted_parsers[i - 1].name == parser.name then
     56      -- Sorted by runtime path order (load order), thus, if the previous parser has the same name,
     57      -- the current parser will not be loaded and `ts.language.inspect(parser.name)` with have
     58      -- incorrect information.
     59      health.ok(string.format('Parser: %-20s (not loaded), path: %s', parser.name, parser.path))
     60    else
     61      local lang = ts.language.inspect(parser.name)
     62      health.ok(
     63        string.format('Parser: %-25s ABI: %d, path: %s', parser.name, lang.abi_version, parser.path)
     64      )
     65    end
     66  end
     67 
     68  health.start('Treesitter queries')
     69  local query_files = vim.api.nvim_get_runtime_file('queries/**/*.scm', true)
     70 
     71  ---@class QueryEntry
     72  ---@field lang string
     73  ---@field type string
     74  ---@field path string
     75  ---@field index integer
     76  local queries_by_lang = {} ---@type table<string, QueryEntry[]>
     77 
     78  for i, query_file in ipairs(query_files) do
     79    local lang, query_type = query_file:match('queries/([^/]+)/([^/]+)%.scm$')
     80    if lang and query_type then
     81      if not queries_by_lang[lang] then
     82        queries_by_lang[lang] = {}
     83      end
     84      table.insert(queries_by_lang[lang], {
     85        lang = lang,
     86        type = query_type,
     87        path = query_file,
     88        index = i,
     89      })
     90    end
     91  end
     92 
     93  if not vim.tbl_isempty(queries_by_lang) then
     94    for lang, queries in vim.spairs(queries_by_lang) do
     95      table.sort(queries, function(a, b)
     96        if a.type == b.type then
     97          return a.index < b.index
     98        else
     99          return a.type < b.type
    100        end
    101      end)
    102 
    103      for _, query in ipairs(queries) do
    104        local dir = vim.fs.dirname(query.path)
    105        health.ok(string.format('%-15s %-15s %s', lang, query.type, dir))
    106      end
    107    end
    108  end
    109 end
    110 
    111 return M