Skip to content

Commit 2427aba

Browse files
committed
refactor(animation): improve text change animation logic
1 parent c921b8a commit 2427aba

File tree

1 file changed

+50
-61
lines changed

1 file changed

+50
-61
lines changed

lua/tiny-glimmer/animation/text_change.lua

Lines changed: 50 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,107 @@
11
local M = {}
22

3+
---@param callback function|nil Function to call with the merged ranges
34
---@return nil
45
function M.handle_text_change_animation(callback)
5-
local detach_listener = false
66
local ranges = {}
7-
local iter = 0
8-
9-
---Callback function for buffer changes
10-
---@param event any Event type
11-
---@param bufnr number Buffer number
12-
---@param changedtick number Changed tick
13-
---@param start_row number Starting row of change
14-
---@param start_col number Starting column of change
15-
---@param byte_offset number Byte offset
16-
---@param old_end_row number Old end row
17-
---@param old_end_col number Old end column
18-
---@param old_byte_end number Old end byte
19-
---@param new_end_row number New end row
20-
---@param new_end_col number New end column
21-
---@param new_byte_end number New end byte
22-
function M.on_bytes(
23-
event,
24-
bufnr,
25-
changedtick,
7+
local final_ranges = {}
8+
9+
local insert = table.insert
10+
local max = math.max
11+
12+
-- Flag to detach buffer listener
13+
local detach_listener = false
14+
15+
local function on_bytes(
16+
_, -- event
17+
_, -- bufnr
18+
_, -- changedtick
2619
start_row,
2720
start_col,
28-
byte_offset,
29-
old_end_row,
30-
old_end_col,
31-
old_byte_end,
21+
_, -- byte_offset
22+
_, -- old_end_row
23+
_, -- old_end_col
24+
_, -- old_byte_end
3225
new_end_row,
3326
new_end_col,
34-
new_byte_end
27+
_ -- new_byte_end
3528
)
3629
if detach_listener then
3730
return true
3831
end
3932

4033
-- Calculate the affected text range
41-
local buffer_line_count = vim.api.nvim_buf_line_count(0)
4234
local end_row = start_row + new_end_row
4335
local end_col = start_col + new_end_col
4436

45-
-- Adjust end column for changes at buffer end
46-
if end_row >= buffer_line_count then
37+
if end_row >= vim.api.nvim_buf_line_count(0) then
4738
local last_line = vim.api.nvim_buf_get_lines(0, -2, -1, false)[1]
48-
end_col = #last_line
39+
if last_line then
40+
end_col = #last_line
41+
end
4942
end
5043

51-
local range = {
44+
insert(ranges, {
5245
start_line = start_row,
5346
start_col = start_col,
5447
end_line = end_row,
5548
end_col = end_col,
56-
}
57-
58-
table.insert(ranges, range)
59-
60-
iter = iter + 1
49+
})
6150
end
6251

63-
-- Attach buffer listener
6452
vim.api.nvim_buf_attach(0, false, {
65-
on_bytes = M.on_bytes,
53+
on_bytes = on_bytes,
6654
})
6755

6856
vim.schedule(function()
6957
detach_listener = true
7058

71-
local final_ranges = {}
72-
73-
-- Sort ranges by start line and then by start column
74-
table.sort(ranges, function(a, b)
75-
if a.start_line == b.start_line then
76-
return a.start_col < b.start_col
77-
end
78-
return a.start_line < b.start_line
79-
end)
59+
local range_count = #ranges
60+
if range_count > 0 then
61+
table.sort(ranges, function(a, b)
62+
if a.start_line == b.start_line then
63+
return a.start_col < b.start_col
64+
end
65+
return a.start_line < b.start_line
66+
end)
8067

81-
if #ranges > 0 then
8268
local current = ranges[1]
8369

84-
for i = 2, #ranges do
70+
local is_empty_range = function(r)
71+
return r.start_line == r.end_line and r.start_col == r.end_col
72+
end
73+
74+
for i = 2, range_count do
8575
local next_range = ranges[i]
8676

8777
-- Check if ranges overlap or are adjacent
8878
if
8979
current.end_line < next_range.start_line
9080
or (current.end_line == next_range.start_line and current.end_col < next_range.start_col)
9181
then
92-
-- No overlap, add current range and start new one
93-
if current.start_line ~= current.end_line or current.start_col ~= current.end_col then
94-
table.insert(final_ranges, current)
82+
-- No overlap, add current range if not empty
83+
if not is_empty_range(current) then
84+
insert(final_ranges, current)
9585
end
9686
current = next_range
9787
else
98-
-- Merge overlapping ranges
99-
current.end_line = math.max(current.end_line, next_range.end_line)
88+
-- Merge overlapping ranges (optimize the conditional)
89+
current.end_line = max(current.end_line, next_range.end_line)
10090
if current.end_line == next_range.end_line then
101-
current.end_col = math.max(current.end_col, next_range.end_col)
91+
current.end_col = max(current.end_col, next_range.end_col)
10292
end
10393
end
10494
end
10595

106-
if current.start_line ~= current.end_line or current.start_col ~= current.end_col then
107-
table.insert(final_ranges, current)
96+
-- Add the last range if not empty
97+
if not is_empty_range(current) then
98+
insert(final_ranges, current)
10899
end
109100
end
110101

111-
vim.schedule(function()
112-
if callback then
113-
callback(final_ranges)
114-
end
115-
end)
102+
if callback then
103+
callback(final_ranges)
104+
end
116105
end)
117106
end
118107

0 commit comments

Comments
 (0)