summaryrefslogtreecommitdiff
path: root/lua/warp/util.lua
blob: c51c5aa30d0f07ccdbfeeecfcc073a754d15e09a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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