1
1
local M = {}
2
2
local config = require (" copilot-lsp.config" ).config
3
3
4
+ local buffer_histories = {}
5
+
4
6
--- @param bufnr integer
5
7
--- @param ns_id integer
6
8
local function _dismiss_suggestion (bufnr , ns_id )
11
13
--- @param bufnr integer
12
14
--- @param state copilotlsp.InlineEdit
13
15
local function _store_suggestion_history (bufnr , state )
14
- local history = vim .b [bufnr ].copilotlsp_nes_history or {}
15
- table.insert (history , 1 , vim .deepcopy (state ))
16
- if # history > 2 then
17
- table.remove (history , 3 )
16
+ if not buffer_histories [bufnr ] then
17
+ buffer_histories [bufnr ] = vim .ringbuf (2 )
18
18
end
19
- vim . b [bufnr ]. copilotlsp_nes_history = history
19
+ buffer_histories [bufnr ]: push ( vim . deepcopy ( state ))
20
20
end
21
21
22
22
--- @private
23
23
--- @param bufnr integer
24
24
local function _clear_suggestion_history (bufnr )
25
- vim .b [bufnr ].copilotlsp_nes_history = nil
25
+ buffer_histories [bufnr ] = nil
26
+ vim .b [bufnr ].copilotlsp_nes_restore_index = nil
26
27
end
27
28
28
29
--- @param bufnr ? integer
@@ -44,6 +45,19 @@ function M.clear_suggestion(bufnr, ns_id)
44
45
vim .b [bufnr ].copilotlsp_nes_last_col = nil
45
46
end
46
47
48
+ --- Check if there's history for a buffer
49
+ --- @param bufnr integer
50
+ --- @return boolean
51
+ function M .has_history (bufnr )
52
+ local history = buffer_histories [bufnr ]
53
+ if not history then
54
+ return false
55
+ end
56
+ -- Check if ringbuf has any items
57
+ local item = history :peek ()
58
+ return item ~= nil
59
+ end
60
+
47
61
--- @param bufnr ? integer
48
62
--- @param ns_id integer
49
63
--- @return boolean -- true if suggestion was restored , false otherwise
@@ -52,32 +66,27 @@ function M.restore_suggestion(bufnr, ns_id)
52
66
if not vim .api .nvim_buf_is_valid (bufnr ) then
53
67
return false
54
68
end
55
- local history = vim . b [bufnr ]. copilotlsp_nes_history
56
- if not history or # history == 0 then
69
+ local history = buffer_histories [bufnr ]
70
+ if not history then
57
71
return false
58
72
end
59
- local restore_index = vim .b [bufnr ].copilotlsp_nes_restore_index or 0
60
- restore_index = restore_index + 1
61
- -- If we've cycled through all history, wrap around
62
- if restore_index > # history then
63
- restore_index = 1
73
+ local suggestion = history :pop ()
74
+ if not suggestion then
75
+ return false
64
76
end
65
- local suggestion = history [restore_index ]
66
- vim .b [bufnr ].copilotlsp_nes_restore_index = restore_index
77
+ -- Validate suggestion is still applicable
67
78
local start_line = suggestion .range .start .line
68
79
if start_line >= vim .api .nvim_buf_line_count (bufnr ) then
69
80
_clear_suggestion_history (bufnr )
70
81
return false
71
82
end
72
- -- Clear current display and show restored suggestion
73
83
_dismiss_suggestion (bufnr , ns_id )
74
84
local preview = M ._calculate_preview (bufnr , suggestion )
75
85
M ._display_preview (bufnr , ns_id , preview )
76
-
77
86
vim .b [bufnr ].nes_state = suggestion
78
87
vim .b [bufnr ].copilotlsp_nes_namespace_id = ns_id
79
88
vim .b [bufnr ].copilotlsp_nes_cursor_moves = 1
80
-
89
+ history : push ( suggestion )
81
90
return true
82
91
end
83
92
@@ -329,4 +338,11 @@ function M._display_next_suggestion(bufnr, ns_id, edits)
329
338
})
330
339
end
331
340
341
+ -- Clean up history when buffer is deleted
342
+ vim .api .nvim_create_autocmd (" BufDelete" , {
343
+ callback = function (ev )
344
+ buffer_histories [ev .buf ] = nil
345
+ end ,
346
+ })
347
+
332
348
return M
0 commit comments