home ~ projects ~ socials

Write To A Neovim Buffer Via A Timer In A Lua Script

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')
-- end

Other 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 --