|
| 1 | +local a = vim.api |
| 2 | +local cmd = vim.cmd |
| 3 | +local wo = vim.wo |
| 4 | +local handler = require("copilot.handlers") |
| 5 | +local format = require("copilot_cmp.format") |
| 6 | +local print_panel = {} |
| 7 | + |
| 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) |
| 12 | + |
| 13 | + local ft = vim.bo.filetype |
| 14 | + vim.api.nvim_buf_call(print_panel.bufnr, function () |
| 15 | + vim.bo.filetype = ft |
| 16 | + end) |
| 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 = {} |
| 75 | + end) |
| 76 | +end |
| 77 | + |
| 78 | +local create_win = function () |
| 79 | + local oldwin = a.nvim_get_current_win() --record current window |
| 80 | + local height = tostring(math.floor(vim.api.nvim_win_get_height(oldwin)*.3)) |
| 81 | + cmd(height .. "split") |
| 82 | + local win = a.nvim_get_current_win() |
| 83 | + wo.number = false |
| 84 | + wo.relativenumber = false |
| 85 | + wo.numberwidth = 1 |
| 86 | + wo.signcolumn = "no" |
| 87 | + a.nvim_set_current_win(oldwin) |
| 88 | + return win |
| 89 | +end |
| 90 | + |
| 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) |
| 105 | +end |
| 106 | + |
| 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