Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only show indent guides for current block (resolves #561) #723

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
145 changes: 77 additions & 68 deletions doc/indent_blankline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -330,6 +338,7 @@ config.indent *ibl.config.indent*
highlight = { "Function", "Label" },
smart_indent_cap = true,
priority = 2,
current_block_only = true,
}
<

Expand Down
2 changes: 2 additions & 0 deletions lua/ibl/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ M.default_config = {
highlight = "IblIndent",
smart_indent_cap = true,
priority = 1,
current_block_only = false,
},
whitespace = {
highlight = "IblWhitespace",
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions lua/ibl/config.types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
53 changes: 53 additions & 0 deletions lua/ibl/indent.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local scope = require "ibl.scope"

local M = {}

---@enum ibl.indent.whitespace
Expand Down Expand Up @@ -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
19 changes: 19 additions & 0 deletions lua/ibl/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down