|
1 | 1 | local M = {}
|
2 | 2 |
|
3 |
| ----@param opts table Animation options |
4 |
| ----@return nil |
5 |
| -local function handle_text_change_animation(opts) |
6 |
| - local detach_listener = false |
7 |
| - local ranges = {} |
8 |
| - local iter = 0 |
9 |
| - |
10 |
| - ---Callback function for buffer changes |
11 |
| - ---@param event any Event type |
12 |
| - ---@param bufnr number Buffer number |
13 |
| - ---@param changedtick number Changed tick |
14 |
| - ---@param start_row number Starting row of change |
15 |
| - ---@param start_col number Starting column of change |
16 |
| - ---@param byte_offset number Byte offset |
17 |
| - ---@param old_end_row number Old end row |
18 |
| - ---@param old_end_col number Old end column |
19 |
| - ---@param old_byte_end number Old end byte |
20 |
| - ---@param new_end_row number New end row |
21 |
| - ---@param new_end_col number New end column |
22 |
| - ---@param new_byte_end number New end byte |
23 |
| - function M.on_bytes( |
24 |
| - event, |
25 |
| - bufnr, |
26 |
| - changedtick, |
27 |
| - start_row, |
28 |
| - start_col, |
29 |
| - byte_offset, |
30 |
| - old_end_row, |
31 |
| - old_end_col, |
32 |
| - old_byte_end, |
33 |
| - new_end_row, |
34 |
| - new_end_col, |
35 |
| - new_byte_end |
36 |
| - ) |
37 |
| - if detach_listener then |
38 |
| - return true |
39 |
| - end |
40 |
| - |
41 |
| - -- Calculate the affected text range |
42 |
| - local buffer_line_count = vim.api.nvim_buf_line_count(0) |
43 |
| - local end_row = start_row + new_end_row |
44 |
| - local end_col = start_col + new_end_col |
45 |
| - |
46 |
| - -- Adjust end column for changes at buffer end |
47 |
| - if end_row >= buffer_line_count then |
48 |
| - local last_line = vim.api.nvim_buf_get_lines(0, -2, -1, false)[1] |
49 |
| - end_col = #last_line |
50 |
| - end |
51 |
| - |
52 |
| - local range = { |
53 |
| - start_line = start_row, |
54 |
| - start_col = start_col, |
55 |
| - end_line = end_row, |
56 |
| - end_col = end_col, |
57 |
| - } |
58 |
| - |
59 |
| - table.insert(ranges, range) |
60 |
| - |
61 |
| - iter = iter + 1 |
62 |
| - end |
63 |
| - |
64 |
| - -- Attach buffer listener |
65 |
| - vim.api.nvim_buf_attach(0, false, { |
66 |
| - on_bytes = M.on_bytes, |
67 |
| - }) |
68 |
| - |
69 |
| - vim.schedule(function() |
70 |
| - detach_listener = true |
71 |
| - |
72 |
| - local final_ranges = {} |
73 |
| - |
74 |
| - -- Sort ranges by start line and then by start column |
75 |
| - table.sort(ranges, function(a, b) |
76 |
| - if a.start_line == b.start_line then |
77 |
| - return a.start_col < b.start_col |
78 |
| - end |
79 |
| - return a.start_line < b.start_line |
80 |
| - end) |
81 |
| - |
82 |
| - if #ranges > 0 then |
83 |
| - local current = ranges[1] |
84 |
| - |
85 |
| - for i = 2, #ranges do |
86 |
| - local next_range = ranges[i] |
87 |
| - |
88 |
| - -- Check if ranges overlap or are adjacent |
89 |
| - if |
90 |
| - current.end_line < next_range.start_line |
91 |
| - or (current.end_line == next_range.start_line and current.end_col < next_range.start_col) |
92 |
| - then |
93 |
| - -- No overlap, add current range and start new one |
94 |
| - if current.start_line ~= current.end_line or current.start_col ~= current.end_col then |
95 |
| - table.insert(final_ranges, current) |
96 |
| - end |
97 |
| - current = next_range |
98 |
| - else |
99 |
| - -- Merge overlapping ranges |
100 |
| - current.end_line = math.max(current.end_line, next_range.end_line) |
101 |
| - if current.end_line == next_range.end_line then |
102 |
| - current.end_col = math.max(current.end_col, next_range.end_col) |
103 |
| - end |
104 |
| - end |
105 |
| - end |
106 |
| - |
107 |
| - if current.start_line ~= current.end_line or current.start_col ~= current.end_col then |
108 |
| - table.insert(final_ranges, current) |
| 3 | +local handle_text_change_animation = require("tiny-glimmer.animation.text_change").handle_text_change_animation |
| 4 | + |
| 5 | +local function create_callback(opts) |
| 6 | + return function(ranges) |
| 7 | + for i = 1, #ranges do |
| 8 | + local range = ranges[i] |
| 9 | + |
| 10 | + if ranges[i] ~= nil then |
| 11 | + require("tiny-glimmer.animation.factory") |
| 12 | + .get_instance() |
| 13 | + :create_named_text_animation("undo_" .. i, opts.default_animation, { |
| 14 | + base = { range = range }, |
| 15 | + }) |
109 | 16 | end
|
110 | 17 | end
|
111 |
| - |
112 |
| - vim.schedule(function() |
113 |
| - for i = 1, #final_ranges do |
114 |
| - local range = final_ranges[i] |
115 |
| - |
116 |
| - if final_ranges[i] ~= nil then |
117 |
| - require("tiny-glimmer.animation.factory") |
118 |
| - .get_instance() |
119 |
| - :create_named_text_animation("undo_" .. i, opts.default_animation, { |
120 |
| - base = { range = range }, |
121 |
| - }) |
122 |
| - end |
123 |
| - end |
124 |
| - end) |
125 |
| - end) |
| 18 | + end |
126 | 19 | end
|
127 | 20 |
|
128 | 21 | ---Animate undo operation
|
129 | 22 | ---@param opts table Animation options
|
130 | 23 | function M.undo(opts)
|
131 |
| - handle_text_change_animation(opts) |
| 24 | + handle_text_change_animation(create_callback(opts)) |
132 | 25 | end
|
133 | 26 |
|
134 | 27 | ---Animate redo operation
|
135 | 28 | ---@param opts table Animation options
|
136 | 29 | function M.redo(opts)
|
137 |
| - handle_text_change_animation(opts) |
| 30 | + handle_text_change_animation(create_callback(opts)) |
138 | 31 | end
|
139 | 32 |
|
140 | 33 | return M
|
0 commit comments