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

Fast current_indent (resolves #649) #726

Closed
wants to merge 16 commits into from
90 changes: 90 additions & 0 deletions doc/indent_blankline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ config *ibl.config*
• {scope} (|ibl.config.scope|)
Configures the scope

• {current_indent} (|ibl.config.current_indent|)
Configures the current_indent

• {exclude} (|ibl.config.exclude|)
Configures what is excluded from indent-blankline

Expand All @@ -211,6 +214,7 @@ config *ibl.config*
indent = { char = "|" },
whitespace = { highlight = { "Whitespace", "NonText" } },
scope = { exclude = { language = { "lua" } } },
current_indent = { enabled = true },
}
<

Expand Down Expand Up @@ -541,6 +545,92 @@ config.scope.exclude *ibl.config.scope.exclude*
}
<

config.current_indent *ibl.config.current_indent*

Configures the current indent

The current indent *is* the current indentation level (unlike scope).

Example: ~

In Python, using the same example as above, current_indent will highlight the
current inner most indentation guide. With scope disabled, this will look like
this:
>python
def foo();
if True:
┋ a = "foo █ar"
┋ # ↳ cursor here
print(a)
<
If we have the same code with scope enabled, it will look like this:
>python
def foo();
┋ if True:
┋ ┋ a = "foo █ar"
┋ ┋ # ↳ cursor here
┋ print(a)
<
If you have both scope and current_indent enabled and the two overlap, the
scope will take priority by default. So the Rust example from above will look
identical since the scope matches the current indent level. To make
current_indent take priority, make sure that its priority is set to a higher
value than scope's priority.
(this code would not compile)
>rust
fn foo() {
if true {
┋ let a = "foo █ar";
┋ // ↳ cursor here
}
print(a);
}
<
Fields: ~
*ibl.config.current_indent.enabled*
• {enabled} (boolean)
Enables or disables current_indent

Default: `false` ~

*ibl.config.current_indent.char*
• {char} (string)
Character that gets used to display the current
indents indentation guide
Each character has to have a display width
of 0 or 1

Default: |ibl.config.indent.char| ~


*ibl.config.current_indent.highlight*
• {highlight} (string)
Highlight group that gets applied to the current
indent

Default: |hl-IblCurrentIndent| ~

*ibl.config.current_indent.show_start*
• {show_start} (boolean)
Shows an underline on the line above the current
indent level

Default: `true` ~

*ibl.config.current_indent.show_end*
• {show_end} (boolean)
Shows an underline on the line below the current
indent level

Default: `true` ~

*ibl.config.current_indent.priority*
• {priority} (number)
Virtual text priority for the current_indent

Default: `64` ~


config.exclude *ibl.config.exclude*

Configures what is excluded from indent-blankline
Expand Down
29 changes: 29 additions & 0 deletions lua/ibl/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ M.default_config = {
},
},
},
current_indent = {
enabled = false,
char = nil,
highlight = "IblCurrentIndent",
show_start = false,
show_end = false,
priority = 64,
},
exclude = {
filetypes = {
"lspinfo",
Expand Down Expand Up @@ -116,6 +124,7 @@ local validate_config = function(config)
indent = { config.indent, "table", true },
whitespace = { config.whitespace, "table", true },
scope = { config.scope, "table", true },
current_indent = { config.current_indent, "table", true },
exclude = { config.exclude, "table", true },
}, config, "ibl.config")

Expand Down Expand Up @@ -229,6 +238,26 @@ local validate_config = function(config)
end
end

if config.current_indent then
utils.validate({
enabled = { config.current_indent.enabled, "boolean", true },
char = { config.current_indent.char, "string", true },
highlight = { config.current_indent.highlight, "string", true },
show_start = { config.current_indent.show_start, "boolean", true },
show_end = { config.current_indent.show_end, "boolean", true },
priority = { config.current_indent.priority, "number", true },
}, config.current_indent, "ibl.config.current_indent")
if config.current_indent.char then
vim.validate {
char = {
config.current_indent.char,
validate_char,
"current_indent.char to have a display width of 0 or 1",
},
}
end
end

