1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 22:50:05 +08:00
SpaceVim/bundle/indent-blankline.nvim/lua/indent_blankline/utils.lua

199 lines
5.4 KiB
Lua
Raw Normal View History

local M = {}
M.memo =
setmetatable(
{
put = function(cache, params, result)
local node = cache
for i = 1, #params do
local param = vim.inspect(params[i])
node.children = node.children or {}
node.children[param] = node.children[param] or {}
node = node.children[param]
end
node.result = result
end,
get = function(cache, params)
local node = cache
for i = 1, #params do
local param = vim.inspect(params[i])
node = node.children and node.children[param]
if not node then
return nil
end
end
return node.result
end
},
{
__call = function(memo, func)
local cache = {}
return function(...)
local params = {...}
local result = memo.get(cache, params)
if not result then
result = {func(...)}
memo.put(cache, params, result)
end
return unpack(result)
end
end
}
)
M.error_handler = function(err)
if vim.g.indent_blankline_debug then
vim.cmd("echohl Error")
vim.cmd('echomsg "' .. err .. '"')
vim.cmd("echohl None")
end
end
M.is_indent_blankline_enabled =
M.memo(
function(
b_enabled,
g_enabled,
filetype,
filetype_include,
filetype_exclude,
buftype,
buftype_exclude,
bufname_exclude,
bufname)
if b_enabled ~= nil then
return b_enabled
end
if g_enabled == false then
return false
end
for _, ft in ipairs(filetype_exclude) do
if ft == filetype then
return false
end
end
for _, bt in ipairs(buftype_exclude) do
if bt == buftype then
return false
end
end
for _, bn in ipairs(bufname_exclude) do
if vim.fn["matchstr"](bufname, bn) == bufname then
return false
end
end
if #filetype_include > 0 then
for _, ft in ipairs(filetype_include) do
if ft == filetype then
return true
end
end
return false
end
return true
end
)
M.clear_line_indent = function(buf, lnum)
xpcall(vim.api.nvim_buf_clear_namespace, M.error_handler, buf, vim.g.indent_blankline_namespace, lnum - 1, lnum)
end
M.get_from_list = function(list, i)
return list[((i - 1) % #list) + 1]
end
M._if = function(bool, a, b)
if bool then
return a
else
return b
end
end
M.find_indent = function(line, shiftwidth, strict_tabs)
local indent = 0
local spaces = 0
for ch in line:gmatch(".") do
if ch == " " then
if strict_tabs and indent == 0 and spaces ~= 0 then
return 0, false
end
indent = indent + math.floor(spaces / shiftwidth) + 1
spaces = 0
elseif ch == " " then
if strict_tabs and indent ~= 0 then
return indent, true
end
spaces = spaces + 1
else
break
end
end
indent = indent + math.floor(spaces / shiftwidth)
return indent, spaces % shiftwidth ~= 0
end
M.get_current_context = function(type_patterns)
local ts_utils = require "nvim-treesitter.ts_utils"
local cursor_node = ts_utils.get_node_at_cursor()
while cursor_node do
local node_type = cursor_node:type()
for _, rgx in ipairs(type_patterns) do
if node_type:find(rgx) then
local node_start, _, node_end, _ = cursor_node:range()
if node_start ~= node_end then
return true, node_start + 1, node_end + 1
end
node_start, node_end = nil, nil
end
end
cursor_node = cursor_node:parent()
end
return false
end
M.reset_highlights = function()
local whitespace_highlight = vim.fn.synIDtrans(vim.fn.hlID("Whitespace"))
local label_highlight = vim.fn.synIDtrans(vim.fn.hlID("Label"))
local whitespace_fg = {
vim.fn.synIDattr(whitespace_highlight, "fg", "gui"),
vim.fn.synIDattr(whitespace_highlight, "fg", "cterm")
}
local label_fg = {
vim.fn.synIDattr(label_highlight, "fg", "gui"),
vim.fn.synIDattr(label_highlight, "fg", "cterm")
}
for highlight_name, highlight in pairs(
{
IndentBlanklineChar = whitespace_fg,
IndentBlanklineSpaceChar = whitespace_fg,
IndentBlanklineSpaceCharBlankline = whitespace_fg,
IndentBlanklineContextChar = label_fg
}
) do
local current_highlight = vim.fn.synIDtrans(vim.fn.hlID(highlight_name))
if vim.fn.synIDattr(current_highlight, "fg") == "" and vim.fn.synIDattr(current_highlight, "bg") == "" then
vim.cmd(
string.format(
"highlight %s guifg=%s ctermfg=%s gui=nocombine cterm=nocombine",
highlight_name,
M._if(highlight[1] == "", "NONE", highlight[1]),
M._if(highlight[2] == "", "NONE", highlight[2])
)
)
end
end
end
return M