Write To A Neovim Buffer Via A Timer In A Lua Script
October 2024
This was my first attempt at writing to a Neovim buffer with delays between the writes. It's not what I do now that I've found nvim_paste()
This is just a copy of a bunch of code that needs to be parsed out, but look for the timer stuff in here
-- local pause = function(min, max)
-- return math.random(min, max)
-- end
-- updates.write = function(data)
-- local timer = vim.loop.new_timer()
-- local d = {}
-- local i = 1
-- for str in string.gmatch(data, "(.)") do
-- table.insert(d, str)
-- end
-- timer:start(0, pause(20, 50), vim.schedule_wrap(function()
-- vim.cmd('normal A' .. d[i])
-- -- print(d[i])
-- i = i + 1
-- if i > #d then
-- timer:close()
-- end
-- end))
-- end
-- updates.run = function()
-- local main_timer = vim.loop.new_timer()
-- local main_indx = 1
-- main_timer:start(1000, pause(10, 10), vim.schedule_wrap(function()
-- local v = updates.content[main_indx]
-- main_indx = main_indx + 1
-- print(v.data)
-- if main_indx > #updates.content then
-- main_timer:close()
-- end
-- end))
-- -- for k, v in ipairs(updates.content) do
-- -- if v.kind == "write" then
-- -- updates.write(v.data)
-- -- end
-- -- end
-- end
-- local do_it = function()
-- print("asdf")
-- local t = vim.loop.new_timer()
-- t:start(0, 4000, vim.schedule_wrap(function()
-- print("qwer")
-- t:close()
-- end))
-- -- print("eeeee")
-- end
-- d.write = function(s)
-- print(s)
-- end
-- function mysplit(inputstr, sep)
-- if sep == nil then
-- sep = "%s"
-- end
-- local t = {}
-- for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
-- table.insert(t, str)
-- end
-- return t
-- end
-- return {
-- run = updates.run()
-- }
-- local fa = function()
-- print("a")
-- end
-- local fb = function()
-- print("b")
-- end
-- local do_it = function()
-- vim.defer_fn(fa, 1000)
-- vim.defer_fn(fb, 2000)
-- end
-- local do_sleep = function(t)
-- os.execute("sleep " .. tonumber(t))
-- end
-- function foo1 (a)
-- print("foo", a)
-- return coroutine.yield(2*a)
-- end
-- co = coroutine.create(function (a,b)
-- vim.api.nvim_command('echo ' .. a)
-- -- print("co-body", a, b)
-- do_sleep(a)
-- local r = foo1(a+1)
-- -- print("co-body", r)
-- local r, s = coroutine.yield(a+b, a-b)
-- -- print("co-body", r, s)
-- return b, "end"
-- end)
-- print("main", coroutine.resume(co, 4, 10))
-- print("main", coroutine.resume(co, 1, 10))
-- print("main", coroutine.resume(co, "r"))
-- print("main", coroutine.resume(co, "x", "y"))
-- print("main", coroutine.resume(co, "x", "y"))-- local ping1 = function()
-- vim.cmd('normal Aa')
-- end
-- local ping2 = function()
-- vim.cmd('normal Ab')
-- end
-- local run_it = function()
-- ping1()
-- do_sleep(3)
-- ping2()
-- end
-- local run_it = function()
-- vim.api.nvim_command('echo "Hello, Nvim!"')
-- do_sleep(3)
-- vim.api.nvim_command('echo "etc...!"')
-- end
-- run_it()
-- local a = require'plenary.async'
-- -- Create a timer handle (implementation detail: uv_timer_t).
-- local timer = vim.uv.new_timer()
-- local i = 0
-- -- Waits 1000ms, then repeats every 750ms until timer:close().
-- timer:start(1000, 750, function()
-- print('timer invoked! i='..tostring(i))
-- if i > 4 then
-- timer:close() -- Always close handles to avoid leaks.
-- end
-- i = i + 1
-- end)
-- print('sleeping');
-- local Job = require'plenary.job'
-- local do3 = function()
-- print("asdf")
-- Job:new({
-- command = 'sleep',
-- args = { '3' },
-- -- cwd = '/usr/bin',
-- -- env = { ['a'] = 'b' },
-- on_exit = function(j, return_val)
-- print(j:result())
-- -- print(return_val)
-- -- print(j:result())
-- end,
-- }):start() -- or start()
-- print("qwer")
-- end
-- do3()
-- local a = require "plenary.async"
-- function do_sleep(t)
-- os.execute("sleep " .. tonumber(t))
-- end
-- local ping = function()
-- print("asdf")
-- print("werwerw")
-- end
-- local ping2 = function()
-- print("qwer")
-- end
--local do_it = function()
-- print("asdf")
-- print("werwerw")
-- -- do_sleep(1)
-- -- print("qwer")
-- -- do_sleep(1)
-- -- print("zxcv")
---- a.run(ping)
---- do_sleep(1)
---- a.run(ping2)
---- do_sleep(1)
---- a.run(ping2)
----return vim.cmd.luaeval('math.pi')
---- call v:lua.ping2()
--end
--local do_it2 = function()
-- do_sleep(2)
-- print("qwer")
---- a.run(ping)
---- do_sleep(1)
---- a.run(ping2)
---- do_sleep(1)
---- a.run(ping2)
----return vim.cmd.luaeval('math.pi')
---- call v:lua.ping2()
--end
-- a.run(do_it)
-- a.run(do_it2)
-- b = vim.api.nvim_get_current_buf()
-- print(b)
-- function write_character(char)
-- vim.cmd('normal A' .. char)
-- -- local pos = vim.api.nvim_win_get_cursor(0)[2]
-- -- local line = vim.api.nvim_get_current_line()
-- -- local nline = line:sub(0, pos) .. char .. line:sub(pos + 1)
-- -- vim.api.nvim_set_current_line(nline)
-- end
-- function working_write_character()
-- local pos = vim.api.nvim_win_get_cursor(0)[2]
-- local line = vim.api.nvim_get_current_line()
-- local nline = line:sub(0, pos) .. '-- code' .. line:sub(pos + 1)
-- vim.api.nvim_set_current_line(nline)
-- end
-- function make_newline()
-- -- local pos = vim.api.nvim_win_get_cursor(0)
-- -- vim.api.nvim_buf_set_lines(0, pos[1], pos[1], false, {''}) -- For `o`
-- -- vim.api.nvim_buf_set_lines(0, pos[1]-1, pos[1]-1, false, {''}) -- For `O`
-- vim.cmd'normal o'
-- end
-- function do_sleep(t)
-- os.execute("sleep " .. tonumber(t))
-- end
-- write_character("a")
-- -- make_newline()
-- do_sleep(0.9)
-- write_character("b")
-- do_sleep(0.9)
-- -- make_newline()
-- write_character("c")
-- vim.api.execute("normal! i" .. "asdf")
-- function doIt()
-- write_character("a")
-- -- make_newline()
-- do_sleep(0.9)
-- write_character("b")
-- do_sleep(0.9)
-- -- make_newline()
-- write_character("c")
-- end
-- doIt()
-- local a = require "plenary.async"
-- local function write_char(char)
-- vim.cmd('normal A' .. char)
-- end
-- local function wchar(char)
-- local pos = vim.api.nvim_win_get_cursor(0)[2]
-- local line = vim.api.nvim_get_current_line()
-- local nline = line:sub(0, pos) .. char .. line:sub(pos + 1)
-- vim.api.nvim_set_current_line(nline)
-- end
-- local function do_sleep(t)
-- os.execute("sleep " .. tonumber(t))
-- end
-- local function do_stuff()
-- wchar('a')
-- do_sleep(1)
-- wchar('b')
-- end
-- local do_stuff = function()
-- a.uv.do_sleep(2)
-- vim.cmd('normal Ax')
-- endOther version that might be a dupe
function string:split(delimiter)
local result = {}
local from = 1
local delim_from, delim_to = string.find( self, delimiter, from )
while delim_from do
table.insert( result, string.sub( self, from , delim_from-1 ) )
from = delim_to + 1
delim_from, delim_to = string.find( self, delimiter, from )
end
table.insert( result, string.sub( self, from ) )
return result
end
local load_script = function()
local content = {}
local fn = "/Users/alan/workshop/nvim_auto_typer/auto-type-script.txt"
local f = assert(io.open(fn, "r"))
local script_data = f:read("*all")
local lines = script_data:split("\n")
f:close()
for _, line in ipairs(lines) do
if line ~= "" then
local line_parts = line:split("|")
if line_parts[1] ~= nil then
if line_parts[1] == "newline" then
table.insert(content, { action = "newline" })
elseif line_parts[1] == "pause" then
table.insert(content, { action = "pause", kind = line_parts[2] })
elseif line_parts[1] == "pop_window" then
table.insert(content, { action = "pop_window" })
elseif line_parts[1] == "tab" then
table.insert(content, { action = "tab" })
elseif line_parts[1] == "write" then
table.insert(content, { action = "write", data = line_parts[2] })
end
end
end
end
return content
end
local output_chars = function(data)
for str in string.gmatch(data, "(.)") do
vim.api.nvim_paste(str, false, -1)
vim.uv.sleep(20)
end
end
local go = function(content)
for _, v in ipairs(content) do
if v.action == "newline" then
vim.api.nvim_paste("\n", false, -1)
elseif v.action == "pause" then
vim.uv.sleep(1000)
elseif v.action == "tab" then
vim.api.nvim_paste("\t", false, -1)
elseif v.action == "write" then
output_chars(v.data)
end
end
end
run = function()
vim.cmd('NvimTreeClose')
vim.cmd('set paste')
local content = load_script()
go(content)
vim.cmd('set nopaste')
end
run()
-- return {
-- run = run
-- }Another Other version again that might be a dupe
local updates = {
content = {},
runner = {},
debug = 1
}
function string:split(delimiter)
local result = { }
local from = 1
local delim_from, delim_to = string.find( self, delimiter, from )
while delim_from do
table.insert( result, string.sub( self, from , delim_from-1 ) )
from = delim_to + 1
delim_from, delim_to = string.find( self, delimiter, from )
end
table.insert( result, string.sub( self, from ) )
return result
end
updates.load_script = function()
local fn = "/Users/alan/workshop/nvim_auto_typer/auto-type-script.txt"
local f = assert(io.open(fn, "r"))
local script_data = f:read("*all")
local lines = script_data:split("\n")
f:close()
for _, line in ipairs(lines) do
if line ~= "" then
local line_parts = line:split("|")
if line_parts[1] == "newline" then
table.insert(updates.content, { action = "newline" })
elseif line_parts[1] == "pause" then
table.insert(updates.content, { action = "pause", kind = "edit"})
elseif line_parts[1] == "tab" then
table.insert(updates.content, { action = "tab" })
elseif line_parts[1] == "write" then
table.insert(updates.content, { action = "write", data = line_parts[2] })
end
end
end
end
updates.deploy = function(d)
vim.cmd('set paste')
if d.kind == 'char' then
vim.cmd('normal A' .. d.data)
elseif d.kind == 'newline' then
vim.cmd('normal o')
end
vim.cmd('set nopaste')
end
updates.make_runner = function()
local runner_ping = 1
for k, v in ipairs(updates.content) do
if v.action == 'write' then
for str in string.gmatch(v.data, "(.)") do
local tics = 5
if updates.debug == 1 then
tics = 0
end
updates.runner[runner_ping] = { kind = "char", tics = tics, data = str }
runner_ping = runner_ping + 1
end
elseif v.action == 'newline' then
local tics = 80
if updates.debug == 1 then
tics = 0
end
updates.runner[runner_ping] = { kind = "newline", tics = tics }
runner_ping = runner_ping + 1
end
end
end
updates.go = function()
local timer = vim.loop.new_timer()
local runner_index = 1
local runner_tics = 0
timer:start(0, 5, vim.schedule_wrap(function()
if runner_tics == updates.runner[runner_index].tics then
updates.deploy(updates.runner[runner_index])
runner_index = runner_index + 1
if runner_index > #updates.runner then
timer:stop()
timer:close()
else
runner_tics = 0
end
else
runner_tics = runner_tics + 1
end
end))
end
updates.run = function()
-- local pop_buffer = vim.api.nvim_create_buf(false, true)
vim.cmd('NvimTreeClose')
vim.cmd('tabnew')
updates.load_script()
updates.make_runner()
updates.go()
end
updates.run()
-- return {
-- run = updates.run()
-- }end of line