mirror of
https://github.com/HiPhish/rainbow-delimiters.nvim.git
synced 2024-09-16 14:24:05 +02:00
Implement functions for togging rainbow per buffer
This commit is contained in:
parent
698a439662
commit
adfb780b35
6 changed files with 256 additions and 97 deletions
|
@ -23,4 +23,22 @@ function! rainbow_delimiters#hlgroup_at(i)
|
||||||
return luaeval("require('rainbow-delimiters').hlgroup_at(_A)", a:i)
|
return luaeval("require('rainbow-delimiters').hlgroup_at(_A)", a:i)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Disable highlighting for the given buffer. Buffer number zero means current
|
||||||
|
" buffer.
|
||||||
|
function! rainbow_delimiters#disable(bufnr)
|
||||||
|
call luaeval("require('rainbow-delimiters').disable(_A)", a:bufnr)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Enable highlighting for the given buffer. Buffer number zero means current
|
||||||
|
" buffer.
|
||||||
|
function! rainbow_delimiters#enable(bufnr)
|
||||||
|
call luaeval("require('rainbow-delimiters').enable(_A)", a:bufnr)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Toggle highlighting for the given buffer. Buffer number zero means current
|
||||||
|
" buffer.
|
||||||
|
function! rainbow_delimiters#toggle(bufnr)
|
||||||
|
call luaeval("require('rainbow-delimiters').toggle(_A)", a:bufnr)
|
||||||
|
endfunction
|
||||||
|
|
||||||
" vim:tw=79:ts=4:sw=4:noet:
|
" vim:tw=79:ts=4:sw=4:noet:
|
||||||
|
|
|
@ -366,6 +366,36 @@ There is a utility library provided for people writing their own strategies.
|
||||||
It is available as a table under the Lua module `'rainbow-delimiters'`.
|
It is available as a table under the Lua module `'rainbow-delimiters'`.
|
||||||
|
|
||||||
|
|
||||||
|
*rb-delimiters.enable*
|
||||||
|
*rb_delimiters#enable*
|
||||||
|
'rainbow-delimiters'.enable({bufnr})
|
||||||
|
Re-enable rainbow delimiters for the buffer {bufnr} (or the current buffer
|
||||||
|
if {bufnr} is `0`) after it has been disabled.
|
||||||
|
|
||||||
|
rainbow_delimiters#enable({bufnr})
|
||||||
|
Vim script binding for the above function.
|
||||||
|
|
||||||
|
|
||||||
|
*rb-delimiters.disable*
|
||||||
|
*rb_delimiters#disable*
|
||||||
|
'rainbow-delimiters'.disable({bufnr})
|
||||||
|
Disable rainbow delimiters for the buffer {bufnr} (or the current buffer
|
||||||
|
if {bufnr} is `0`).
|
||||||
|
|
||||||
|
rainbow_delimiters#disable({bufnr})
|
||||||
|
Vim script binding for the above function.
|
||||||
|
|
||||||
|
|
||||||
|
*rb-delimiters.toggle*
|
||||||
|
*rb_delimiters#toggle*
|
||||||
|
'rainbow-delimiters'.toggle({bufnr})
|
||||||
|
Toggle rainbow delimiters for the buffer {bufnr} (or the current buffer
|
||||||
|
if {bufnr} is `0`).
|
||||||
|
|
||||||
|
rainbow_delimiters#toggle({bufnr})
|
||||||
|
Vim script binding for the above function.
|
||||||
|
|
||||||
|
|
||||||
*rb-delimiters.hlgroup_at*
|
*rb-delimiters.hlgroup_at*
|
||||||
*rainbow-delimiters#hlgroup_at*
|
*rainbow-delimiters#hlgroup_at*
|
||||||
'rainbow-delimiters'.hlgroup_at({nesting_level})
|
'rainbow-delimiters'.hlgroup_at({nesting_level})
|
||||||
|
|
|
@ -17,6 +17,33 @@
|
||||||
|
|
||||||
local lib = require 'rainbow-delimiters.lib'
|
local lib = require 'rainbow-delimiters.lib'
|
||||||
|
|
||||||
|
---Disable rainbow delimiters for a given buffer.
|
||||||
|
---@param bufnr number Buffer number, zero for current buffer.
|
||||||
|
local function disable(bufnr)
|
||||||
|
bufnr = bufnr > 0 and bufnr or vim.api.nvim_get_current_buf()
|
||||||
|
lib.detach(bufnr)
|
||||||
|
lib.buffers[bufnr] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
---Enable rainbow delimiters for a given buffer.
|
||||||
|
---@param bufnr number Buffer number, zero for current buffer.
|
||||||
|
local function enable(bufnr)
|
||||||
|
bufnr = bufnr > 0 and bufnr or vim.api.nvim_get_current_buf()
|
||||||
|
lib.buffers[bufnr] = nil
|
||||||
|
lib.attach(bufnr)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toggle(bufnr)
|
||||||
|
bufnr = bufnr > 0 and bufnr or vim.api.nvim_get_current_buf()
|
||||||
|
if lib.buffers[bufnr] then
|
||||||
|
print 'turn off'
|
||||||
|
disable(bufnr)
|
||||||
|
else
|
||||||
|
print 'turn on'
|
||||||
|
enable(bufnr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---Public API for use in writing strategies or other custom code.
|
---Public API for use in writing strategies or other custom code.
|
||||||
local M = {
|
local M = {
|
||||||
hlgroup_at = lib.hlgroup_at,
|
hlgroup_at = lib.hlgroup_at,
|
||||||
|
@ -25,7 +52,10 @@ local M = {
|
||||||
['global'] = require 'rainbow-delimiters.strategy.global',
|
['global'] = require 'rainbow-delimiters.strategy.global',
|
||||||
['local'] = require 'rainbow-delimiters.strategy.local',
|
['local'] = require 'rainbow-delimiters.strategy.local',
|
||||||
['noop'] = require 'rainbow-delimiters.strategy.no-op',
|
['noop'] = require 'rainbow-delimiters.strategy.no-op',
|
||||||
}
|
},
|
||||||
|
enable = enable,
|
||||||
|
disable = disable,
|
||||||
|
toggle = toggle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
local get_query = vim.treesitter.query.get
|
local get_query = vim.treesitter.query.get
|
||||||
|
local get_parser= vim.treesitter.get_parser
|
||||||
local log = require 'rainbow-delimiters.log'
|
local log = require 'rainbow-delimiters.log'
|
||||||
local config = require 'rainbow-delimiters.config'
|
local config = require 'rainbow-delimiters.config'
|
||||||
|
|
||||||
|
@ -120,6 +121,100 @@ function M.clear_namespace(bufnr, lang, line_start, line_end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Start rainbow highlighting for the given buffer
|
||||||
|
function M.attach(bufnr)
|
||||||
|
-- Rainbow delimiters was explicitly disabled for this buffer
|
||||||
|
if M.buffers[bufnr] == false then return end
|
||||||
|
|
||||||
|
local lang = vim.treesitter.language.get_lang(vim.bo[bufnr].ft)
|
||||||
|
if not lang then
|
||||||
|
log.trace('Cannot attach to buffer %d, no parser for %s', bufnr, lang)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
log.trace('Attaching to buffer %d with language %s.', bufnr, lang)
|
||||||
|
|
||||||
|
if M.buffers[bufnr] then
|
||||||
|
if M.buffers[bufnr].lang == lang then return end
|
||||||
|
-- The file type of the buffer has change, so we need to detach first
|
||||||
|
-- before we re-attach
|
||||||
|
M.detach(bufnr)
|
||||||
|
end
|
||||||
|
|
||||||
|
local parser
|
||||||
|
do
|
||||||
|
local success
|
||||||
|
success, parser = pcall(get_parser, bufnr, lang)
|
||||||
|
if not success then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
local strategy
|
||||||
|
do
|
||||||
|
strategy = config.strategy[lang]
|
||||||
|
if type(strategy) == 'function' then
|
||||||
|
strategy = strategy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not strategy or strategy == vim.NIL then return end
|
||||||
|
|
||||||
|
-- Intentionally abort; the user has explicitly disabled rainbow delimiters
|
||||||
|
-- for this buffer, usually by setting a strategy- or query function which
|
||||||
|
-- returned nil.
|
||||||
|
if not strategy then
|
||||||
|
log.warn('No strategy defined for %s', lang)
|
||||||
|
end
|
||||||
|
|
||||||
|
parser:register_cbs {
|
||||||
|
on_detach = function(bnr)
|
||||||
|
if not M.buffers[bnr] then return end
|
||||||
|
M.detach(bufnr)
|
||||||
|
end,
|
||||||
|
on_child_removed = function(child)
|
||||||
|
M.clear_namespace(bufnr, child:lang())
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local settings = {
|
||||||
|
strategy = strategy,
|
||||||
|
parser = parser,
|
||||||
|
lang = lang
|
||||||
|
}
|
||||||
|
M.buffers[bufnr] = settings
|
||||||
|
|
||||||
|
-- For now we silently discard errors, but in the future we should log
|
||||||
|
-- them.
|
||||||
|
local success, error = pcall(strategy.on_attach, bufnr, settings)
|
||||||
|
if not success then
|
||||||
|
log.error('Error attaching strategy to buffer %d: %s', bufnr, error)
|
||||||
|
M.buffers[bufnr] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Start rainbow highlighting for the given buffer
|
||||||
|
function M.detach(bufnr)
|
||||||
|
log.trace('Detaching from buffer %d.', bufnr)
|
||||||
|
if not M.buffers[bufnr] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local strategy = M.buffers[bufnr].strategy
|
||||||
|
local parser = M.buffers[bufnr].parser
|
||||||
|
|
||||||
|
-- Clear all the namespaces for each language
|
||||||
|
parser:for_each_child(function(_, lang)
|
||||||
|
M.clear_namespace(bufnr, lang)
|
||||||
|
end, true)
|
||||||
|
-- Finally release all resources the parser is holding on to
|
||||||
|
parser:destroy()
|
||||||
|
|
||||||
|
-- For now we silently discard errors, but in the future we should log
|
||||||
|
-- them.
|
||||||
|
local success, error = pcall(strategy.on_detach, bufnr)
|
||||||
|
if not success then
|
||||||
|
log.error('Error detaching strategy from buffer %d: %s', bufnr, error)
|
||||||
|
end
|
||||||
|
M.buffers[bufnr] = nil
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
||||||
-- vim:tw=79:ts=4:sw=4:noet:
|
-- vim:tw=79:ts=4:sw=4:noet:
|
||||||
|
|
|
@ -21,7 +21,6 @@ local api = vim.api
|
||||||
local set_hl = api.nvim_set_hl
|
local set_hl = api.nvim_set_hl
|
||||||
local create_augroup = api.nvim_create_augroup
|
local create_augroup = api.nvim_create_augroup
|
||||||
local create_autocmd = api.nvim_create_autocmd
|
local create_autocmd = api.nvim_create_autocmd
|
||||||
local get_parser = vim.treesitter.get_parser
|
|
||||||
local get_lang = vim.treesitter.language.get_lang
|
local get_lang = vim.treesitter.language.get_lang
|
||||||
local config = require 'rainbow-delimiters.config'
|
local config = require 'rainbow-delimiters.config'
|
||||||
local log = require 'rainbow-delimiters.log'
|
local log = require 'rainbow-delimiters.log'
|
||||||
|
@ -44,99 +43,6 @@ end
|
||||||
define_hlgroups()
|
define_hlgroups()
|
||||||
|
|
||||||
|
|
||||||
--- [ CALLBACK FUNCTIONS ]-----------------------------------------------------
|
|
||||||
local attach, detach
|
|
||||||
|
|
||||||
function attach(bufnr)
|
|
||||||
local lang = vim.treesitter.language.get_lang(vim.bo[bufnr].ft)
|
|
||||||
if not lang then
|
|
||||||
log.trace('Cannot attach to buffer %d, no parser for %s', bufnr, lang)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
log.trace('Attaching to buffer %d with language %s.', bufnr, lang)
|
|
||||||
|
|
||||||
if lib.buffers[bufnr] then
|
|
||||||
if lib.buffers[bufnr].lang == lang then return end
|
|
||||||
-- The file type of the buffer has change, so we need to detach first
|
|
||||||
-- before we re-attach
|
|
||||||
detach(bufnr)
|
|
||||||
end
|
|
||||||
|
|
||||||
local parser
|
|
||||||
do
|
|
||||||
local success
|
|
||||||
success, parser = pcall(get_parser, bufnr, lang)
|
|
||||||
if not success then return end
|
|
||||||
end
|
|
||||||
|
|
||||||
local strategy
|
|
||||||
do
|
|
||||||
strategy = config.strategy[lang]
|
|
||||||
if type(strategy) == 'function' then
|
|
||||||
strategy = strategy()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not strategy or strategy == vim.NIL then return end
|
|
||||||
|
|
||||||
-- Intentionally abort; the user has explicitly disabled rainbow delimiters
|
|
||||||
-- for this buffer, usually by setting a strategy- or query function which
|
|
||||||
-- returned nil.
|
|
||||||
if not strategy then
|
|
||||||
log.warn('No strategy defined for %s', lang)
|
|
||||||
end
|
|
||||||
|
|
||||||
parser:register_cbs {
|
|
||||||
on_detach = function(bnr)
|
|
||||||
if not lib.buffers[bnr] then return end
|
|
||||||
detach(bufnr)
|
|
||||||
end,
|
|
||||||
on_child_removed = function(child)
|
|
||||||
lib.clear_namespace(bufnr, child:lang())
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local settings = {
|
|
||||||
strategy = strategy,
|
|
||||||
parser = parser,
|
|
||||||
lang = lang
|
|
||||||
}
|
|
||||||
lib.buffers[bufnr] = settings
|
|
||||||
|
|
||||||
-- For now we silently discard errors, but in the future we should log
|
|
||||||
-- them.
|
|
||||||
local success, error = pcall(strategy.on_attach, bufnr, settings)
|
|
||||||
if not success then
|
|
||||||
log.error('Error attaching strategy to buffer %d: %s', bufnr, error)
|
|
||||||
lib.buffers[bufnr] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function detach(bufnr)
|
|
||||||
log.trace('Detaching from buffer %d.', bufnr)
|
|
||||||
if not lib.buffers[bufnr] then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local strategy = lib.buffers[bufnr].strategy
|
|
||||||
local parser = lib.buffers[bufnr].parser
|
|
||||||
|
|
||||||
-- Clear all the namespaces for each language
|
|
||||||
parser:for_each_child(function(_, lang)
|
|
||||||
lib.clear_namespace(bufnr, lang)
|
|
||||||
end, true)
|
|
||||||
-- Finally release all resources the parser is holding on to
|
|
||||||
parser:destroy()
|
|
||||||
|
|
||||||
-- For now we silently discard errors, but in the future we should log
|
|
||||||
-- them.
|
|
||||||
local success, error = pcall(strategy.on_detach, bufnr)
|
|
||||||
if not success then
|
|
||||||
log.error('Error detaching strategy from buffer %d: %s', bufnr, error)
|
|
||||||
end
|
|
||||||
lib.buffers[bufnr] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- [ SET UP AUTOCOMMANDS ]----------------------------------------------------
|
--- [ SET UP AUTOCOMMANDS ]----------------------------------------------------
|
||||||
local hl_augroup = create_augroup('TSRainbowHighlight', {})
|
local hl_augroup = create_augroup('TSRainbowHighlight', {})
|
||||||
local rb_augroup = create_augroup('TSRainbowDelimits', {})
|
local rb_augroup = create_augroup('TSRainbowDelimits', {})
|
||||||
|
@ -154,14 +60,14 @@ create_autocmd('FileType', {
|
||||||
local lang = get_lang(args.match)
|
local lang = get_lang(args.match)
|
||||||
if not config.enabled_for(lang) then return end
|
if not config.enabled_for(lang) then return end
|
||||||
|
|
||||||
attach(args.buf)
|
lib.attach(args.buf)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
create_autocmd('BufUnload', {
|
create_autocmd('BufUnload', {
|
||||||
desc = 'Detach from the current buffer',
|
desc = 'Detach from the current buffer',
|
||||||
group = rb_augroup,
|
group = rb_augroup,
|
||||||
callback = function(args) detach(args.buf) end
|
callback = function(args) lib.detach(args.buf) end
|
||||||
})
|
})
|
||||||
|
|
||||||
vim.g.loaded_rainbow = true
|
vim.g.loaded_rainbow = true
|
||||||
|
|
80
test/vader/integration/toggle.vader
Normal file
80
test/vader/integration/toggle.vader
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# We can use functions to turn rainbow delimiters off and on again.
|
||||||
|
|
||||||
|
Execute lua (Set up the plugin):
|
||||||
|
the_strategy = require('rainbow-delimiters.strategy.global')
|
||||||
|
vim.g.rainbow_delimiters = {strategy = {[''] = the_strategy}}
|
||||||
|
|
||||||
|
Given lua (A Lua buffer):
|
||||||
|
print((((('Hello, world!')))))
|
||||||
|
|
||||||
|
Execute (Leave things as they are):
|
||||||
|
redraw! " Without this there will be no extmarks at all
|
||||||
|
|
||||||
|
Then (Rainbow delimiters are active):
|
||||||
|
let extmarks = luaeval('vim.inspect_pos(0, 0, 5)').extmarks
|
||||||
|
\->map('v:val["ns_id"]')
|
||||||
|
\->filter({_, nsid -> nsid == luaeval('require("rainbow-delimiters.lib").nsids.lua')})
|
||||||
|
AssertNotEqual [], extmarks
|
||||||
|
|
||||||
|
Execute (Turn rainbow delimiters off):
|
||||||
|
call rainbow_delimiters#disable(0)
|
||||||
|
redraw! " Without this there will be no extmarks at all
|
||||||
|
|
||||||
|
Then (Rainbow delimiters are inactive):
|
||||||
|
let extmarks = luaeval('vim.inspect_pos(0, 0, 5)').extmarks
|
||||||
|
\->map('v:val["ns_id"]')
|
||||||
|
\->filter({_, nsid -> nsid == luaeval('require("rainbow-delimiters.lib").nsids.lua')})
|
||||||
|
AssertEqual [], extmarks
|
||||||
|
|
||||||
|
Execute (Turn rainbow delimiters off a second time):
|
||||||
|
call rainbow_delimiters#disable(0)
|
||||||
|
redraw! " Without this there will be no extmarks at all
|
||||||
|
|
||||||
|
Then (Disabling is idempotent):
|
||||||
|
let extmarks = luaeval('vim.inspect_pos(0, 0, 5)').extmarks
|
||||||
|
\->map('v:val["ns_id"]')
|
||||||
|
\->filter({_, nsid -> nsid == luaeval('require("rainbow-delimiters.lib").nsids.lua')})
|
||||||
|
AssertEqual [], extmarks
|
||||||
|
|
||||||
|
Execute (Turn rainbow delimiters back on):
|
||||||
|
call rainbow_delimiters#enable(0)
|
||||||
|
redraw! " Without this there will be no extmarks at all
|
||||||
|
|
||||||
|
Then (Rainbow delimiters are active):
|
||||||
|
let extmarks = luaeval('vim.inspect_pos(0, 0, 5)').extmarks
|
||||||
|
\->map('v:val["ns_id"]')
|
||||||
|
\->filter({_, nsid -> nsid == luaeval('require("rainbow-delimiters.lib").nsids.lua')})
|
||||||
|
AssertNotEqual [], extmarks
|
||||||
|
|
||||||
|
Execute (Turn rainbow delimiters on a second time):
|
||||||
|
call rainbow_delimiters#enable(0)
|
||||||
|
redraw! " Without this there will be no extmarks at all
|
||||||
|
|
||||||
|
Then (Enabling is idempotent):
|
||||||
|
let extmarks = luaeval('vim.inspect_pos(0, 0, 5)').extmarks
|
||||||
|
\->map('v:val["ns_id"]')
|
||||||
|
\->filter({_, nsid -> nsid == luaeval('require("rainbow-delimiters.lib").nsids.lua')})
|
||||||
|
AssertNotEqual [], extmarks
|
||||||
|
|
||||||
|
Execute (Toggle rainbow delimiters off):
|
||||||
|
call rainbow_delimiters#toggle(0)
|
||||||
|
redraw! " Without this there will be no extmarks at all
|
||||||
|
|
||||||
|
Then (Rainbow delimiters are inactive):
|
||||||
|
let extmarks = luaeval('vim.inspect_pos(0, 0, 5)').extmarks
|
||||||
|
\->map('v:val["ns_id"]')
|
||||||
|
\->filter({_, nsid -> nsid == luaeval('require("rainbow-delimiters.lib").nsids.lua')})
|
||||||
|
AssertEqual [], extmarks
|
||||||
|
|
||||||
|
Execute (Toggle rainbow delimiters back on):
|
||||||
|
call rainbow_delimiters#toggle(0)
|
||||||
|
redraw! " Without this there will be no extmarks at all
|
||||||
|
|
||||||
|
Then (Rainbow delimiters are active):
|
||||||
|
let extmarks = luaeval('vim.inspect_pos(0, 0, 5)').extmarks
|
||||||
|
\->map('v:val["ns_id"]')
|
||||||
|
\->filter({_, nsid -> nsid == luaeval('require("rainbow-delimiters.lib").nsids.lua')})
|
||||||
|
AssertNotEqual [], extmarks
|
||||||
|
|
||||||
|
|
||||||
|
# vim:tw=79:ts=2:sw=2:et:
|
Loading…
Reference in a new issue