if config.exclude then
if config.exclude then
utils.validate({
Expand Down
38 changes: 37 additions & 1 deletion lua/ibl/config.types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
---@field whitespace ibl.config.whitespace?
--- Configures the scope
---@field scope ibl.config.scope?
--- Configures the current_indent
---@field current_indent ibl.config.current_indent?
--- Configures what is excluded from indent-blankline
---@field exclude ibl.config.exclude?

Expand Down Expand Up @@ -109,6 +111,22 @@
--- </code>
---@field node_type table<string, string[]>?

---@class ibl.config.current_indent
--- Enables or disables current_indent
---@field enabled boolean?
--- Character that gets used to display the current_indent indentation guide
---
--- The character has to have a display width of 0 or 1
---@field char string?
--- Highlight group that get applied to the current_indent
---@field highlight string?
--- Shows an underline on the first line of the current_indent
---@field show_start boolean?
--- Shows an underline on the last line of the current_indent
---@field show_end boolean?
--- Virtual text priority for the current_indent
---@field priority number?

---@class ibl.config.exclude
--- List of `filetypes` for which indent-blankline is disabled
---@field filetypes string[]?
Expand All @@ -130,7 +148,9 @@
--- Configures the whitespace
---@field whitespace ibl.config.full.whitespace: ibl.config.whitespace
--- Configures the scope
---@field scope ibl.config.full.scope: ig.config.scope
---@field scope ibl.config.full.scope: ibl.config.scope
--- Configures the current_indent
---@field current_indent ibl.config.full.current_indent: ibl.config.current_indent
--- Configures what is excluded from indent-blankline
---@field exclude ibl.config.full.exclude: ibl.config.exclude

Expand Down Expand Up @@ -225,6 +245,22 @@
--- </code>
---@field node_type table<string, string[]>

---@class ibl.config.full.current_indent: ibl.config.current_indent
--- Enables or disables current_indent
---@field enabled boolean
--- Character that gets used to display the current_indent indentation guide
---
--- The character has to have a display width of 0 or 1
---@field char string?
--- Highlight group that get applied to the current_indent
---@field highlight string
--- Shows an underline on the first line of the current_indent
---@field show_start boolean
--- Shows an underline on the last line of the current_indent
---@field show_end boolean
--- Virtual text priority for the current_indent
---@field priority number

---@class ibl.config.full.exclude: ibl.config.exclude
--- List of `filetypes` for which indent-blankline is disabled
---@field filetypes string[]
Expand Down
21 changes: 21 additions & 0 deletions lua/ibl/highlights.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ local M = {
whitespace = {},
---@type ibl.highlight[]
scope = {},
---@type ibl.highlight[]
current_indent = {},
}

---@param name string
Expand All @@ -33,9 +35,11 @@ end
local setup_builtin_hl_groups = function()
local whitespace_hl = get "Whitespace"
local line_nr_hl = get "LineNr"
local cursor_line_nr_hl = get "CursorLineNr"
local ibl_indent_hl_name = "IblIndent"
local ibl_whitespace_hl_name = "IblWhitespace"
local ibl_scope_hl_name = "IblScope"
local ibl_current_indent_hl_name = "IblCurrentIndent"

if not_set(get(ibl_indent_hl_name)) then
vim.api.nvim_set_hl(0, ibl_indent_hl_name, whitespace_hl)
Expand All @@ -46,6 +50,9 @@ local setup_builtin_hl_groups = function()
if not_set(get(ibl_scope_hl_name)) then
vim.api.nvim_set_hl(0, ibl_scope_hl_name, line_nr_hl)
end
if not_set(get(ibl_current_indent_hl_name)) then
vim.api.nvim_set_hl(0, ibl_current_indent_hl_name, cursor_line_nr_hl)
end
end

M.setup = function()
Expand Down Expand Up @@ -107,6 +114,20 @@ M.setup = function()
vim.api.nvim_set_hl(0, M.scope[i].char, char_hl)
vim.api.nvim_set_hl(0, M.scope[i].underline, { sp = char_hl.fg, underline = true })
end

local current_indent_highlights = config.current_indent.highlight
M.current_indent = {}
local char_hl = get(current_indent_highlights)
if not_set(char_hl) then
error(string.format("No highlight group '%s' found", current_indent_highlights))
end
char_hl.nocombine = true
M.current_indent = {
char = "@ibl.current_indent.char",
underline = "@ibl.current_indent.underline",
}
vim.api.nvim_set_hl(0, M.current_indent.char, char_hl)
vim.api.nvim_set_hl(0, M.current_indent.underline, { sp = char_hl.fg, underline = true })
end

return M
1 change: 1 addition & 0 deletions lua/ibl/indent.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ M.get = function(whitespace, opts, indent_state)
if shiftwidth == 0 then
shiftwidth = tabstop
end

local whitespace_tbl = {}

for ch in whitespace:gmatch "." do
Expand Down