diff --git a/doc/indent_blankline.txt b/doc/indent_blankline.txt index 7b21a304..89cd8f3a 100644 --- a/doc/indent_blankline.txt +++ b/doc/indent_blankline.txt @@ -240,87 +240,95 @@ config.viewport_buffer *ibl.config.viewport_buffer* { min = 100, max = 600 } < -config.indent *ibl.config.indent* +config.indent *ibl.config.indent* Configures the indentation Fields: ~ - *ibl.config.indent.char* - • {char} (string|string[]) - Character, or list of characters, that get used to - display the indentation guide - Each character has to have a display width of 0 or 1 - - Default: `▎` ~ - - Alternatives: ~ - • left aligned solid - • `▏` - • `▎` (default) - • `▍` - • `▌` - • `▋` - • `▊` - • `▉` - • `█` - • center aligned solid - • `│` - • `┃` - • right aligned solid - • `▕` - • `▐` - • center aligned dashed - • `╎` - • `╏` - • `┆` - • `┇` - • `┊` - • `┋` - • center aligned double - • `║` - - *ibl.config.indent.tab_char* - • {tab_char} (string|string[]) - Character, or list of characters, that get used to - display the indentation guide for tabs - Each character has to have a display width of 0 or 1 - - Default: uses |lcs-tab| if |'list'| is set, ~ - otherwise, uses |ibl.config.indent.char| ~ + *ibl.config.indent.char* + • {char} (string|string[]) + Character, or list of characters, that get used to + display the indentation guide + Each character has to have a display width of 0 or 1 + + Default: `▎` ~ + + Alternatives: ~ + • left aligned solid + • `▏` + • `▎` (default) + • `▍` + • `▌` + • `▋` + • `▊` + • `▉` + • `█` + • center aligned solid + • `│` + • `┃` + • right aligned solid + • `▕` + • `▐` + • center aligned dashed + • `╎` + • `╏` + • `┆` + • `┇` + • `┊` + • `┋` + • center aligned double + • `║` + + *ibl.config.indent.tab_char* + • {tab_char} (string|string[]) + Character, or list of characters, that get used to + display the indentation guide for tabs + Each character has to have a display width of 0 or 1 + + Default: uses |lcs-tab| if |'list'| is set, ~ + otherwise, uses |ibl.config.indent.char| ~ + *ibl.config.indent.highlight* - • {highlight} (string|string[]) - Highlight group, or list of highlight groups, that - get applied to the indentation guide + • {highlight} (string|string[]) + Highlight group, or list of highlight groups, that + get applied to the indentation guide - Default: |hl-IblIndent| ~ + Default: |hl-IblIndent| ~ - *ibl.config.indent.smart_indent_cap* - • {smart_indent_cap} (boolean) - Caps the number of indentation levels by looking at - the surrounding code + *ibl.config.indent.smart_indent_cap* + • {smart_indent_cap} (boolean) + Caps the number of indentation levels by looking at + the surrounding code - Default: `true` ~ + Default: `true` ~ - Example: ~ + Example: ~ >c - # OFF - { - ▎ foo_bar(a, b, - ▎ ▎ ▎ ▎ ▎ c, d); - } - - # ON - { - ▎ foo_bar(a, b, - ▎ ▎ c, d); - } + # OFF + { + ▎ foo_bar(a, b, + ▎ ▎ ▎ ▎ ▎ c, d); + } + + # ON + { + ▎ foo_bar(a, b, + ▎ ▎ c, d); + } < - *ibl.config.indent.priority* - • {priority} (number) - Virtual text priority for the indentation guide + *ibl.config.indent.priority* + • {priority} (number) + Virtual text priority for the indentation guide + + Default: `1` ~ + + *ibl.config.indent.current_block_only* + • {current_block_only} (number) + Only show indent guides in the current code block + + Default: `false` ~ - Default: `1` ~ Example: ~ >lua @@ -330,6 +338,7 @@ config.indent *ibl.config.indent* highlight = { "Function", "Label" }, smart_indent_cap = true, priority = 2, + current_block_only = true, } < diff --git a/lua/ibl/config.lua b/lua/ibl/config.lua index 9fa36595..63b7af1d 100644 --- a/lua/ibl/config.lua +++ b/lua/ibl/config.lua @@ -29,6 +29,7 @@ M.default_config = { highlight = "IblIndent", smart_indent_cap = true, priority = 1, + current_block_only = false, }, whitespace = { highlight = "IblWhitespace", @@ -133,6 +134,7 @@ local validate_config = function(config) highlight = { config.indent.highlight, { "string", "table" }, true }, smart_indent_cap = { config.indent.smart_indent_cap, "boolean", true }, priority = { config.indent.priority, "number", true }, + current_block_only = { config.indent.current_block_only, "boolean", true }, }, config.indent, "ibl.config.indent") if config.indent.char then vim.validate { diff --git a/lua/ibl/config.types.lua b/lua/ibl/config.types.lua index eb13694b..78619343 100644 --- a/lua/ibl/config.types.lua +++ b/lua/ibl/config.types.lua @@ -42,6 +42,8 @@ ---@field smart_indent_cap boolean? --- Virtual text priority for the indentation guide ---@field priority number? +--- Only show indentation guide for the current block +---@field current_block_only boolean? ---@class ibl.config.whitespace --- Highlight group, or list of highlight groups, that get applied to the whitespace @@ -158,6 +160,8 @@ ---@field smart_indent_cap boolean --- Virtual text priority for the indentation guide ---@field priority number +--- Only show indentation guide for the current block +---@field current_block_only boolean ---@class ibl.config.full.whitespace: ibl.config.whitespace --- Highlight group, or list of highlight groups, that get applied to the whitespace diff --git a/lua/ibl/indent.lua b/lua/ibl/indent.lua index 0e394719..baf511f4 100644 --- a/lua/ibl/indent.lua +++ b/lua/ibl/indent.lua @@ -1,3 +1,5 @@ +local scope = require "ibl.scope" + local M = {} ---@enum ibl.indent.whitespace @@ -114,4 +116,55 @@ M.is_space_indent = function(whitespace) return vim.tbl_contains({ M.whitespace.INDENT, M.whitespace.SPACE }, whitespace) end +---@param bufnr number +---@param config ibl.config.full +---@return TSNode? +M.get_current_block = function(bufnr, config) + local lang_tree_ok, lang_tree = pcall(vim.treesitter.get_parser, bufnr) + if not lang_tree_ok or not lang_tree then + return nil + end + + local win + if bufnr ~= vim.api.nvim_get_current_buf() then + local win_list = vim.fn.win_findbuf(bufnr) + win = win_list and win_list[1] + if not win then + return nil + end + else + win = 0 + end + + local range = scope.get_cursor_range(win) + lang_tree = scope.language_for_range(lang_tree, range, config) + if not lang_tree then + return nil + end + + -- get the current_node at the mouse + local current_node = vim.treesitter.get_node() + if current_node then + local current_block = current_node:tree():root() + local parent_block = current_node --[[@as TSNode|nil]] + if current_block == parent_block then + -- if we are in the root, don't show indents + return nil + end + while parent_block do + -- go up the tree until we are one step below the root + if parent_block:parent() == current_block then + current_block = parent_block + break + else + parent_block = parent_block:parent() + end + end + return current_block + else + -- if we can't get current_node, then don't show indents anywhere + return nil + end +end + return M diff --git a/lua/ibl/init.lua b/lua/ibl/init.lua index 76772517..8eb1b7dd 100644 --- a/lua/ibl/init.lua +++ b/lua/ibl/init.lua @@ -260,6 +260,25 @@ M.refresh = function(bufnr) end end + if config.indent.current_block_only then + local current_block = indent.get_current_block(bufnr, config) + if current_block then + local block_start_row, _, block_end_row, _ = current_block:range() + block_start_row, block_end_row = block_start_row + 1, block_end_row + 1 + for i, _ in ipairs(lines) do + local row = i + offset + if block_start_row > row or block_end_row < row then + -- skip lines not in the current block + line_skipped[i] = true + end + end + else + for i, _ in ipairs(lines) do + line_skipped[i] = true + end + end + end + for i, line in ipairs(lines) do local row = i + offset if line_skipped[i] then