summaryrefslogtreecommitdiff
path: root/lua/warp/row_selectors/grid.lua
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2024-03-12 23:04:21 +0000
committerJosh Rahm <rahm@google.com>2024-03-12 23:04:21 +0000
commitd7415ac09d7afecc430d64ea17b57ceab7432c2e (patch)
tree7ab43d8c002c7b31d119a9b5e5dfe67a2e164489 /lua/warp/row_selectors/grid.lua
parentff00585c7c9e0cac8d1c75a8cb60fd82519b6856 (diff)
downloadnvim-warp-d7415ac09d7afecc430d64ea17b57ceab7432c2e.tar.gz
nvim-warp-d7415ac09d7afecc430d64ea17b57ceab7432c2e.tar.bz2
nvim-warp-d7415ac09d7afecc430d64ea17b57ceab7432c2e.zip
Big refactor to warp.
Now two lines are displayed for row-choosing. Made row-choosing modular as well.
Diffstat (limited to 'lua/warp/row_selectors/grid.lua')
-rw-r--r--lua/warp/row_selectors/grid.lua111
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