11local a = vim .api
22local cmd = vim .cmd
33local wo = vim .wo
4+ local handler = require (" copilot.handlers" )
5+ local format = require (" copilot_cmp.format" )
6+ local print_panel = {}
47
5- local print_buf = {}
8+ local set_text = function (full_text )
9+ vim .api .nvim_buf_set_lines (print_panel .bufnr , 0 , - 1 , false , {})
10+ vim .api .nvim_buf_set_option (print_panel .bufnr , " modifiable" , true )
11+ vim .api .nvim_buf_set_option (print_panel .bufnr , " readonly" , false )
612
7- print_buf .set_text = function (full_text )
813 local ft = vim .bo .filetype
9- vim .api .nvim_buf_call (print_buf .bufnr , function ()
14+ vim .api .nvim_buf_call (print_panel .bufnr , function ()
1015 vim .bo .filetype = ft
1116 end )
12- vim .api .nvim_buf_set_lines (print_buf .bufnr , 0 , - 1 , false , {})
13- vim .api .nvim_buf_set_var (print_buf .bufnr , " modifiable" , 1 )
14- vim .api .nvim_buf_set_var (print_buf .bufnr , " readonly" , 0 )
15- vim .api .nvim_buf_set_lines (print_buf .bufnr , 0 , # full_text , false ,full_text )
16-
17- vim .schedule (function ()
18- vim .api .nvim_buf_set_var (print_buf .bufnr , " modifiable" , 0 )
19- vim .api .nvim_buf_set_var (print_buf .bufnr , " readonly" , 1 )
17+ vim .api .nvim_buf_set_lines (print_panel .bufnr , 0 , # full_text , false ,full_text )
18+
19+ vim .api .nvim_buf_set_option (print_panel .bufnr , " modifiable" , false )
20+ vim .api .nvim_buf_set_option (print_panel .bufnr , " readonly" , true )
21+ end
22+
23+ local format_entry = function (number , str )
24+ local lines = {}
25+ for s in str :gmatch (" [^\r\n ]+" ) do table.insert (lines , s ) end
26+ table.insert (lines , ' ' )
27+ return {
28+ len = # lines ,
29+ lines = lines ,
30+ number = number ,
31+ }
32+ end
33+
34+ local sort_items = function (items )
35+ local sorted = {}
36+ for fmt_string , value in pairs (items ) do
37+ sorted [value .score ] = fmt_string
38+ end
39+ return sorted
40+ end
41+
42+ local make_entries = function (items )
43+ local entries = {}
44+ items = sort_items (items )
45+ for number , str in ipairs (vim .tbl_values (items )) do
46+ table.insert (entries , format_entry (number , str ))
47+ end
48+ for index , _ in ipairs (entries ) do
49+ local last = entries [index - 1 ]
50+ entries [index ].linenr = last and last .linenr + last .len or 1
51+ end
52+ return entries
53+ end
54+
55+ local get_full_text = function (entries )
56+ return vim .tbl_flatten (vim .tbl_map (function (e )
57+ return e .lines
58+ end , entries ))
59+ end
60+
61+ print_panel .add_panel_callbacks = function ()
62+ local items = {}
63+
64+ handler .add_handler_callback (" PanelSolution" , " pb" , function (result )
65+ local formatted = format .deindent (result .displayText )
66+ items [formatted ] = result
67+ end )
68+
69+ handler .add_handler_callback (" PanelSolutionsDone" , " pb" , function ()
70+ if vim .tbl_isempty (items ) then return end
71+ print_panel .entries = make_entries (items )
72+ print_panel .current = 1
73+ set_text (get_full_text (print_panel .entries ))
74+ items = {}
2075 end )
2176end
2277
2378local create_win = function ()
2479 local oldwin = a .nvim_get_current_win () -- record current window
25- cmd (" vsplit" )
80+ local height = tostring (math.floor (vim .api .nvim_win_get_height (oldwin )* .3 ))
81+ cmd (height .. " split" )
2682 local win = a .nvim_get_current_win ()
2783 wo .number = false
2884 wo .relativenumber = false
@@ -32,10 +88,113 @@ local create_win = function ()
3288 return win
3389end
3490
35- print_buf .create = function (bufnr )
36- print_buf .bufnr = bufnr
37- print_buf .win = create_win ()
38- a .nvim_win_set_buf (print_buf .win , print_buf .bufnr )
91+ print_panel .select = function (id )
92+ if not id then id = print_panel .current or 1 end
93+ local selection = print_panel .entries [id ]
94+ vim .api .nvim_win_set_cursor (print_panel .win , {selection .linenr , 0 })
95+ vim .cmd (" normal zt" )
96+ print_panel .current = id
97+ print_panel .linenr = selection .linenr
98+ end
99+
100+ print_panel .next = function ()
101+ local entries = print_panel .entries
102+ local current = print_panel .current
103+ local id = entries [current + 1 ] and current + 1 or 1
104+ print_panel .select (id )
39105end
40106
41- return print_buf
107+ print_panel .prev = function ()
108+ local entries = print_panel .entries
109+ local current = print_panel .current
110+ local id = entries [current - 1 ] and current - 1 or # entries
111+ print_panel .select (id )
112+ end
113+
114+ print_panel .set_options = function ()
115+ local opts = {
116+ win = { fcs = " eob: " , signcolumn = " no" , list = false },
117+ buf = { bufhidden = " wipe" , buftype = " nofile" , swapfile = false , buflisted = false , }
118+ }
119+ for option , value in pairs (opts .win ) do
120+ vim .api .nvim_win_set_option (print_panel .win , option , value )
121+ end
122+
123+ for option , value in pairs (opts .buf ) do
124+ vim .api .nvim_buf_set_option (print_panel .bufnr , option , value )
125+ end
126+ end
127+
128+ print_panel .create = function (bufnr )
129+ print_panel .bufnr = bufnr
130+ print_panel .win = create_win ()
131+ print_panel .last = 1
132+ a .nvim_win_set_buf (print_panel .win , print_panel .bufnr )
133+ print_panel .set_options ()
134+ print_panel .add_panel_callbacks ()
135+
136+ local keymaps = {
137+ [" j" ] = print_panel .next ,
138+ [" k" ] = print_panel .prev ,
139+ [" <CR>" ] = print_panel .select ,
140+ }
141+
142+ for key , fn in pairs (keymaps ) do
143+ vim .keymap .set (" n" , key , fn , {
144+ silent = true ,
145+ buffer = print_panel .bufnr ,
146+ })
147+ end
148+
149+ local id = vim .api .nvim_create_augroup (" Panel" , {
150+ clear = false
151+ })
152+
153+ vim .api .nvim_create_autocmd ({" TextChangedI" , " TextChangedP" }, {
154+ callback = function ()
155+ print (" callback" )
156+ require (" copilot.extensions.panel" ).send_request ()
157+ end ,
158+ group = id ,
159+ })
160+
161+ vim .api .nvim_create_autocmd (" WinEnter" , {
162+ callback = function ()
163+ if print_panel .entries then
164+ print_panel .select (print_panel .entries .current )
165+ end
166+ end ,
167+ buffer = print_panel .bufnr ,
168+ group = id ,
169+ })
170+
171+ vim .api .nvim_create_autocmd (" WinClosed" , {
172+ pattern = { tostring (print_panel .win ) },
173+ callback = function ()
174+ -- cleanup panel triggers
175+ vim .api .nvim_create_augroup (" Panel" , { clear = true })
176+ handler .remove_handler_callback (" PanelSolution" , " pb" )
177+ handler .remove_handler_callback (" PanelSolutionsDone" , " pb" )
178+ end ,
179+ once = true ,
180+ group = id ,
181+ })
182+ end
183+
184+ return print_panel
185+
186+ -- if you add back numbering:
187+ --
188+ -- local add_prefix_spacing = function (str, number)
189+ -- return string.rep(' ', number) .. str
190+ -- end
191+ --
192+ -- local entry_str = "[" .. number .. "]"
193+ -- for index, value in ipairs(lines) do
194+ -- if index == 1 then
195+ -- lines[index] = entry_str .. add_prefix_spacing(value, vim.o.shiftwidth)
196+ -- else
197+ -- lines[index] = add_prefix_spacing(value, vim.o.shiftwidth+entry_str:len())
198+ -- end
199+ -- end
200+
0 commit comments