|
| 1 | +local M = {} |
| 2 | + |
| 3 | +local current_selection = {} |
| 4 | +local current_idx = 0 |
| 5 | +local current_style = "normal"; |
| 6 | +local typist_namespace = vim.api.nvim_create_namespace("theprimeagen_typist") |
| 7 | +local current_extmark = nil |
| 8 | + |
| 9 | +function M.pluck() |
| 10 | + local start_pos = vim.fn.getpos("'<") |
| 11 | + local end_pos = vim.fn.getpos("'>") |
| 12 | + |
| 13 | + current_selection = vim.api.nvim_buf_get_lines(0, start_pos[2] - 1, end_pos[2], false) |
| 14 | + current_idx = 0 |
| 15 | +end |
| 16 | + |
| 17 | +function M.set_lines(lines) |
| 18 | + current_selection = lines |
| 19 | + current_idx = 0 |
| 20 | +end |
| 21 | + |
| 22 | +local running = false |
| 23 | +function M.next(speed, cb) |
| 24 | + speed = speed or 16 |
| 25 | + cb = cb or function() end |
| 26 | + current_idx = current_idx + 1 |
| 27 | + |
| 28 | + if current_idx > #current_selection or running then |
| 29 | + return false |
| 30 | + end |
| 31 | + running = true |
| 32 | + |
| 33 | + local starting_pos = vim.fn.getpos(".")[2] |
| 34 | + |
| 35 | + local current = current_selection[current_idx] |
| 36 | + local idx = 1 |
| 37 | + local current_line = "" |
| 38 | + local function print_line_normal() |
| 39 | + if idx > #current then |
| 40 | + running = false |
| 41 | + if current_style == "normal" then |
| 42 | + vim.api.nvim_win_set_cursor(0, {starting_pos + 1, 0}) |
| 43 | + end |
| 44 | + cb() |
| 45 | + return |
| 46 | + end |
| 47 | + |
| 48 | + current_line = current_line .. current:sub(idx, idx) |
| 49 | + |
| 50 | + if current_style == "normal" then |
| 51 | + vim.api.nvim_buf_set_lines(0, starting_pos - 1, starting_pos, false, {current_line}) |
| 52 | + vim.api.nvim_win_set_cursor(0, {starting_pos, #current_line}) |
| 53 | + else |
| 54 | + --local current_line = vim.api.nvim_buf_get_lines(0, starting_pos - 1, starting_pos, false)[1] |
| 55 | + vim.api.nvim_buf_del_extmark(0, typist_namespace, current_extmark or 0) |
| 56 | + current_extmark = vim.api.nvim_buf_set_extmark(0, typist_namespace, starting_pos - 1, 0, { |
| 57 | + virt_text = { |
| 58 | + {"", "Comment"}, |
| 59 | + {"", "Comment"}, |
| 60 | + {current_line, "Comment"}, |
| 61 | + }, |
| 62 | + virt_text_pos = "eol", |
| 63 | + hl_mode = "combine", |
| 64 | + }) |
| 65 | + end |
| 66 | + |
| 67 | + idx = idx + 1 |
| 68 | + vim.defer_fn(print_line_normal, speed) |
| 69 | + end |
| 70 | + |
| 71 | + print_line_normal() |
| 72 | + return true |
| 73 | +end |
| 74 | + |
| 75 | +function M.run(speed) |
| 76 | + if M.next(speed) then |
| 77 | + vim.schedule(function() |
| 78 | + M.run(speed) |
| 79 | + end) |
| 80 | + end |
| 81 | +end |
| 82 | + |
| 83 | +function M.ghost_line() |
| 84 | + current_style = "ghost" |
| 85 | +end |
| 86 | + |
| 87 | +function M.normal() |
| 88 | + current_style = "normal" |
| 89 | +end |
| 90 | + |
| 91 | +function M.clear() |
| 92 | + vim.api.nvim_buf_del_extmark(0, typist_namespace, current_extmark or 0) |
| 93 | + current_extmark = nil |
| 94 | +end |
| 95 | + |
| 96 | + |
| 97 | +return M |
0 commit comments