Skip to content

Commit

Permalink
refactor: wow we more minimal and fast
Browse files Browse the repository at this point in the history
  • Loading branch information
glepnir committed May 9, 2024
1 parent ebd8e9b commit fb08876
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 56 deletions.
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,4 @@ vim.cmd.highlight('IndentLine guifg=#123456')
vim.cmd.highlight('IndentLineCurrent guifg=#123456')
```

## Tips

set the `updatetime` to 100 will have a better experience when edit in insert
mode.

## License MIT
76 changes: 30 additions & 46 deletions lua/indentmini/init.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
local api = vim.api
local au, buf_set_extmark = api.nvim_create_autocmd, api.nvim_buf_set_extmark
local set_decoration_provider = api.nvim_set_decoration_provider
local buf_set_extmark, set_provider = api.nvim_buf_set_extmark, api.nvim_set_decoration_provider
local ns = api.nvim_create_namespace('IndentLine')
local g = api.nvim_create_augroup('IndentMini', { clear = true })
local indent_fn = vim.fn.indent
local UP, DOWN = -1, 1
local UP, DOWN, INVALID = -1, 1, -1
local opt = {
config = {
virt_text_pos = 'overlay',
Expand Down Expand Up @@ -53,15 +51,21 @@ local function find_row(bufnr, row, curindent, direction, render)
end
end

local function event_created(e, bufnr)
return not vim.tbl_isempty(api.nvim_get_autocmds({
group = g,
event = e,
buffer = bufnr,
}))
---@return integer top_row
---@return integer bot_row
---@return integer cur_inlevel
local function current_line_range(winid, bufnr, shiftw)
local row = api.nvim_win_get_cursor(winid)[1] - 1
local indent = indent_fn(row + 1)
if indent == 0 then
return INVALID, INVALID, INVALID
end
local top_row = find_row(bufnr, row, indent, UP, false) or INVALID
local bot_row = find_row(bufnr, row, indent, DOWN, false) or INVALID
return top_row, bot_row, math.floor(indent / shiftw)
end

local function on_line(_, _, bufnr, row)
local function on_line(_, winid, bufnr, row)
if
not api.nvim_get_option_value('expandtab', { buf = bufnr })
or vim.tbl_contains(opt.exclude, function(v)
Expand All @@ -77,57 +81,37 @@ local function on_line(_, _, bufnr, row)
end
local line_is_empty = #lines[1] == 0
local shiftw = vim.fn.shiftwidth()
local top_row, bot_row
if indent == 0 and line_is_empty then
local top_row = find_row(bufnr, row, indent, UP, true)
local bot_row = find_row(bufnr, row, indent, DOWN, true)
top_row = find_row(bufnr, row, indent, UP, true)
bot_row = find_row(bufnr, row, indent, DOWN, true)
local top_indent = top_row and indent_fn(top_row + 1) or 0
local bot_indent = bot_row and indent_fn(bot_row + 1) or 0
indent = math.max(top_indent, bot_indent)
end

local reg_srow, reg_erow, cur_inlevel = current_line_range(winid, bufnr, shiftw)
for i = 1, indent - 1, shiftw do
local col = i - 1
local level = math.floor(col / shiftw) + 1
local hi_name = ('IndentLine%d%d'):format(row + 1, level)
local higroup = 'IndentLine'
if row > reg_srow and row < reg_erow and level == cur_inlevel then
higroup = 'IndentLineCurrent'
end
local hi_name = (higroup .. '%d%d'):format(row + 1, level)
if col_in_screen(col) and non_or_space(row, col) then
opt.config.virt_text[1][2] = hi_name
if line_is_empty and col > 0 then
opt.config.virt_text_win_col = i - 1
end
buf_set_extmark(bufnr, ns, row, col, opt.config)
opt.config.virt_text_win_col = nil
api.nvim_set_hl(ns, hi_name, { link = 'IndentLine', default = true })
api.nvim_set_hl(ns, hi_name, {
link = higroup,
default = true,
force = true,
})
end
end

if opt.current and not event_created({ 'CursorMoved', 'CursorHoldI', 'InsertEnter' }, bufnr) then
au({ 'CursorMoved', 'CursorHoldI', 'InsertEnter' }, {
group = g,
buffer = bufnr,
callback = function(data)
local cur_hi = 'IndentLineCurrent'
local line, _ = unpack(api.nvim_win_get_cursor(0))
local curindent = indent_fn(line)
local srow = find_row(data.buf, line - 1, curindent, UP, false) or 0
local erow = find_row(data.buf, line - 1, curindent, DOWN, false) or 0
for k, v in pairs(api.nvim_get_hl(ns, {}) or {}) do
if v.link and v.link == cur_hi then
api.nvim_set_hl(ns, k, { link = 'IndentLine', force = true })
end
end
if erow < 1 then
return
end
-- only render visible part of screen
srow = math.max(vim.fn.line('w0') - 2, srow)
erow = math.min(vim.fn.line('w$'), erow)
local level = math.floor(curindent / shiftw)
for i = srow + 2, erow, 1 do
api.nvim_set_hl(ns, ('IndentLine%d%d'):format(i, level), { link = cur_hi, force = true })
end
end,
})
end
end

return {
Expand All @@ -140,6 +124,6 @@ return {
conf.exclude or {}
)
opt.config.virt_text = { { conf.char or '' } }
set_decoration_provider(ns, { on_win = on_win, on_line = on_line })
set_provider(ns, { on_win = on_win, on_line = on_line })
end,
}
10 changes: 5 additions & 5 deletions test/indentmini_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ end
local function count_current_hl()
local cur_hi = 'IndentLineCurrent'
local ns = get_indent_ns()
local t = {}
for k, v in pairs(nvim_get_hl(ns) or {}) do
if v.link and v.link == cur_hi then
t[#t + 1] = k:match('IndentLine(%d+)3')
local count = 0
for k, _ in pairs(nvim_get_hl(ns) or {}) do
if k:find('Current') then
count = count + 1
end
end
return #t
return count
end

local function screen(lines)
Expand Down

0 comments on commit fb08876

Please sign in to comment.