diff options
Diffstat (limited to 'lua/warp/row_selectors/grid.lua')
-rw-r--r-- | lua/warp/row_selectors/grid.lua | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/lua/warp/row_selectors/grid.lua b/lua/warp/row_selectors/grid.lua new file mode 100644 index 0000000..d32a2a1 --- /dev/null +++ b/lua/warp/row_selectors/grid.lua @@ -0,0 +1,111 @@ +local M = {} +local util = require("warp.util") + +local cons = "tnshrdlcumwfgypkbvjxqz" -- 21 +local vowel = "aeiou" -- 5 + +local function char_at(s, i) + local m = (i % #s) + 1 + return string.sub(s, m, m) +end + +local function open_vertical(opts) + local current_win = vim.api.nvim_get_current_win() + local height = vim.api.nvim_win_get_height(current_win) + local topline = vim.fn.line('w0') + local width_of_garbage = vim.fn.getwininfo(current_win)[1].textoff + local row_map = {} + local left_buf = vim.api.nvim_create_buf(0, 1) + local right_buf = vim.api.nvim_create_buf(0, 1) + local line = 0 + local real_width = math.max(3, width_of_garbage) + local left_lines = {} + local right_lines = {} + local undecorated_lines = {} + + local function pad_left(t) + return (' '):rep(real_width - 3) .. t .. ' ' + end + + local function pad_right(t) + return ' ' .. t .. ' ' + end + + while line < height do + local t = char_at(cons, line) .. char_at(vowel, line) + table.insert(undecorated_lines, t) + table.insert(left_lines, pad_left(t)) + table.insert(right_lines, pad_right(t)) + row_map[t] = topline + line + line = line + 1 + end + vim.api.nvim_buf_set_lines(left_buf, 0, -1, 0, left_lines) + vim.api.nvim_buf_set_lines(right_buf, 0, -1, 0, right_lines) + -- local curpos = vim.api.nvim_win_get_cursor(0) + util.new_panel(left_buf, 0, 0, real_width, height) + if opts.two_columns then + local pos = vim.o.textwidth + width_of_garbage + pos = math.min(pos, vim.api.nvim_win_get_width(0) - 4) + util.new_panel(right_buf, 0, pos, 4, height) + end + return { + row_map = row_map, + cleanup = function () + vim.api.nvim_buf_delete(left_buf, {force = true}) + vim.api.nvim_buf_delete(right_buf, {force = true}) + end, + filter_vert_text = function(ch) + local new_left_text = {} + local new_right_text = {} + + for _, t in pairs(undecorated_lines) do + local str = t:gsub("^" .. ch, function(m) return (' '):rep(#m) end) + + if t:match('^' .. ch) then + table.insert(new_left_text, pad_left(str)) + table.insert(new_right_text, pad_right(str)) + else + table.insert(new_left_text, "") + table.insert(new_right_text, "") + end + end + + vim.api.nvim_buf_set_lines(left_buf, 0, -1, 0, new_left_text) + vim.api.nvim_buf_set_lines(right_buf, 0, -1, 0, new_right_text) + end + } +end + +M.read_row = function(opts) + local data + + if not opts then + opts = {} + end + + local row = (function () + data = open_vertical(opts) + local vch1 = util.next_char() + if vch1 == '\x1b' then + return + elseif vch1 == '.' then + return '.' + else + data.filter_vert_text(vch1) + local vch2 = util.next_char() + if vch1 == '\x1b' then return end + return data.row_map[vch1 .. vch2] + end + end)() + + data.cleanup() + return row +end + +M.with_opts = function(opts) + return { + read_row = function() return M.read_row(opts) end + } +end + +return M |