summaryrefslogtreecommitdiff
path: root/start/indent-blankline-2.20.4/lua
diff options
context:
space:
mode:
Diffstat (limited to 'start/indent-blankline-2.20.4/lua')
-rw-r--r--start/indent-blankline-2.20.4/lua/indent_blankline/commands.lua58
-rw-r--r--start/indent-blankline-2.20.4/lua/indent_blankline/init.lua651
-rw-r--r--start/indent-blankline-2.20.4/lua/indent_blankline/utils.lua341
3 files changed, 1050 insertions, 0 deletions
diff --git a/start/indent-blankline-2.20.4/lua/indent_blankline/commands.lua b/start/indent-blankline-2.20.4/lua/indent_blankline/commands.lua
new file mode 100644
index 0000000..263d332
--- /dev/null
+++ b/start/indent-blankline-2.20.4/lua/indent_blankline/commands.lua
@@ -0,0 +1,58 @@
+local M = {}
+
+M.refresh = function(bang, scroll)
+ scroll = scroll or false
+ if bang then
+ local win = vim.api.nvim_get_current_win()
+ vim.cmd(string.format([[noautocmd windo lua require("indent_blankline").refresh(%s)]], tostring(scroll)))
+ if vim.api.nvim_win_is_valid(win) then
+ vim.api.nvim_set_current_win(win)
+ end
+ else
+ require("indent_blankline").refresh(scroll)
+ end
+end
+
+M.enable = function(bang)
+ if bang then
+ vim.g.indent_blankline_enabled = true
+ local win = vim.api.nvim_get_current_win()
+ vim.cmd [[noautocmd windo lua require("indent_blankline").refresh(false)]]
+ vim.api.nvim_set_current_win(win)
+ else
+ vim.b.indent_blankline_enabled = true
+ require("indent_blankline").refresh(false)
+ end
+end
+
+M.disable = function(bang)
+ if bang then
+ vim.g.indent_blankline_enabled = false
+ local buffers = vim.api.nvim_list_bufs()
+ for _, buffer in pairs(buffers) do
+ vim.api.nvim_buf_clear_namespace(buffer, vim.g.indent_blankline_namespace, 1, -1)
+ end
+ else
+ vim.b.indent_blankline_enabled = false
+ vim.b.__indent_blankline_active = false
+ vim.api.nvim_buf_clear_namespace(0, vim.g.indent_blankline_namespace, 1, -1)
+ end
+end
+
+M.toggle = function(bang)
+ if bang then
+ if vim.g.indent_blankline_enabled then
+ M.disable(bang)
+ else
+ M.enable(bang)
+ end
+ else
+ if vim.b.__indent_blankline_active then
+ M.disable(bang)
+ else
+ M.enable(bang)
+ end
+ end
+end
+
+return M
diff --git a/start/indent-blankline-2.20.4/lua/indent_blankline/init.lua b/start/indent-blankline-2.20.4/lua/indent_blankline/init.lua
new file mode 100644
index 0000000..129458e
--- /dev/null
+++ b/start/indent-blankline-2.20.4/lua/indent_blankline/init.lua
@@ -0,0 +1,651 @@
+local utils = require "indent_blankline/utils"
+local M = {}
+
+local char_highlight = "IndentBlanklineChar"
+local space_char_highlight = "IndentBlanklineSpaceChar"
+local space_char_blankline_highlight = "IndentBlanklineSpaceCharBlankline"
+local context_highlight = "IndentBlanklineContextChar"
+local context_space_char_highlight = "IndentBlanklineContextSpaceChar"
+
+M.init = function()
+ if not vim.g.indent_blankline_namespace then
+ vim.g.indent_blankline_namespace = vim.api.nvim_create_namespace "indent_blankline"
+ end
+
+ utils.reset_highlights()
+
+ require("indent_blankline.commands").refresh(true)
+end
+
+M.setup = function(options)
+ if options == nil then
+ options = {}
+ end
+
+ local o = utils.first_not_nil
+
+ vim.g.indent_blankline_char = o(options.char, vim.g.indent_blankline_char, vim.g.indentLine_char, "│")
+ vim.g.indent_blankline_char_blankline = o(options.char_blankline, vim.g.indent_blankline_char_blankline)
+ vim.g.indent_blankline_char_list =
+ o(options.char_list, vim.g.indent_blankline_char_list, vim.g.indentLine_char_list)
+ vim.g.indent_blankline_char_list_blankline =
+ o(options.char_list_blankline, vim.g.indent_blankline_char_list_blankline)
+ vim.g.indent_blankline_context_char =
+ o(options.context_char, vim.g.indent_blankline_context_char, vim.g.indent_blankline_char)
+ vim.g.indent_blankline_context_char_blankline = o(
+ options.context_char_blankline,
+ vim.g.indent_blankline_context_char_blankline,
+ vim.g.indent_blankline_char_blankline
+ )
+ vim.g.indent_blankline_context_char_list = o(options.context_char_list, vim.g.indent_blankline_context_char_list)
+ vim.g.indent_blankline_context_char_list_blankline =
+ o(options.context_char_list_blankline, vim.g.indent_blankline_context_char_list)
+ vim.g.indent_blankline_char_highlight_list =
+ o(options.char_highlight_list, vim.g.indent_blankline_char_highlight_list)
+ vim.g.indent_blankline_space_char_highlight_list =
+ o(options.space_char_highlight_list, vim.g.indent_blankline_space_char_highlight_list)
+ vim.g.indent_blankline_space_char_blankline =
+ o(options.space_char_blankline, vim.g.indent_blankline_space_char_blankline, " ")
+ vim.g.indent_blankline_space_char_blankline_highlight_list = o(
+ options.space_char_blankline_highlight_list,
+ vim.g.indent_blankline_space_char_blankline_highlight_list,
+ options.space_char_highlight_list,
+ vim.g.indent_blankline_space_char_highlight_list
+ )
+ vim.g.indent_blankline_indent_level = o(options.indent_level, vim.g.indent_blankline_indent_level, 20)
+ vim.g.indent_blankline_enabled = o(options.enabled, vim.g.indent_blankline_enabled, true)
+ vim.g.indent_blankline_disable_with_nolist =
+ o(options.disable_with_nolist, vim.g.indent_blankline_disable_with_nolist, false)
+ vim.g.indent_blankline_filetype = o(options.filetype, vim.g.indent_blankline_filetype, vim.g.indentLine_fileType)
+ vim.g.indent_blankline_filetype_exclude = o(
+ options.filetype_exclude,
+ vim.g.indent_blankline_filetype_exclude,
+ vim.g.indentLine_fileTypeExclude,
+ { "lspinfo", "packer", "checkhealth", "help", "man", "" }
+ )
+ vim.g.indent_blankline_bufname_exclude =
+ o(options.bufname_exclude, vim.g.indent_blankline_bufname_exclude, vim.g.indentLine_bufNameExclude)
+ vim.g.indent_blankline_buftype_exclude = o(
+ options.buftype_exclude,
+ vim.g.indent_blankline_buftype_exclude,
+ vim.g.indentLine_bufTypeExclude,
+ { "terminal", "nofile", "quickfix", "prompt" }
+ )
+ vim.g.indent_blankline_viewport_buffer = o(options.viewport_buffer, vim.g.indent_blankline_viewport_buffer, 10)
+ vim.g.indent_blankline_use_treesitter = o(options.use_treesitter, vim.g.indent_blankline_use_treesitter, false)
+ vim.g.indent_blankline_max_indent_increase = o(
+ options.max_indent_increase,
+ vim.g.indent_blankline_max_indent_increase,
+ options.indent_level,
+ vim.g.indent_blankline_indent_level
+ )
+ vim.g.indent_blankline_show_first_indent_level =
+ o(options.show_first_indent_level, vim.g.indent_blankline_show_first_indent_level, true)
+ vim.g.indent_blankline_show_trailing_blankline_indent =
+ o(options.show_trailing_blankline_indent, vim.g.indent_blankline_show_trailing_blankline_indent, true)
+ vim.g.indent_blankline_show_end_of_line =
+ o(options.show_end_of_line, vim.g.indent_blankline_show_end_of_line, false)
+ vim.g.indent_blankline_show_foldtext = o(options.show_foldtext, vim.g.indent_blankline_show_foldtext, true)
+ vim.g.indent_blankline_show_current_context =
+ o(options.show_current_context, vim.g.indent_blankline_show_current_context, false)
+ vim.g.indent_blankline_show_current_context_start =
+ o(options.show_current_context_start, vim.g.indent_blankline_show_current_context_start, false)
+ vim.g.indent_blankline_use_treesitter_scope =
+ o(options.use_treesitter_scope, vim.g.indent_blankline_use_treesitter_scope, false)
+ vim.g.indent_blankline_show_current_context_start_on_current_line = o(
+ options.show_current_context_start_on_current_line,
+ vim.g.indent_blankline_show_current_context_start_on_current_line,
+ true
+ )
+ vim.g.indent_blankline_context_highlight_list =
+ o(options.context_highlight_list, vim.g.indent_blankline_context_highlight_list)
+ vim.g.indent_blankline_context_patterns = o(options.context_patterns, vim.g.indent_blankline_context_patterns, {
+ "class",
+ "^func",
+ "method",
+ "^if",
+ "while",
+ "for",
+ "with",
+ "try",
+ "except",
+ "match",
+ "arguments",
+ "argument_list",
+ "object",
+ "dictionary",
+ "element",
+ "table",
+ "tuple",
+ "do_block",
+ })
+ vim.g.indent_blankline_context_pattern_highlight =
+ o(options.context_pattern_highlight, vim.g.indent_blankline_context_pattern_highlight)
+ vim.g.indent_blankline_strict_tabs = o(options.strict_tabs, vim.g.indent_blankline_strict_tabs, false)
+
+ vim.g.indent_blankline_disable_warning_message =
+ o(options.disable_warning_message, vim.g.indent_blankline_disable_warning_message, false)
+ vim.g.indent_blankline_char_priority = o(options.char_priority, vim.g.indent_blankline_char_priority, 1)
+ vim.g.indent_blankline_context_start_priority =
+ o(options.context_start_priority, vim.g.indent_blankline_context_start_priority, 10000)
+
+ if vim.g.indent_blankline_show_current_context then
+ vim.cmd [[
+ augroup IndentBlanklineContextAutogroup
+ autocmd!
+ autocmd CursorMoved,CursorMovedI * IndentBlanklineRefresh
+ augroup END
+ ]]
+ end
+
+ vim.g.__indent_blankline_setup_completed = true
+end
+
+local refresh = function(scroll)
+ local v = utils.get_variable
+ local bufnr = vim.api.nvim_get_current_buf()
+
+ if not vim.api.nvim_buf_is_loaded(bufnr) then
+ return
+ end
+
+ if
+ not utils.is_indent_blankline_enabled(
+ vim.b.indent_blankline_enabled,
+ vim.g.indent_blankline_enabled,
+ v "indent_blankline_disable_with_nolist",
+ vim.opt.list:get(),
+ vim.bo.filetype,
+ v "indent_blankline_filetype" or {},
+ v "indent_blankline_filetype_exclude",
+ vim.bo.buftype,
+ v "indent_blankline_buftype_exclude" or {},
+ v "indent_blankline_bufname_exclude" or {},
+ vim.fn["bufname"] ""
+ )
+ then
+ if vim.b.__indent_blankline_active then
+ vim.schedule_wrap(utils.clear_buf_indent)(bufnr)
+ end
+ vim.b.__indent_blankline_active = false
+ return
+ else
+ vim.b.__indent_blankline_active = true
+ end
+
+ local win_start = vim.fn.line "w0"
+ local win_end = vim.fn.line "w$"
+ local offset = math.max(win_start - 1 - v "indent_blankline_viewport_buffer", 0)
+ local win_view = vim.fn.winsaveview()
+ local left_offset = win_view.leftcol
+ local lnum = win_view.lnum
+ local left_offset_s = tostring(left_offset)
+ local range = math.min(win_end + v "indent_blankline_viewport_buffer", vim.api.nvim_buf_line_count(bufnr))
+
+ if not vim.b.__indent_blankline_ranges then
+ vim.b.__indent_blankline_ranges = {}
+ end
+
+ if scroll then
+ local updated_range
+
+ if vim.b.__indent_blankline_ranges[left_offset_s] then
+ local blankline_ranges = vim.b.__indent_blankline_ranges[left_offset_s]
+ local need_to_update = true
+
+ -- find a candidate that could contain the window
+ local idx_candidate = utils.binary_search_ranges(blankline_ranges, { win_start, win_end })
+ local candidate_start, candidate_end = unpack(blankline_ranges[idx_candidate])
+
+ -- check if the current window is contained or if a new range needs to be created
+ if candidate_start <= win_start then
+ if candidate_end >= win_end then
+ need_to_update = false
+ else
+ table.insert(blankline_ranges, idx_candidate + 1, { offset, range })
+ end
+ else
+ table.insert(blankline_ranges, idx_candidate, { offset, range })
+ end
+
+ if not need_to_update then
+ return
+ end
+
+ -- merge ranges and update the variable, strategies are: contains or extends
+ updated_range = utils.merge_ranges(blankline_ranges)
+ else
+ updated_range = { { offset, range } }
+ end
+
+ -- we can't assign directly to a table key, so we update the reference to the variable
+ local new_ranges = vim.b.__indent_blankline_ranges
+ new_ranges[left_offset_s] = updated_range
+ vim.b.__indent_blankline_ranges = new_ranges
+ else
+ vim.b.__indent_blankline_ranges = { [left_offset_s] = { { offset, range } } }
+ end
+
+ local lines = vim.api.nvim_buf_get_lines(bufnr, offset, range, false)
+ local char = v "indent_blankline_char"
+ local char_blankline = v "indent_blankline_char_blankline"
+ local char_list = v "indent_blankline_char_list" or {}
+ local char_list_blankline = v "indent_blankline_char_list_blankline" or {}
+ local context_char = v "indent_blankline_context_char"
+ local context_char_blankline = v "indent_blankline_context_char_blankline"
+ local context_char_list = v "indent_blankline_context_char_list" or {}
+ local context_char_list_blankline = v "indent_blankline_context_char_list_blankline" or {}
+ local char_highlight_list = v "indent_blankline_char_highlight_list" or {}
+ local space_char_highlight_list = v "indent_blankline_space_char_highlight_list" or {}
+ local space_char_blankline_highlight_list = v "indent_blankline_space_char_blankline_highlight_list" or {}
+ local space_char_blankline = v "indent_blankline_space_char_blankline"
+ local char_priority = v "indent_blankline_char_priority"
+ local context_start_priority = v "indent_blankline_context_start_priority"
+
+ local list_chars
+ local no_tab_character = false
+ -- No need to check for disable_with_nolist as this part would never be executed if "true" && nolist
+ if vim.opt.list:get() then
+ -- list is set, get listchars
+ local tab_characters
+ local space_character = vim.opt.listchars:get().space or " "
+ if vim.opt.listchars:get().tab then
+ -- tab characters can be any UTF-8 character, Lua 5.1 cannot handle this without external libraries
+ tab_characters = vim.fn.split(vim.opt.listchars:get().tab, "\\zs")
+ else
+ no_tab_character = true
+ tab_characters = { "^", "I" }
+ end
+ list_chars = {
+ space_char = space_character,
+ trail_char = vim.opt.listchars:get().trail or space_character,
+ lead_char = vim.opt.listchars:get().lead or space_character,
+ tab_char_start = tab_characters[1] or space_character,
+ tab_char_fill = tab_characters[2] or space_character,
+ tab_char_end = tab_characters[3],
+ eol_char = vim.opt.listchars:get().eol,
+ }
+ else
+ -- nolist is set, replace all listchars with empty space
+ list_chars = {
+ space_char = " ",
+ trail_char = " ",
+ lead_char = " ",
+ tab_char_start = " ",
+ tab_char_fill = " ",
+ tab_char_end = nil,
+ eol_char = nil,
+ }
+ end
+
+ local max_indent_level = v "indent_blankline_indent_level"
+ local max_indent_increase = v "indent_blankline_max_indent_increase"
+ local expandtab = vim.bo.expandtab
+ local use_ts_indent = false
+ local ts_indent
+ if v "indent_blankline_use_treesitter" then
+ local ts_query_status, ts_query = pcall(require, "nvim-treesitter.query")
+ if not ts_query_status then
+ vim.schedule_wrap(function()
+ utils.error_handler("nvim-treesitter not found. Treesitter indent will not work", vim.log.levels.WARN)
+ end)()
+ end
+ local ts_indent_status
+ ts_indent_status, ts_indent = pcall(require, "nvim-treesitter.indent")
+ use_ts_indent = ts_query_status and ts_indent_status and ts_query.has_indents(vim.bo.filetype)
+ end
+ local first_indent = v "indent_blankline_show_first_indent_level"
+ local trail_indent = v "indent_blankline_show_trailing_blankline_indent"
+ local end_of_line = v "indent_blankline_show_end_of_line"
+ local strict_tabs = v "indent_blankline_strict_tabs"
+ local foldtext = v "indent_blankline_show_foldtext"
+
+ local tabs = vim.bo.shiftwidth == 0 or not expandtab
+ local shiftwidth = utils._if(tabs, utils._if(no_tab_character, 2, vim.bo.tabstop), vim.bo.shiftwidth)
+
+ local context_highlight_list = v "indent_blankline_context_highlight_list" or {}
+ local context_pattern_highlight = v "indent_blankline_context_pattern_highlight" or {}
+ local context_status, context_start, context_end, context_pattern = false, 0, 0, nil
+ local show_current_context_start = v "indent_blankline_show_current_context_start"
+ local show_current_context_start_on_current_line = v "indent_blankline_show_current_context_start_on_current_line"
+ if v "indent_blankline_show_current_context" then
+ context_status, context_start, context_end, context_pattern =
+ utils.get_current_context(v "indent_blankline_context_patterns", v "indent_blankline_use_treesitter_scope")
+ end
+
+ local get_virtual_text =
+ function(indent, extra, blankline, context_active, context_indent, prev_indent, virtual_string)
+ local virtual_text = {}
+ local current_left_offset = left_offset
+ local local_max_indent_level = math.min(max_indent_level, prev_indent + max_indent_increase)
+ local indent_char = utils._if(blankline and char_blankline, char_blankline, char)
+ local context_indent_char =
+ utils._if(blankline and context_char_blankline, context_char_blankline, context_char)
+ local indent_char_list = utils._if(blankline and #char_list_blankline > 0, char_list_blankline, char_list)
+ local context_indent_char_list = utils._if(
+ blankline and #context_char_list_blankline > 0,
+ context_char_list_blankline,
+ context_char_list
+ )
+ for i = 1, math.min(math.max(indent, 0), local_max_indent_level) do
+ local space_count = shiftwidth
+ local context = context_active and context_indent == i
+ local show_indent_char = (i ~= 1 or first_indent) and indent_char ~= ""
+ local show_context_indent_char = context and (i ~= 1 or first_indent) and context_indent_char ~= ""
+ local show_end_of_line_char = i == 1 and blankline and end_of_line and list_chars["eol_char"]
+ local show_indent_or_eol_char = show_indent_char or show_context_indent_char or show_end_of_line_char
+ if show_indent_or_eol_char then
+ space_count = space_count - 1
+ if current_left_offset > 0 then
+ current_left_offset = current_left_offset - 1
+ else
+ table.insert(virtual_text, {
+ utils._if(
+ show_end_of_line_char,
+ list_chars["eol_char"],
+ utils._if(
+ context,
+ utils.get_from_list(
+ context_indent_char_list,
+ i - utils._if(not first_indent, 1, 0),
+ context_indent_char
+ ),
+ utils.get_from_list(
+ indent_char_list,
+ i - utils._if(not first_indent, 1, 0),
+ indent_char
+ )
+ )
+ ),
+ utils._if(
+ context,
+ utils._if(
+ context_pattern_highlight[context_pattern],
+ context_pattern_highlight[context_pattern],
+ utils.get_from_list(context_highlight_list, i, context_highlight)
+ ),
+ utils.get_from_list(char_highlight_list, i, char_highlight)
+ ),
+ })
+ end
+ end
+ if current_left_offset > 0 then
+ local current_space_count = space_count
+ space_count = space_count - current_left_offset
+ current_left_offset = current_left_offset - current_space_count
+ end
+ if space_count > 0 then
+ -- ternary operator below in table.insert() doesn't work because it would evaluate each option regardless
+ local tmp_string
+ local index = 1 + (i - 1) * shiftwidth
+ if show_indent_or_eol_char then
+ if table.maxn(virtual_string) >= index + space_count then
+ -- first char was already set above
+ tmp_string = table.concat(virtual_string, "", index + 1, index + space_count)
+ end
+ else
+ if table.maxn(virtual_string) >= index + space_count - 1 then
+ tmp_string = table.concat(virtual_string, "", index, index + space_count - 1)
+ end
+ end
+ table.insert(virtual_text, {
+ utils._if(
+ tmp_string,
+ tmp_string,
+ utils._if(blankline, space_char_blankline, list_chars["lead_char"]):rep(space_count)
+ ),
+ utils._if(
+ blankline,
+ utils.get_from_list(space_char_blankline_highlight_list, i, space_char_blankline_highlight),
+ utils.get_from_list(
+ space_char_highlight_list,
+ i,
+ utils._if(context, context_space_char_highlight, space_char_highlight)
+ )
+ ),
+ })
+ end
+ end
+
+ local index = math.ceil(#virtual_text / 2) + 1
+ local extra_context_active = context_active and context_indent == index
+
+ if
+ (
+ (indent_char ~= "" or #indent_char_list > 0)
+ or (extra_context_active and (context_indent_char ~= "" or #context_char_list > 0))
+ )
+ and ((blankline or extra) and trail_indent)
+ and (first_indent or #virtual_text > 0)
+ and current_left_offset < 1
+ and indent < local_max_indent_level
+ then
+ table.insert(virtual_text, {
+ utils._if(
+ extra_context_active,
+ utils.get_from_list(
+ context_indent_char_list,
+ index - utils._if(not first_indent, 1, 0),
+ context_indent_char
+ ),
+ utils.get_from_list(indent_char_list, index - utils._if(not first_indent, 1, 0), indent_char)
+ ),
+ utils._if(
+ extra_context_active,
+ utils.get_from_list(context_highlight_list, index, context_highlight),
+ utils.get_from_list(char_highlight_list, index, char_highlight)
+ ),
+ })
+ end
+
+ return virtual_text
+ end
+
+ local prev_indent
+ local next_indent
+ local next_extra
+ local empty_line_counter = 0
+ local context_indent
+ for i = 1, #lines do
+ if foldtext and vim.fn.foldclosed(i + offset) > 0 then
+ utils.clear_line_indent(bufnr, i + offset)
+ else
+ local async
+ async = vim.loop.new_async(function()
+ local blankline = lines[i]:len() == 0
+ local whitespace = string.match(lines[i], "^%s+") or ""
+ local only_whitespace = whitespace == lines[i]
+ local context_active = false
+ local context_first_line = false
+ if context_status then
+ context_active = offset + i > context_start and offset + i <= context_end
+ context_first_line = offset + i == context_start
+ end
+
+ if blankline and use_ts_indent then
+ vim.schedule_wrap(function()
+ local indent = ts_indent.get_indent(i + offset) or 0
+ utils.clear_line_indent(bufnr, i + offset)
+
+ if
+ context_first_line
+ and show_current_context_start
+ and (show_current_context_start_on_current_line or lnum ~= context_start)
+ then
+ if
+ not vim.api.nvim_buf_is_loaded(bufnr)
+ or not vim.api.nvim_buf_get_var(bufnr, "__indent_blankline_active")
+ then
+ return
+ end
+ xpcall(
+ vim.api.nvim_buf_set_extmark,
+ utils.error_handler,
+ bufnr,
+ vim.g.indent_blankline_namespace,
+ context_start - 1,
+ #whitespace,
+ {
+ end_col = #lines[i],
+ hl_group = "IndentBlanklineContextStart",
+ priority = context_start_priority,
+ }
+ )
+ end
+
+ if indent == 0 then
+ return
+ end
+
+ indent = indent / shiftwidth
+ if context_first_line then
+ context_indent = indent + 1
+ end
+
+ local virtual_text = get_virtual_text(
+ indent,
+ false,
+ blankline,
+ context_active,
+ context_indent,
+ max_indent_level,
+ {}
+ )
+ if
+ not vim.api.nvim_buf_is_loaded(bufnr)
+ or not vim.api.nvim_buf_get_var(bufnr, "__indent_blankline_active")
+ then
+ return
+ end
+ xpcall(
+ vim.api.nvim_buf_set_extmark,
+ utils.error_handler,
+ bufnr,
+ vim.g.indent_blankline_namespace,
+ i - 1 + offset,
+ 0,
+ {
+ virt_text = virtual_text,
+ virt_text_pos = "overlay",
+ hl_mode = "combine",
+ priority = char_priority,
+ }
+ )
+ end)()
+ return async:close()
+ end
+
+ local indent, extra
+ local virtual_string = {}
+ if not blankline then
+ indent, extra, virtual_string =
+ utils.find_indent(whitespace, only_whitespace, shiftwidth, strict_tabs, list_chars)
+ elseif empty_line_counter > 0 then
+ empty_line_counter = empty_line_counter - 1
+ indent = next_indent
+ extra = next_extra
+ else
+ if i == #lines then
+ indent = 0
+ extra = false
+ else
+ local j = i + 1
+ while j < #lines and lines[j]:len() == 0 do
+ j = j + 1
+ empty_line_counter = empty_line_counter + 1
+ end
+ local j_whitespace = string.match(lines[j], "^%s+")
+ local j_only_whitespace = j_whitespace == lines[j]
+ indent, extra, _ =
+ utils.find_indent(j_whitespace, j_only_whitespace, shiftwidth, strict_tabs, list_chars)
+ end
+ next_indent = indent
+ next_extra = extra
+ end
+
+ if context_first_line then
+ context_indent = indent + 1
+ end
+
+ vim.schedule_wrap(utils.clear_line_indent)(bufnr, i + offset)
+ if
+ context_first_line
+ and show_current_context_start
+ and (show_current_context_start_on_current_line or lnum ~= context_start)
+ then
+ vim.schedule_wrap(function()
+ if
+ not vim.api.nvim_buf_is_loaded(bufnr)
+ or not vim.api.nvim_buf_get_var(bufnr, "__indent_blankline_active")
+ then
+ return
+ end
+ xpcall(
+ vim.api.nvim_buf_set_extmark,
+ utils.error_handler,
+ bufnr,
+ vim.g.indent_blankline_namespace,
+ context_start - 1,
+ #whitespace,
+ {
+ end_col = #lines[i],
+ hl_group = "IndentBlanklineContextStart",
+ priority = context_start_priority,
+ }
+ )
+ end)()
+ end
+
+ if indent == 0 and #virtual_string == 0 and not extra then
+ prev_indent = 0
+ return async:close()
+ end
+
+ if not prev_indent or indent + utils._if(extra, 1, 0) <= prev_indent + max_indent_increase then
+ prev_indent = indent
+ end
+
+ local virtual_text = get_virtual_text(
+ indent,
+ extra,
+ blankline,
+ context_active,
+ context_indent,
+ prev_indent - utils._if(trail_indent, 0, 1),
+ virtual_string
+ )
+ vim.schedule_wrap(function()
+ if
+ not vim.api.nvim_buf_is_loaded(bufnr)
+ or not vim.api.nvim_buf_get_var(bufnr, "__indent_blankline_active")
+ then
+ return
+ end
+ xpcall(
+ vim.api.nvim_buf_set_extmark,
+ utils.error_handler,
+ bufnr,
+ vim.g.indent_blankline_namespace,
+ i - 1 + offset,
+ 0,
+ {
+ virt_text = virtual_text,
+ virt_text_pos = "overlay",
+ hl_mode = "combine",
+ priority = char_priority,
+ }
+ )
+ end)()
+ return async:close()
+ end)
+
+ async:send()
+ end
+ end
+end
+
+M.refresh = function(scroll)
+ xpcall(refresh, utils.error_handler, scroll)
+end
+
+return M
diff --git a/start/indent-blankline-2.20.4/lua/indent_blankline/utils.lua b/start/indent-blankline-2.20.4/lua/indent_blankline/utils.lua
new file mode 100644
index 0000000..e21a5c9
--- /dev/null
+++ b/start/indent-blankline-2.20.4/lua/indent_blankline/utils.lua
@@ -0,0 +1,341 @@
+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, level)
+ if err:match "Invalid buffer id.*" then
+ return
+ end
+ if not pcall(require, "notify") then
+ err = string.format("indent-blankline: %s", err)
+ end
+ vim.notify_once(err, level or vim.log.levels.DEBUG, {
+ title = "indent-blankline",
+ })
+end
+
+M.is_indent_blankline_enabled = M.memo(
+ function(
+ b_enabled,
+ g_enabled,
+ disable_with_nolist,
+ opt_list,
+ filetype,
+ filetype_include,
+ filetype_exclude,
+ buftype,
+ buftype_exclude,
+ bufname_exclude,
+ bufname
+ )
+ if b_enabled ~= nil then
+ return b_enabled
+ end
+ if g_enabled ~= true then
+ return false
+ end
+ if disable_with_nolist and not opt_list then
+ return false
+ end
+
+ local plain = M._if(vim.fn.has "nvim-0.6.0" == 1, { plain = true }, true)
+ local undotted_filetypes = vim.split(filetype, ".", plain)
+ table.insert(undotted_filetypes, filetype)
+
+ for _, ft in ipairs(filetype_exclude) do
+ for _, undotted_filetype in ipairs(undotted_filetypes) do
+ if undotted_filetype == ft then
+ return false
+ end
+ 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.clear_buf_indent = function(buf)
+ xpcall(vim.api.nvim_buf_clear_namespace, M.error_handler, buf, vim.g.indent_blankline_namespace, 0, -1)
+end
+
+M.get_from_list = function(list, i, default)
+ if not list or #list == 0 then
+ return default
+ end
+ 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(whitespace, only_whitespace, shiftwidth, strict_tabs, list_chars)
+ local indent = 0
+ local spaces = 0
+ local tab_width
+ local virtual_string = {}
+
+ if whitespace then
+ for ch in whitespace:gmatch "." do
+ if ch == "\t" then
+ if strict_tabs and indent == 0 and spaces ~= 0 then
+ return 0, false, {}
+ end
+ indent = indent + math.floor(spaces / shiftwidth) + 1
+ spaces = 0
+ -- replace dynamic-width tab with fixed-width string (ta..ab)
+ tab_width = shiftwidth - table.maxn(virtual_string) % shiftwidth
+ -- check if tab_char_end is set, see :help listchars
+ if list_chars["tab_char_end"] then
+ if tab_width == 1 then
+ table.insert(virtual_string, list_chars["tab_char_end"])
+ else
+ table.insert(virtual_string, list_chars["tab_char_start"])
+ for _ = 1, (tab_width - 2) do
+ table.insert(virtual_string, list_chars["tab_char_fill"])
+ end
+ table.insert(virtual_string, list_chars["tab_char_end"])
+ end
+ else
+ table.insert(virtual_string, list_chars["tab_char_start"])
+ for _ = 1, (tab_width - 1) do
+ table.insert(virtual_string, list_chars["tab_char_fill"])
+ end
+ end
+ else
+ if strict_tabs and indent ~= 0 then
+ -- return early when no more tabs are found
+ return indent, true, virtual_string
+ end
+ if only_whitespace then
+ -- if the entire line is only whitespace use trail_char instead of lead_char
+ table.insert(virtual_string, list_chars["trail_char"])
+ else
+ table.insert(virtual_string, list_chars["lead_char"])
+ end
+ spaces = spaces + 1
+ end
+ end
+ end
+
+ return indent + math.floor(spaces / shiftwidth), table.maxn(virtual_string) % shiftwidth ~= 0, virtual_string
+end
+
+M.get_current_context = function(type_patterns, use_treesitter_scope)
+ local ts_utils_status, ts_utils = pcall(require, "nvim-treesitter.ts_utils")
+ if not ts_utils_status then
+ vim.schedule_wrap(function()
+ M.error_handler("nvim-treesitter not found. Context will not work", vim.log.levels.WARN)
+ end)()
+ return false
+ end
+ local locals = require "nvim-treesitter.locals"
+ local cursor_node = ts_utils.get_node_at_cursor()
+
+ if use_treesitter_scope then
+ local current_scope = locals.containing_scope(cursor_node, 0)
+ if not current_scope then
+ return false
+ end
+ local node_start, _, node_end, _ = current_scope:range()
+ if node_start == node_end then
+ return false
+ end
+ return true, node_start + 1, node_end + 1, current_scope:type()
+ end
+
+ 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, rgx
+ end
+ 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,
+ IndentBlanklineContextStart = 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") == ""
+ and vim.fn.synIDattr(current_highlight, "sp") == ""
+ then
+ if highlight_name == "IndentBlanklineContextStart" then
+ vim.cmd(
+ string.format(
+ "highlight %s guisp=%s gui=underline cterm=underline",
+ highlight_name,
+ M._if(highlight[1] == "", "NONE", highlight[1])
+ )
+ )
+ else
+ 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
+end
+
+M.first_not_nil = function(...)
+ for _, value in pairs { ... } do -- luacheck: ignore
+ return value
+ end
+end
+
+M.get_variable = function(key)
+ if vim.b[key] ~= nil then
+ return vim.b[key]
+ end
+ if vim.t[key] ~= nil then
+ return vim.t[key]
+ end
+ return vim.g[key]
+end
+
+M.merge_ranges = function(ranges)
+ local merged_ranges = { { unpack(ranges[1]) } }
+
+ for i = 2, #ranges do
+ local current_end = merged_ranges[#merged_ranges][2]
+ local next_start, next_end = unpack(ranges[i])
+ if current_end >= next_start - 1 then
+ if current_end < next_end then
+ merged_ranges[#merged_ranges][2] = next_end
+ end
+ else
+ table.insert(merged_ranges, { next_start, next_end })
+ end
+ end
+
+ return merged_ranges
+end
+
+M.binary_search_ranges = function(ranges, target_range)
+ local exact_match = false
+ local idx_start = 1
+ local idx_end = #ranges
+ local idx_mid
+
+ local range_start
+ local target_start = target_range[1]
+
+ while idx_start < idx_end do
+ idx_mid = math.ceil((idx_start + idx_end) / 2)
+ range_start = ranges[idx_mid][1]
+
+ if range_start == target_start then
+ exact_match = true
+ break
+ elseif range_start < target_start then
+ idx_start = idx_mid -- it's important to make the low-end inclusive
+ else
+ idx_end = idx_mid - 1
+ end
+ end
+
+ -- if we don't have an exact match, choose the smallest index
+ if not exact_match then
+ idx_mid = idx_start
+ end
+
+ return idx_mid
+end
+
+return M