diff options
Diffstat (limited to 'lua/warp')
-rw-r--r-- | lua/warp/col_selectors/grid.lua | 10 | ||||
-rw-r--r-- | lua/warp/col_selectors/null.lua | 8 | ||||
-rw-r--r-- | lua/warp/col_selectors/words.lua | 9 | ||||
-rw-r--r-- | lua/warp/row_selectors/grid.lua | 111 | ||||
-rw-r--r-- | lua/warp/row_selectors/null.lua | 5 | ||||
-rw-r--r-- | lua/warp/util.lua | 77 | ||||
-rw-r--r-- | lua/warp/win_selectors/null.lua (renamed from lua/warp/win_selectors/current.lua) | 0 |
7 files changed, 209 insertions, 11 deletions
diff --git a/lua/warp/col_selectors/grid.lua b/lua/warp/col_selectors/grid.lua index bc37b56..5f575d8 100644 --- a/lua/warp/col_selectors/grid.lua +++ b/lua/warp/col_selectors/grid.lua @@ -1,5 +1,6 @@ local vim = assert(vim) +local util = require('warp.util') local M = {} local hsel1 = "tnshrdlcmwfpgkbvjxy" -- 19 @@ -41,7 +42,7 @@ local big_line, col_map = make_big_line() M.strategy = function() local filter - return { + return util.wrap_col_selector({ display = function() local curpos = vim.api.nvim_win_get_cursor(0) local line_at = vim.fn.getline(curpos[1]) @@ -85,7 +86,12 @@ M.strategy = function() return false end - } + }) end +M.run = function () + M.strategy().run() +end + + return M diff --git a/lua/warp/col_selectors/null.lua b/lua/warp/col_selectors/null.lua index eb00921..61a1f79 100644 --- a/lua/warp/col_selectors/null.lua +++ b/lua/warp/col_selectors/null.lua @@ -1,12 +1,6 @@ -local vim = assert(vim) - local M = {} -M.null_strategy = function() - return { - display = function() return nil end, - on_char = function() return false end - } +M.run = function () end return M diff --git a/lua/warp/col_selectors/words.lua b/lua/warp/col_selectors/words.lua index 8135a45..305477c 100644 --- a/lua/warp/col_selectors/words.lua +++ b/lua/warp/col_selectors/words.lua @@ -2,6 +2,7 @@ local vim = assert(vim) local M = {} local alphabet = "etansihrdlocumwfgypkbvjxqz" +local util = require('warp.util') local function split_lines(line) local i @@ -49,10 +50,14 @@ local function split_lines(line) return winstr, chars_to_col end +M.run = function () + M.words_strategy().run() +end + M.words_strategy = function() local chartab - return { + return util.wrap_col_selector({ display = function() local curpos = vim.api.nvim_win_get_cursor(0) local line_at = vim.fn.getline(curpos[1]) @@ -71,7 +76,7 @@ M.words_strategy = function() end return false end - } + }) end return M 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 diff --git a/lua/warp/row_selectors/null.lua b/lua/warp/row_selectors/null.lua new file mode 100644 index 0000000..8e8e9f5 --- /dev/null +++ b/lua/warp/row_selectors/null.lua @@ -0,0 +1,5 @@ +local M = {} + +M.read_row = function () return '.' end + +return M diff --git a/lua/warp/util.lua b/lua/warp/util.lua new file mode 100644 index 0000000..4f1858e --- /dev/null +++ b/lua/warp/util.lua @@ -0,0 +1,77 @@ +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' + }) + 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) + + 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 diff --git a/lua/warp/win_selectors/current.lua b/lua/warp/win_selectors/null.lua index 2d2a75f..2d2a75f 100644 --- a/lua/warp/win_selectors/current.lua +++ b/lua/warp/win_selectors/null.lua |