summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/warp.lua189
1 files changed, 84 insertions, 105 deletions
diff --git a/lua/warp.lua b/lua/warp.lua
index 9eb1b67..d3b6337 100644
--- a/lua/warp.lua
+++ b/lua/warp.lua
@@ -12,6 +12,20 @@ local function char_at(s, i)
return string.sub(s, m, m)
end
+local function new_panel(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 = false,
+ style = 'minimal'
+ })
+ vim.api.nvim_win_set_option(w, "winhighlight", "Normal:WarpNormal")
+ return w
+end
+
M.open_vertical = function()
local current_win = vim.api.nvim_get_current_win()
local height = vim.api.nvim_win_get_height(current_win)
@@ -20,36 +34,18 @@ M.open_vertical = function()
M.row_map = {}
- M.vert_buf = vim.api.nvim_create_buf(0, 1)
+ M.vert_buf = vim.api.nvim_create_buf(0, 1)
local line = 0
M.vert_lines = {}
local real_width = math.max(3, width_of_garbage)
while line < height do
local t = char_at(cons, line) .. char_at(vowel, line)
- table.insert(M.vert_lines, (' '):rep(real_width-3) .. t .. ' ')
+ table.insert(M.vert_lines, (' '):rep(real_width - 3) .. t .. ' ')
M.row_map[t] = topline + line
line = line + 1
end
vim.api.nvim_buf_set_lines(M.vert_buf, 0, -1, 0, M.vert_lines)
-
- local vert_win = vim.api.nvim_open_win(
- M.vert_buf,
- false,
- {
- relative = 'win',
- row = 0,
- col = 0,
- width = real_width,
- height = height
- })
-
- vim.api.nvim_win_set_option(vert_win, "winhighlight", "Normal:WarpNormal")
- vim.api.nvim_win_set_option(vert_win, "number", false) -- Hide line numbers
- vim.api.nvim_win_set_option(vert_win, "relativenumber", false) -- Hide relative numbers
- vim.api.nvim_win_set_option(vert_win, "wrap", false) -- Disable wrapping
- vim.api.nvim_win_set_option(vert_win, "signcolumn", "no") -- Hide sign column
-
- return vert_win
+ return new_panel(M.vert_buf, 0, 0, real_width, height);
end
M.open_horiz = function()
@@ -58,12 +54,10 @@ M.open_horiz = function()
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 width = vim.api.nvim_win_get_width(current_win) - width_of_garbage
- M.horiz_bufnr = vim.api.nvim_create_buf(0, 1)
+ M.horiz_bufnr = vim.api.nvim_create_buf(0, 1)
local col = 0
- -- local bottom_line = ""
- -- local top_line = ""
local line = ''
local v = ''
@@ -75,15 +69,11 @@ M.open_horiz = function()
while col < max_width do
v = char_at(hsel1, i)
if c then
- if M.col_map [v .. c] then
- break
- end
+ if M.col_map[v .. c] then break end
M.col_map[c .. v] = col - 1
end
c = char_at(hsel2, i)
- if M.col_map [c .. v] then
- break
- end
+ if M.col_map[c .. v] then break end
line = line .. v
col = col + 1
if col < max_width then
@@ -94,27 +84,11 @@ M.open_horiz = function()
end
end
- vim.api.nvim_buf_set_lines(M.horiz_bufnr, 0, -1, 0, { ' ' .. line })
+ vim.api.nvim_buf_set_lines(M.horiz_bufnr, 0, -1, 0, {' ' .. line})
M.horiz_line = line
- local horiz_win = vim.api.nvim_open_win(
- M.horiz_bufnr,
- false,
- {
- relative = 'win',
- row = curpos[1] - topline + 1,
- col = width_of_garbage - 1, -- -curpos[2],
- width = max_width + 2,
- height = 1
- })
- vim.api.nvim_win_set_option(horiz_win, "winhighlight", "Normal:WarpNormal")
-
- vim.api.nvim_win_set_option(horiz_win, "number", false) -- Hide line numbers
- vim.api.nvim_win_set_option(horiz_win, "relativenumber", false) -- Hide relative numbers
- vim.api.nvim_win_set_option(horiz_win, "wrap", false) -- Disable wrapping
- vim.api.nvim_win_set_option(horiz_win, "signcolumn", "no") -- Hide sign column
-
- return horiz_win
+ return new_panel(M.horiz_bufnr, curpos[1] - topline + 1, width_of_garbage - 1,
+ max_width + 2, 1)
end
M.filter_horiz_string = function(ch)
@@ -130,15 +104,13 @@ M.filter_horiz_string = function(ch)
end
i = i + 1
end
- vim.api.nvim_buf_set_lines(M.horiz_bufnr, 0, -1, 0, { ' ' .. new_horiz_line })
+ vim.api.nvim_buf_set_lines(M.horiz_bufnr, 0, -1, 0, {' ' .. new_horiz_line})
end
-M.filter_vert_text = function (ch)
+M.filter_vert_text = function(ch)
local new_vert_text = {}
for _, t in pairs(M.vert_lines) do
- local str = t:gsub("^%s*" .. ch, function (m)
- return (' '):rep(#m)
- end)
+ local str = t:gsub("^%s*" .. ch, function(m) return (' '):rep(#m) end)
if t:match('^%s*' .. ch) then
table.insert(new_vert_text, str)
@@ -156,68 +128,75 @@ local function next_char()
end
M.run = function()
- local cleanup = function (w)
- vim.api.nvim_buf_delete(vim.api.nvim_win_get_buf(w), { force = true })
- end
-
- local w1 = M.open_vertical()
local current_pos = vim.api.nvim_win_get_cursor(0)
+ local old_scroll = vim.o.scrolloff
+ vim.o.scrolloff = 0
- local r
- local vch1 = next_char()
- if vch1 == '\x1b' then
- cleanup(w1)
- return
- elseif vch1 == '.' then
- r = current_pos[1]
- cleanup(w1)
- else
- M.filter_vert_text(vch1)
- local vch2 = next_char()
- cleanup(w1)
- if vch1 == '\x1b' then
- return
- end
- r = M.row_map[vch1 .. vch2]
- end
+ (function()
+ local w
- if r then
- vim.api.nvim_win_set_cursor(0, {r, current_pos[2]})
- local w2 = M.open_horiz()
-
- local c
- local hch1 = next_char()
- if hch1 == '\x1b' then
- cleanup(w2)
- return
- elseif hch1 == '.' then
- c = current_pos[2]
- elseif not hch1:match('[a-z]') then
- c = hch1
- else
- M.filter_horiz_string(hch1)
+ local cleanup = function(win)
+ vim.api.nvim_buf_delete(vim.api.nvim_win_get_buf(win), {force = true})
+ end
- local hch2 = next_char()
- if hch2 == '\x1b' then
- cleanup(w2)
+ local read_row = function()
+ w = M.open_vertical()
+ local vch1 = next_char()
+ if vch1 == '\x1b' then
return
+ elseif vch1 == '.' then
+ return current_pos[1]
+ else
+ M.filter_vert_text(vch1)
+ local vch2 = next_char()
+ if vch1 == '\x1b' then return end
+ return M.row_map[vch1 .. vch2]
end
- c = M.col_map[hch1 .. hch2]
end
- cleanup(w2)
+ local r = read_row()
+ if w then
+ cleanup(w)
+ w = nil
+ end
- if c then
- vim.api.nvim_win_set_cursor(0, {r, 0})
- if c == '$' then
- vim.cmd("normal! $")
- elseif type(c) == 'string' then
- vim.cmd("normal! f" .. c)
+ if not r then return end
+
+ vim.api.nvim_win_set_cursor(0, {r, current_pos[2]})
+
+ local read_col = function()
+ w = M.open_horiz()
+ local hch1 = next_char()
+
+ if hch1 == '\x1b' then
+ return nil
+ elseif hch1 == '.' then
+ return current_pos[2]
+ elseif not hch1:match('[a-z]') then
+ return hch1
else
- vim.cmd("normal! " .. (c + 1) .. "|") -- handle multibyte characters
+ M.filter_horiz_string(hch1)
+
+ local hch2 = next_char()
+ if hch2 == '\x1b' then return end
+ return M.col_map[hch1 .. hch2]
end
end
- end
+
+ local c = read_col()
+ if w then cleanup(w) end
+ if not c then return end
+
+ if c == '$' or c == '^' then
+ vim.cmd("normal! " .. c)
+ elseif type(c) == 'string' then
+ vim.cmd("normal! f" .. c)
+ else
+ vim.cmd("normal! " .. (c + 1) .. "|") -- handle multibyte characters
+ end
+ end)()
+
+ vim.o.scrolloff = old_scroll
end
return M