local M = {} M.next_char = function() vim.cmd("redraw!") return vim.fn.nr2char(vim.fn.getchar()) end M.new_panel = function(buf, row, col, width, height) local w = vim.api.nvim_open_win(buf, false, { relative = 'win', row = row, col = col, width = width, height = height, focusable = true, style = 'minimal', fixed = true }) vim.api.nvim_win_set_option(w, "winhighlight", "Normal:WarpNormal") return w end M.open_horiz = function() local current_win = vim.api.nvim_get_current_win() local curpos = vim.api.nvim_win_get_cursor(0) local topline = vim.fn.line('w0') local width_of_garbage = vim.fn.getwininfo(current_win)[1].textoff local width = vim.api.nvim_win_get_width(current_win) - width_of_garbage local horiz_bufnr = vim.api.nvim_create_buf(0, 1) local line_at = vim.fn.getline(curpos[1]) local max_width = math.min( width, #line_at + 1 + (vim.o.virtualedit == 'onemore' and 1 or 0)) if vim.o.virtualedit == 'all' then max_width = width end return { buf = horiz_bufnr, panel = M.new_panel( horiz_bufnr, curpos[1] - topline + 1, width_of_garbage - 1, max_width + 2, 1) } end M.wrap_col_selector = function(strat) local cleanup = function(win) vim.api.nvim_buf_delete(vim.api.nvim_win_get_buf(win), {force = true}) end local w return { run = function() local data = M.open_horiz() w = data.panel local f = function () local disp = strat.display() if disp then vim.api.nvim_buf_set_lines(data.buf, 0, -1, 0, {' ' .. disp}) local ch = M.next_char() while ch ~= '\x1b' and strat.on_char(ch) do vim.api.nvim_buf_set_lines(data.buf, 0, -1, 0, {' ' .. strat.display()}) ch = M.next_char() end end end f () cleanup(w) end } end M.cleanup = function(win) if win then vim.api.nvim_buf_delete(vim.api.nvim_win_get_buf(win), {force = true}) end end return M