mirror of
https://github.com/HiPhish/rainbow-delimiters.nvim.git
synced 2024-09-16 14:24:05 +02:00
Merge branch 'LuaLS'
This commit is contained in:
commit
a2da59bdac
15 changed files with 369 additions and 54 deletions
|
@ -27,3 +27,11 @@ following criteria:
|
|||
|
||||
If there are many test cases or if the code becomes too verbose feel free to
|
||||
create multiple test files.
|
||||
|
||||
In addition to the queries and test file(s), please consider adding the type
|
||||
annotations in `lua/rainbow-delimiters.types.lua` if you are adding queries
|
||||
for a new language. You will need to update:
|
||||
|
||||
- `@class rainbow_delimiters.config.strategies`
|
||||
- `@class rainbow_delimiters.config.queries`
|
||||
- `@alias rainbow_delimiters.language`
|
||||
|
|
|
@ -50,7 +50,7 @@ Configuration is done by setting entries in the Vim script dictionary
|
|||
\ 'RainbowDelimiterGreen',
|
||||
\ 'RainbowDelimiterViolet',
|
||||
\ 'RainbowDelimiterCyan',
|
||||
\ ],
|
||||
\ ],
|
||||
\ }
|
||||
|
||||
The equivalent code in Lua:
|
||||
|
@ -60,6 +60,7 @@ The equivalent code in Lua:
|
|||
-- This module contains a number of default definitions
|
||||
local rainbow_delimiters = require 'rainbow-delimiters'
|
||||
|
||||
---@type rainbow_delimiters.config
|
||||
vim.g.rainbow_delimiters = {
|
||||
strategy = {
|
||||
[''] = rainbow_delimiters.strategy['global'],
|
||||
|
@ -87,7 +88,7 @@ same parameters as `g:rainbow-delimiters`.
|
|||
.. code:: lua
|
||||
|
||||
require('rainbow-delimiters.setup').setup {
|
||||
strategy = {
|
||||
strategy = {
|
||||
-- ...
|
||||
},
|
||||
query = {
|
||||
|
|
|
@ -108,6 +108,7 @@ Alternatively, the same configuration in Lua:
|
|||
-- This module contains a number of default definitions
|
||||
local rainbow_delimiters = require 'rainbow-delimiters'
|
||||
|
||||
---@type rainbow_delimiters.config
|
||||
vim.g.rainbow_delimiters = {
|
||||
strategy = {
|
||||
[''] = rainbow_delimiters.strategy['global'],
|
||||
|
@ -423,9 +424,9 @@ object-oriented terminology we would say that a strategy table must implement
|
|||
the strategy protocol.
|
||||
>
|
||||
strategy = {
|
||||
on_attach = function(bufnr: number, settings: table),
|
||||
on_detach = function(bufnr: string),
|
||||
on_reset = function(bufnr: number, settings: table),
|
||||
on_attach = function(bufnr: integer, settings: table),
|
||||
on_detach = function(bufnr: integer),
|
||||
on_reset = function(bufnr: integer, settings: table),
|
||||
}
|
||||
<
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
local lib = require 'rainbow-delimiters.lib'
|
||||
|
||||
---Disable rainbow delimiters for a given buffer.
|
||||
---@param bufnr number Buffer number, zero for current buffer.
|
||||
---@param bufnr integer Buffer number, zero for current buffer.
|
||||
local function disable(bufnr)
|
||||
if not bufnr or bufnr == 0 then bufnr = vim.api.nvim_get_current_buf() end
|
||||
lib.detach(bufnr)
|
||||
|
@ -26,13 +26,15 @@ local function disable(bufnr)
|
|||
end
|
||||
|
||||
---Enable rainbow delimiters for a given buffer.
|
||||
---@param bufnr number Buffer number, zero for current buffer.
|
||||
---@param bufnr integer Buffer number, zero for current buffer.
|
||||
local function enable(bufnr)
|
||||
if not bufnr or bufnr == 0 then bufnr = vim.api.nvim_get_current_buf() end
|
||||
lib.buffers[bufnr] = nil
|
||||
lib.attach(bufnr)
|
||||
end
|
||||
|
||||
---Toggle rainbow delimiters for a given buffer.
|
||||
---@param bufnr integer Buffer number, zero for current buffer.
|
||||
local function toggle(bufnr)
|
||||
if not bufnr or bufnr == 0 then bufnr = vim.api.nvim_get_current_buf() end
|
||||
if lib.buffers[bufnr] then
|
||||
|
@ -47,8 +49,11 @@ local M = {
|
|||
hlgroup_at = lib.hlgroup_at,
|
||||
---Available default highlight strategies
|
||||
strategy = {
|
||||
---Global highlighting strategy
|
||||
['global'] = require 'rainbow-delimiters.strategy.global',
|
||||
---Local highlighting strategy
|
||||
['local'] = require 'rainbow-delimiters.strategy.local',
|
||||
---Empty highlighting strategy for testing
|
||||
['noop'] = require 'rainbow-delimiters.strategy.no-op',
|
||||
},
|
||||
enable = enable,
|
||||
|
|
229
lua/rainbow-delimiters.types.lua
Normal file
229
lua/rainbow-delimiters.types.lua
Normal file
|
@ -0,0 +1,229 @@
|
|||
---@meta
|
||||
|
||||
|
||||
--# Utility Library #--
|
||||
|
||||
---Strategy to use for highlighting with rainbow-delimiters
|
||||
---Must implement `on_attach`, `on_detach` and `on_reset`
|
||||
---@class rainbow_delimiters.strategy
|
||||
---`on_attach`: setup the highlighting on attach
|
||||
---@field on_attach fun(bufnr: integer, settings: rainbow_delimiters.buffer_settings)
|
||||
---`on_detach`: remove any unneccesary remaining setup on detach
|
||||
---@field on_detach fun(bufnr: integer)
|
||||
---`on_reset`: update the highlighting on reset
|
||||
---@field on_reset fun(bufnr: integer, settings: rainbow_delimiters.buffer_settings)
|
||||
|
||||
---@class (exact) rainbow_delimiters.buffer_settings
|
||||
---@field strategy rainbow_delimiters.strategy
|
||||
---@field parser LanguageTree
|
||||
---@field lang string
|
||||
|
||||
|
||||
--# Config #--
|
||||
|
||||
---Configuration table for rainbow-delimiters
|
||||
---@class (exact) rainbow_delimiters.config
|
||||
---Strategy to use for highlighting
|
||||
---@field strategy rainbow_delimiters.config.strategies?
|
||||
---Query to use for highlighting
|
||||
---@field query rainbow_delimiters.config.queries?
|
||||
---Highlight colors
|
||||
---@field highlight string[]?
|
||||
---Whitelist for languages to highlight
|
||||
---@field whitelist rainbow_delimiters.language[]?
|
||||
---Blacklist for languages not to highlight
|
||||
---@field blacklist rainbow_delimiters.language[]?
|
||||
---Logging with log file and log level
|
||||
---@field log rainbow_delimiters.logging?
|
||||
|
||||
---@class rainbow_delimiters.config.strategies
|
||||
---@field [''] (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field astro (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field bash (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field c (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field c_sharp (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field clojure (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field commonlisp (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field cpp (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field css (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field cuda (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field cue (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field dart (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field elixir (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field elm (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field fennel (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field fish (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field go (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field haskell (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field hcl (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field html (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field janet_simple (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field java (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field javascript (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field json (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field json5 (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field jsonc (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field jsonnet (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field julia (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field kotlin (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field latex (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field lua (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field luadoc (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field make (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field markdown (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field nim (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field nix (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field perl (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field php (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field python (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field query (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field r (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field racket (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field regex (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field rst (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field ruby (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field rust (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field scheme (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field scss (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field sql (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field templ (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field toml (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field tsx (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field typescript (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field verilog (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field vim (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field vimdoc (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field vue (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field yaml (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---@field zig (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
---User defined language, not part of rainbow_delimiters support
|
||||
---@field [string] (rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?)?
|
||||
|
||||
---@class rainbow_delimiters.config.queries
|
||||
---@field [''] ('rainbow-delimiters' | string)?
|
||||
---@field astro ('rainbow-delimiters' | string)?
|
||||
---@field bash ('rainbow-delimiters' | string)?
|
||||
---@field c ('rainbow-delimiters' | string)?
|
||||
---@field c_sharp ('rainbow-delimiters' | string)?
|
||||
---@field clojure ('rainbow-delimiters' | string)?
|
||||
---@field commonlisp ('rainbow-delimiters' | string)?
|
||||
---@field cpp ('rainbow-delimiters' | string)?
|
||||
---@field css ('rainbow-delimiters' | string)?
|
||||
---@field cuda ('rainbow-delimiters' | string)?
|
||||
---@field cue ('rainbow-delimiters' | string)?
|
||||
---@field dart ('rainbow-delimiters' | string)?
|
||||
---@field elixir ('rainbow-delimiters' | string)?
|
||||
---@field elm ('rainbow-delimiters' | string)?
|
||||
---@field fennel ('rainbow-delimiters' | string)?
|
||||
---@field fish ('rainbow-delimiters' | string)?
|
||||
---@field go ('rainbow-delimiters' | string)?
|
||||
---@field haskell ('rainbow-delimiters' | string)?
|
||||
---@field hcl ('rainbow-delimiters' | string)?
|
||||
---@field html ('rainbow-delimiters' | string)?
|
||||
---@field janet_simple ('rainbow-delimiters' | string)?
|
||||
---@field java ('rainbow-delimiters' | string)?
|
||||
---@field javascript ('rainbow-delimiters' | 'rainbow-parens' | 'rainbow-delimiters-react' | string)?
|
||||
---@field json ('rainbow-delimiters' | string)?
|
||||
---@field json5 ('rainbow-delimiters' | string)?
|
||||
---@field jsonc ('rainbow-delimiters' | string)?
|
||||
---@field jsonnet ('rainbow-delimiters' | string)?
|
||||
---@field julia ('rainbow-delimiters' | string)?
|
||||
---@field kotlin ('rainbow-delimiters' | string)?
|
||||
---@field latex ('rainbow-delimiters' | 'rainbow-blocks' | string)?
|
||||
---@field lua ('rainbow-delimiters' | 'rainbow-blocks' | string)?
|
||||
---@field luadoc ('rainbow-delimiters' | string)?
|
||||
---@field make ('rainbow-delimiters' | string)?
|
||||
---@field markdown ('rainbow-delimiters' | string)?
|
||||
---@field nim ('rainbow-delimiters' | string)?
|
||||
---@field nix ('rainbow-delimiters' | string)?
|
||||
---@field perl ('rainbow-delimiters' | string)?
|
||||
---@field php ('rainbow-delimiters' | string)?
|
||||
---@field python ('rainbow-delimiters' | string)?
|
||||
---@field query ('rainbow-delimiters' | string)?
|
||||
---@field r ('rainbow-delimiters' | string)?
|
||||
---@field racket ('rainbow-delimiters' | string)?
|
||||
---@field regex ('rainbow-delimiters' | string)?
|
||||
---@field rst ('rainbow-delimiters' | string)?
|
||||
---@field ruby ('rainbow-delimiters' | string)?
|
||||
---@field rust ('rainbow-delimiters' | string)?
|
||||
---@field scheme ('rainbow-delimiters' | string)?
|
||||
---@field scss ('rainbow-delimiters' | string)?
|
||||
---@field sql ('rainbow-delimiters' | string)?
|
||||
---@field templ ('rainbow-delimiters' | string)?
|
||||
---@field toml ('rainbow-delimiters' | string)?
|
||||
---@field tsx ('rainbow-delimiters' | 'rainbow-parens' | string)?
|
||||
---@field typescript ('rainbow-delimiters' | 'rainbow-parens' | string)?
|
||||
---@field verilog ('rainbow-delimiters' | 'rainbow-blocks' | string)?
|
||||
---@field vim ('rainbow-delimiters' | string)?
|
||||
---@field vimdoc ('rainbow-delimiters' | string)?
|
||||
---@field vue ('rainbow-delimiters' | string)?
|
||||
---@field yaml ('rainbow-delimiters' | string)?
|
||||
---@field zig ('rainbow-delimiters' | string)?
|
||||
---User defined language, not part of rainbow_delimiters support
|
||||
---@field [string] string?
|
||||
|
||||
---@alias rainbow_delimiters.language
|
||||
---| 'astro'
|
||||
---| 'bash'
|
||||
---| 'c'
|
||||
---| 'c_sharp'
|
||||
---| 'clojure'
|
||||
---| 'commonlisp'
|
||||
---| 'cpp'
|
||||
---| 'css'
|
||||
---| 'cuda'
|
||||
---| 'cue'
|
||||
---| 'dart'
|
||||
---| 'elixir'
|
||||
---| 'elm'
|
||||
---| 'fennel'
|
||||
---| 'fish'
|
||||
---| 'go'
|
||||
---| 'haskell'
|
||||
---| 'hcl'
|
||||
---| 'html'
|
||||
---| 'janet_simple'
|
||||
---| 'java'
|
||||
---| 'javascript'
|
||||
---| 'json'
|
||||
---| 'json5'
|
||||
---| 'jsonc'
|
||||
---| 'jsonnet'
|
||||
---| 'julia'
|
||||
---| 'kotlin'
|
||||
---| 'latex'
|
||||
---| 'lua'
|
||||
---| 'luadoc'
|
||||
---| 'make'
|
||||
---| 'markdown'
|
||||
---| 'nim'
|
||||
---| 'nix'
|
||||
---| 'perl'
|
||||
---| 'php'
|
||||
---| 'python'
|
||||
---| 'query'
|
||||
---| 'r'
|
||||
---| 'racket'
|
||||
---| 'regex'
|
||||
---| 'rst'
|
||||
---| 'ruby'
|
||||
---| 'rust'
|
||||
---| 'scheme'
|
||||
---| 'scss'
|
||||
---| 'sql'
|
||||
---| 'templ'
|
||||
---| 'toml'
|
||||
---| 'tsx'
|
||||
---| 'typescript'
|
||||
---| 'verilog'
|
||||
---| 'vim'
|
||||
---| 'vimdoc'
|
||||
---| 'vue'
|
||||
---| 'yaml'
|
||||
---| 'zig'
|
||||
---User defined language, not part of rainbow_delimiters support
|
||||
---| string
|
||||
|
||||
---@class (exact) rainbow_delimiters.logging
|
||||
---@field file ('rainbow_delimiters.log' | string)?
|
||||
---@field level integer
|
|
@ -15,6 +15,7 @@
|
|||
--]]
|
||||
|
||||
---Default plugin configuration.
|
||||
---@type rainbow_delimiters.config
|
||||
local M = {
|
||||
---Query names by file type
|
||||
query = {
|
||||
|
|
|
@ -31,6 +31,8 @@ local schema = {
|
|||
|
||||
|
||||
---Check whether there is a parser installed for the given language.
|
||||
---@param lang string
|
||||
---@return boolean
|
||||
local function check_parser_installed(lang)
|
||||
local success = pcall(vim.treesitter.language.inspect, lang)
|
||||
return success
|
||||
|
@ -41,6 +43,8 @@ end
|
|||
---This is not a 100% reliable check; we only test the type of the argument and
|
||||
---whether the table has the correct fields, but not what the callback
|
||||
---functions actually do.
|
||||
---@param strategy rainbow_delimiters.strategy | fun(): rainbow_delimiters.strategy?
|
||||
---@return boolean
|
||||
local function check_strategy(strategy)
|
||||
if type(strategy) == 'function' then
|
||||
local finfo = debug.getinfo(strategy)
|
||||
|
@ -62,14 +66,20 @@ local function check_strategy(strategy)
|
|||
end
|
||||
|
||||
---Check whether the given query is defined for the given language.
|
||||
---@param lang string
|
||||
---@param name string
|
||||
---@return boolean
|
||||
local function check_query(lang, name)
|
||||
local query = vim.treesitter.query.get(lang, name)
|
||||
return query ~= nil
|
||||
end
|
||||
|
||||
---@param settings rainbow_delimiters.logging
|
||||
local function check_logging(settings)
|
||||
local level, file = settings.level, settings.file
|
||||
if level then
|
||||
-- Note: although the log level is an integer, Lua 5.1 only has the
|
||||
-- number type
|
||||
if type(level) ~= 'number' then
|
||||
error('The log level must be a number', 'See :h vim.log.levels for valid log levels.')
|
||||
else
|
||||
|
@ -102,7 +112,7 @@ end
|
|||
|
||||
|
||||
function M.check()
|
||||
local settings = vim.g.rainbow_delimiters
|
||||
local settings = vim.g.rainbow_delimiters --[[@as rainbow_delimiters.config]]
|
||||
if not settings then
|
||||
return
|
||||
info("No custom configuration; see :h rb-delimiters-setup for information.")
|
||||
|
|
|
@ -55,6 +55,7 @@ M.nsids = setmetatable({}, {
|
|||
---is a table of information about that buffer (e.g. language, strategy,
|
||||
---query). This also makes sure we keep track of all parsers in active use to
|
||||
---prevent them from being garbage-collected.
|
||||
---@type table<integer, rainbow_delimiters.buffer_settings | false>
|
||||
M.buffers = {}
|
||||
|
||||
|
||||
|
@ -78,11 +79,10 @@ function M.get_query(lang)
|
|||
end
|
||||
|
||||
---Apply highlighting to a single node.
|
||||
---@param bufnr number Buffer which contains the node
|
||||
---@param bufnr integer Buffer which contains the node
|
||||
---@param lang string Language of the node (to group HL into namespaces)
|
||||
---@param node table Node to highlight
|
||||
---@param hlgroup string Name of the highlight group to apply.
|
||||
---@return nil
|
||||
function M.highlight(bufnr, lang, node, hlgroup)
|
||||
-- range of the capture, zero-indexed
|
||||
local startRow, startCol, endRow, endCol = node:range()
|
||||
|
@ -103,7 +103,7 @@ end
|
|||
|
||||
|
||||
---Get the appropriate highlight group for the given level of nesting.
|
||||
---@param i number One-based index into the highlight groups
|
||||
---@param i integer One-based index into the highlight groups
|
||||
---@return string hlgroup Name of the highlight groups
|
||||
function M.hlgroup_at(i)
|
||||
local hlgroups = config.highlight
|
||||
|
@ -113,8 +113,10 @@ end
|
|||
|
||||
---Clears the reserved Rainbow namespace.
|
||||
---
|
||||
---@param bufnr number Number of the buffer for which to clear the namespace
|
||||
---@return nil
|
||||
---@param bufnr integer Number of the buffer for which to clear the namespace
|
||||
---@param lang string
|
||||
---@param line_start integer?
|
||||
---@param line_end integer?
|
||||
function M.clear_namespace(bufnr, lang, line_start, line_end)
|
||||
local nsid = M.nsids[lang]
|
||||
if vim.api.nvim_buf_is_valid(bufnr) then
|
||||
|
@ -123,6 +125,7 @@ function M.clear_namespace(bufnr, lang, line_start, line_end)
|
|||
end
|
||||
|
||||
---Start rainbow highlighting for the given buffer
|
||||
---@param bufnr integer
|
||||
function M.attach(bufnr)
|
||||
-- Rainbow delimiters was explicitly disabled for this buffer
|
||||
if M.buffers[bufnr] == false then return end
|
||||
|
@ -175,10 +178,12 @@ function M.attach(bufnr)
|
|||
if not strategy or strategy == vim.NIL then return end
|
||||
|
||||
parser:register_cbs {
|
||||
---@param bnr integer
|
||||
on_detach = function(bnr)
|
||||
if not M.buffers[bnr] then return end
|
||||
M.detach(bufnr)
|
||||
end,
|
||||
---@param child LanguageTree
|
||||
on_child_removed = function(child)
|
||||
M.clear_namespace(bufnr, child:lang())
|
||||
end,
|
||||
|
@ -201,6 +206,7 @@ function M.attach(bufnr)
|
|||
end
|
||||
|
||||
---Start rainbow highlighting for the given buffer
|
||||
---@param bufnr integer
|
||||
function M.detach(bufnr)
|
||||
log.trace('Detaching from buffer %d.', bufnr)
|
||||
if not M.buffers[bufnr] then
|
||||
|
|
|
@ -30,6 +30,7 @@ end
|
|||
|
||||
---Dynamically determines the module from which the log function was called.
|
||||
---If it was called from somewhere else return the name of the plugin.
|
||||
---@return string
|
||||
local function get_module()
|
||||
local module = debug.getinfo(4, 'S').source:match('^.+rainbow%-delimiters/(.+).lua$')
|
||||
if not module then
|
||||
|
@ -38,6 +39,11 @@ local function get_module()
|
|||
return module:gsub('/', '.')
|
||||
end
|
||||
|
||||
---@param file file*
|
||||
---@param level integer
|
||||
---@param module string
|
||||
---@param message any
|
||||
---@param ... any
|
||||
local function write_log(file, level, module, message, ...)
|
||||
local msg
|
||||
local timestamp = date('%FT%H:%M%z')
|
||||
|
@ -50,6 +56,9 @@ local function write_log(file, level, module, message, ...)
|
|||
file:write(string.format('%s %s %s %s\n', timestamp, level, module, msg))
|
||||
end
|
||||
|
||||
---@param level integer
|
||||
---@param message any
|
||||
---@param ... any
|
||||
local function log(level, message, ...)
|
||||
if level < config.log.level then return end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ local M = {}
|
|||
---Apply the given configuration to the rainbow-delimiter settings. Will
|
||||
---overwrite existing settings.
|
||||
---
|
||||
---@param opts table Settings, same format as `vim.g.rainbow_delimiters`
|
||||
---@param opts rainbow_delimiters.config Settings, same format as `vim.g.rainbow_delimiters`
|
||||
function M.setup(opts)
|
||||
vim.g.rainbow_delimiters = opts
|
||||
end
|
||||
|
|
|
@ -17,18 +17,22 @@
|
|||
---Helper library for stack-like tables.
|
||||
local M = {}
|
||||
|
||||
---@class Stack
|
||||
---@field public size fun(self: Stack): number
|
||||
---@class (exact) Stack
|
||||
---@field public size fun(self: Stack): integer
|
||||
---@field public peek fun(self: Stack): any
|
||||
---@field public push fun(self: Stack, item: any): Stack
|
||||
---@field public pop fun(self: Stack): any
|
||||
---@field public iter fun(self: Stack): (fun(i: number, item: any): number, any), Stack, number
|
||||
---@field private content any[]
|
||||
---@field public iter fun(self: Stack): ((fun(i: integer, item: any): integer?, any), Stack, integer)
|
||||
---@field package content any[]
|
||||
|
||||
---The stack metatable.
|
||||
local mt = {}
|
||||
|
||||
---The actual iterator implementation, hidden behind the iter-method.
|
||||
---@param stack Stack
|
||||
---@param i integer
|
||||
---@return integer?
|
||||
---@return any
|
||||
local function iter_stack(stack, i)
|
||||
if i <= 1 then return end
|
||||
return i - 1, stack.content[i - 1]
|
||||
|
@ -39,7 +43,7 @@ end
|
|||
local function stack_tostring(stack)
|
||||
local items = {}
|
||||
for _, item in ipairs(stack.content) do
|
||||
items[#items+1] = tostring(item)
|
||||
items[#items + 1] = tostring(item)
|
||||
end
|
||||
return string.format('[%s]', table.concat(items, ', '))
|
||||
end
|
||||
|
@ -48,7 +52,8 @@ end
|
|||
---[ Methods ]-----------------------------------------------------------------
|
||||
|
||||
---Returns the current number of items in the stack.
|
||||
---@return number size Current size of the stack
|
||||
---@param self Stack
|
||||
---@return integer size Current size of the stack
|
||||
local function size(self)
|
||||
return #self.content
|
||||
end
|
||||
|
@ -57,9 +62,9 @@ end
|
|||
---returns the current index (one-based, counting from the bottom) and the
|
||||
---current item.
|
||||
---@param self Stack The stack instance
|
||||
---@return fun(i: number, stack: Stack): number, any
|
||||
---@return fun(i: integer, stack: Stack): integer?, any
|
||||
---@return Stack
|
||||
---@return number
|
||||
---@return integer
|
||||
local function iter(self)
|
||||
return iter_stack, self, self:size() + 1
|
||||
end
|
||||
|
@ -98,12 +103,12 @@ end
|
|||
function M.new(items)
|
||||
---@type Stack
|
||||
local result = {
|
||||
content = {}, ---@type any[]
|
||||
size = size, ---@type fun(self: Stack): number
|
||||
iter = iter,
|
||||
push = push, ---@type fun(self: Stack, item: any): Stack
|
||||
pop = pop, ---@type fun(self: Stack): any
|
||||
peek = peek, ---@type fun(self: Stack): any
|
||||
content = {},
|
||||
size = size,
|
||||
iter = iter,
|
||||
push = push,
|
||||
pop = pop,
|
||||
peek = peek,
|
||||
}
|
||||
setmetatable(result, mt)
|
||||
for _, item in ipairs(items or {}) do result:push(item) end
|
||||
|
|
|
@ -27,8 +27,8 @@ local M = {}
|
|||
---Changes are range objects and come in two variants: one with four entries and
|
||||
---one with six entries. We only want the four-entry variant. See
|
||||
---`:h TSNode:range()`
|
||||
---@param change number[]
|
||||
---@return number[]
|
||||
---@param change integer[]
|
||||
---@return integer[]
|
||||
local function normalize_change(change)
|
||||
local result
|
||||
if #change == 4 then
|
||||
|
@ -41,11 +41,10 @@ local function normalize_change(change)
|
|||
return result
|
||||
end
|
||||
|
||||
---@param bufnr number
|
||||
---@param bufnr integer
|
||||
---@param lang string
|
||||
---@param matches Stack
|
||||
---@param level number
|
||||
---@return nil
|
||||
---@param level integer
|
||||
local function highlight_matches(bufnr, lang, matches, level)
|
||||
local hlgroup = lib.hlgroup_at(level)
|
||||
for _, match in matches:iter() do
|
||||
|
@ -65,11 +64,10 @@ local function new_match_record()
|
|||
end
|
||||
|
||||
---Update highlights for a range. Called every time text is changed.
|
||||
---@param bufnr number Buffer number
|
||||
---@param bufnr integer Buffer number
|
||||
---@param changes table List of node ranges in which the changes occurred
|
||||
---@param tree TSTree TS tree
|
||||
---@param lang string Language
|
||||
---@return nil
|
||||
local function update_range(bufnr, changes, tree, lang)
|
||||
log.debug('Updated range with changes %s', vim.inspect(changes))
|
||||
|
||||
|
@ -142,9 +140,8 @@ local function update_range(bufnr, changes, tree, lang)
|
|||
end
|
||||
|
||||
---Update highlights for every tree in given buffer.
|
||||
---@param bufnr number # Buffer number
|
||||
---@param bufnr integer # Buffer number
|
||||
---@param parser LanguageTree
|
||||
---@return nil
|
||||
local function full_update(bufnr, parser)
|
||||
log.debug('Performing full updated on buffer %d', bufnr)
|
||||
local function callback(tree, sub_parser)
|
||||
|
@ -157,10 +154,9 @@ end
|
|||
|
||||
|
||||
---Sets up all the callbacks and performs an initial highlighting
|
||||
---@param bufnr number # Buffer number
|
||||
---@param bufnr integer # Buffer number
|
||||
---@param parser LanguageTree
|
||||
---@param start_parent_lang string? # Parent language or nil
|
||||
---@return nil
|
||||
local function setup_parser(bufnr, parser, start_parent_lang)
|
||||
log.debug('Setting up parser for buffer %d', bufnr)
|
||||
|
||||
|
@ -171,6 +167,8 @@ local function setup_parser(bufnr, parser, start_parent_lang)
|
|||
if not lib.get_query(lang) then return end
|
||||
|
||||
p:register_cbs {
|
||||
---@param changes table
|
||||
---@param tree TSTree
|
||||
on_changedtree = function(changes, tree)
|
||||
log.trace('Changed tree in buffer %d with languages %s', bufnr, lang)
|
||||
-- HACK: As of Neovim v0.9.1 there is no way of unregistering a
|
||||
|
@ -239,6 +237,7 @@ local function setup_parser(bufnr, parser, start_parent_lang)
|
|||
end,
|
||||
-- New languages can be added into the text at some later time, e.g.
|
||||
-- code snippets in Markdown
|
||||
---@param child LanguageTree
|
||||
on_child_added = function(child)
|
||||
setup_parser(bufnr, child, lang)
|
||||
end,
|
||||
|
@ -250,20 +249,28 @@ local function setup_parser(bufnr, parser, start_parent_lang)
|
|||
end
|
||||
|
||||
|
||||
---on_attach implementation for the global strategy
|
||||
---@param bufnr integer
|
||||
---@param settings rainbow_delimiters.buffer_settings
|
||||
function M.on_attach(bufnr, settings)
|
||||
log.trace('global strategy on_attach')
|
||||
local parser = settings.parser
|
||||
setup_parser(bufnr, parser, nil)
|
||||
end
|
||||
|
||||
---on_detach implementation for the global strategy
|
||||
---@param _bufnr integer
|
||||
function M.on_detach(_bufnr)
|
||||
end
|
||||
|
||||
---on_reset implementation for the global strategy
|
||||
---@param bufnr integer
|
||||
---@param settings rainbow_delimiters.buffer_settings
|
||||
function M.on_reset(bufnr, settings)
|
||||
log.trace('global strategy on_reset')
|
||||
full_update(bufnr, settings.parser)
|
||||
end
|
||||
|
||||
return M
|
||||
return M --[[@as rainbow_delimiters.strategy]]
|
||||
|
||||
-- vim:tw=79:ts=4:sw=4:noet:
|
||||
|
|
|
@ -45,11 +45,15 @@ local M = {}
|
|||
local match_trees = {}
|
||||
|
||||
---Reusable autogroup for events in this strategy.
|
||||
---@type number
|
||||
---@type integer
|
||||
local augroup = api.nvim_create_augroup('TSRainbowLocalCursor', {})
|
||||
|
||||
|
||||
---Highlights a single match with the given highlight group
|
||||
---@param bufnr integer
|
||||
---@param lang string
|
||||
---@param match table
|
||||
---@param hlgroup string
|
||||
local function highlight_match(bufnr, lang, match, hlgroup)
|
||||
for _, delimiter in match.delimiter:iter() do lib.highlight(bufnr, lang, delimiter, hlgroup) end
|
||||
end
|
||||
|
@ -57,9 +61,9 @@ end
|
|||
---Highlights all matches and their children on the stack of matches. All
|
||||
---matches must be on the same level of the match tree.
|
||||
---
|
||||
---@param bufnr number Number of the buffer
|
||||
---@param bufnr integer Number of the buffer
|
||||
---@param matches Stack Stack of matches
|
||||
---@param level number Level of the matches
|
||||
---@param level integer Level of the matches
|
||||
local function highlight_matches(bufnr, lang, matches, level)
|
||||
local hlgroup = lib.hlgroup_at(level)
|
||||
for _, match in matches:iter() do
|
||||
|
@ -70,6 +74,13 @@ end
|
|||
|
||||
---Finds a match (and its level) in the match tree whose container node is the
|
||||
---given container node.
|
||||
---@param matches Stack
|
||||
---@param container TSNode
|
||||
---@param level integer
|
||||
---@return table
|
||||
---@return integer
|
||||
---If no match is found, return nil.
|
||||
---@overload fun(matches: Stack, container: TSNode, level: integer)
|
||||
local function find_container(matches, container, level)
|
||||
for _, match in matches:iter() do
|
||||
if match.container == container then return match, level end
|
||||
|
@ -79,7 +90,7 @@ local function find_container(matches, container, level)
|
|||
end
|
||||
|
||||
--- Create a new empty match_record with an optionally set container
|
||||
---@param container TSNode?
|
||||
---@param container TSNode
|
||||
---@return table
|
||||
local function new_match_record(container)
|
||||
return {
|
||||
|
@ -91,7 +102,7 @@ end
|
|||
|
||||
---Assembles the match tree, usually called after the document tree has
|
||||
---changed.
|
||||
---@param bufnr number Buffer number
|
||||
---@param bufnr integer Buffer number
|
||||
---@param changes table List of node ranges in which the changes occurred
|
||||
---@param tree TSTree TS tree
|
||||
---@param lang string Language
|
||||
|
@ -164,6 +175,9 @@ local function build_match_tree(bufnr, changes, tree, lang)
|
|||
return matches
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@param tree TSTree
|
||||
---@param lang string
|
||||
local function update_local(bufnr, tree, lang)
|
||||
if not lib.enabled_for(lang) then return end
|
||||
local query = lib.get_query(lang)
|
||||
|
@ -220,6 +234,8 @@ end
|
|||
|
||||
---Callback function to re-highlight the buffer according to the current cursor
|
||||
---position.
|
||||
---@param bufnr integer
|
||||
---@param parser LanguageTree
|
||||
local function local_rainbow(bufnr, parser)
|
||||
parser:for_each_tree(function(tree, sub_parser)
|
||||
update_local(bufnr, tree, sub_parser:lang())
|
||||
|
@ -227,9 +243,8 @@ local function local_rainbow(bufnr, parser)
|
|||
end
|
||||
|
||||
---Sets up all the callbacks and performs an initial highlighting
|
||||
---@param bufnr number # Buffer number
|
||||
---@param bufnr integer # Buffer number
|
||||
---@param parser LanguageTree
|
||||
---@return nil
|
||||
local function setup_parser(bufnr, parser)
|
||||
log.debug('Setting up parser for buffer %d', bufnr)
|
||||
util.for_each_child(nil, parser:lang(), parser, function(p, lang, _parent_lang)
|
||||
|
@ -238,6 +253,8 @@ local function setup_parser(bufnr, parser)
|
|||
-- nil-reference error
|
||||
if not lib.get_query(lang) then return end
|
||||
p:register_cbs {
|
||||
---@param _changes table
|
||||
---@param tree TSTree
|
||||
on_changedtree = function(_changes, tree)
|
||||
-- HACK: As of Neovim v0.9.1 there is no way of unregistering a
|
||||
-- callback, so we use this check to abort
|
||||
|
@ -257,6 +274,7 @@ local function setup_parser(bufnr, parser)
|
|||
end,
|
||||
-- New languages can be added into the text at some later time, e.g.
|
||||
-- code snippets in Markdown
|
||||
---@param child LanguageTree
|
||||
on_child_added = function(child)
|
||||
setup_parser(bufnr, child)
|
||||
end,
|
||||
|
@ -265,6 +283,9 @@ local function setup_parser(bufnr, parser)
|
|||
end)
|
||||
end
|
||||
|
||||
---on_attach implementation for the local strategy
|
||||
---@param bufnr integer
|
||||
---@param settings rainbow_delimiters.buffer_settings
|
||||
function M.on_attach(bufnr, settings)
|
||||
local parser = settings.parser
|
||||
setup_parser(bufnr, parser)
|
||||
|
@ -293,6 +314,8 @@ function M.on_attach(bufnr, settings)
|
|||
local_rainbow(bufnr, parser)
|
||||
end
|
||||
|
||||
---on_detach implementation for the local strategy
|
||||
---@param bufnr integer
|
||||
function M.on_detach(bufnr)
|
||||
-- Uninstall autocommand and delete cached match tree
|
||||
api.nvim_clear_autocmds {
|
||||
|
@ -302,11 +325,14 @@ function M.on_detach(bufnr)
|
|||
match_trees[bufnr] = nil
|
||||
end
|
||||
|
||||
---on_reset implementation for the local strategy
|
||||
---@param bufnr integer
|
||||
---@param settings rainbow_delimiters.buffer_settings
|
||||
function M.on_reset(bufnr, settings)
|
||||
local parser = settings.parser
|
||||
local_rainbow(bufnr, parser)
|
||||
end
|
||||
|
||||
return M
|
||||
return M --[[@as rainbow_delimiters.strategy]]
|
||||
|
||||
-- vim:tw=79:ts=4:sw=4:noet:
|
||||
|
|
|
@ -17,15 +17,23 @@
|
|||
---A dummy strategy which does nothing; can be used in testing.
|
||||
local M = {}
|
||||
|
||||
M.on_attach = function()
|
||||
---on_attach implementation for the noop strategy
|
||||
---@param _bufnr integer
|
||||
---@param _settings rainbow_delimiters.buffer_settings
|
||||
M.on_attach = function(_bufnr, _settings)
|
||||
end
|
||||
|
||||
M.on_detach = function()
|
||||
---on_detach implementation for the noop strategy
|
||||
---@param _bufnr integer
|
||||
M.on_detach = function(_bufnr)
|
||||
end
|
||||
|
||||
M.on_reset = function()
|
||||
---on_reset implementation for the noop strategy
|
||||
---@param _bufnr integer
|
||||
---@param _settings rainbow_delimiters.buffer_settings
|
||||
M.on_reset = function(_bufnr, _settings)
|
||||
end
|
||||
|
||||
return M
|
||||
return M --[[@as rainbow_delimiters.strategy]]
|
||||
|
||||
-- vim:tw=79:ts=4:sw=4:noet:
|
||||
|
|
|
@ -28,8 +28,7 @@ local M = {}
|
|||
---@param parent_lang string? # Parent language or nil
|
||||
---@param lang string
|
||||
---@param language_tree LanguageTree
|
||||
---@param thunk fun(p: LanguageTree, lang: string, parent_lang: string?): nil
|
||||
---@return nil
|
||||
---@param thunk fun(p: LanguageTree, lang: string, parent_lang: string?)
|
||||
function M.for_each_child(parent_lang, lang, language_tree, thunk)
|
||||
thunk(language_tree, lang, parent_lang)
|
||||
local children = language_tree:children()
|
||||
|
|
Loading…
Reference in a new issue