Went back to single script for luadebug

This commit is contained in:
U-ENGINEERO\joppe.blondel
2025-10-27 14:39:55 +01:00
parent 349cbc8175
commit fa0c8d5a2c
5 changed files with 141 additions and 206 deletions

View File

@ -2,16 +2,6 @@ local core = require "core"
local process = require "process"
local debugger = require "plugins.jpdebug.debugger"
-- Enable hot reloading of mdb
package.loaded["plugins.jpdebug.runners.luadebug.mdb"] = nil
local mdb = require "plugins.jpdebug.runners.luadebug.mdb"
---@class luadebug: runner
local luadebug = debugger.runner:new({
name = "luadebug",
proc = nil ---@type process|nil
})
-- tiny helpers
local function dirname(p) return p:match("^(.*)[/\\]") or "" end
local function join(a, b) return (a:sub(-1) == "/" and a or (a .. "/")) .. b end
@ -25,44 +15,13 @@ local function get_plugin_root()
return dirname(here) -- …/jpdebug
end
-- Main lua process spawner
local function spawn_lua_process(entry, lua, cwd, env)
local host = "localhost"
local port = 8172
-- ------------------- Runner API --------------------------------
-- Resolve vendor/?.lua so "require('mobdebug')" finds the bundled file
local vendor_glob = join(get_plugin_root(), "vendor/?.lua")
-- Build the inline lua launcher
local dbg_call = string.format([[
local ok, m = pcall(require, "mobdebug"); if ok then
print("Connecting to "..%q..":"..tostring(%d))
local connected = m.start(%q, %d)
end
]], host, port, host, port)
local launcher = string.format([[
package.path = %q .. ";" .. package.path
%s
dofile(%q)
]], vendor_glob, dbg_call, entry)
-- Spawn the process
local cmd = {}
if type(lua) == "table" then
for i=1, #lua do table.insert(cmd, lua[i]) end
else
table.insert(cmd, lua)
end
table.insert(cmd, "-e")
table.insert(cmd, launcher)
local proc = process.start(cmd, {
cwd = cwd,
env = env,
stdout = process.REDIRECT_PIPE,
stderr = process.REDIRECT_PIPE,
})
return proc
end
---@class luadebug: runner
local luadebug = debugger.runner:new({
name = "luadebug",
proc = nil ---@type process|nil
})
function luadebug:run(target, name)
if target.entry == nil then
@ -74,42 +33,31 @@ function luadebug:run(target, name)
local cwd = target.cwd or "."
local env = target.env or {}
-- spwawn the mobdebug process
self.mdb = mdb:new({
log = self.log,
error = self.error,
on_connected = function()
self.on_state('running')
self.mdb:setb('test.lua', 6)
self.mdb:run()
end,
on_pause = function(file, line)
self.on_state('paused')
self.on_break(file, line, "breakpoint")
end,
})
self.mdb:spawn(lua, get_plugin_root())
-- spawn the debugger
self:spawn_mdb(lua)
-- TODO error checking
-- spawn the main lua process
local proc = spawn_lua_process(entry, lua, cwd, env)
local proc = self:spawn_lua_process(entry, lua, cwd, env)
if proc == nil then
self.error("Failed to start "..entry)
-- TODO kill mdb
return
end
self.proc = proc
self.on_state('connecting')
-- output pump
-- output pump
core.add_thread(function()
while true do
core.redraw = true
coroutine.yield(0.016) -- 60FPS
local sout = self.proc:read_stdout()
local serr = self.proc:read_stderr()
if sout == nil and serr == nil then
if sout == nil or serr == nil then
-- Make sure to read stderr for the last time
if serr and serr~="" then self.on_stderr(serr) end
local exitcode = self.proc:wait(process.WAIT_INFINITE)
self.on_exit(exitcode)
break
@ -120,11 +68,6 @@ function luadebug:run(target, name)
end)
end
function luadebug:continue()
if not self.proc then return end
self.mdb:run()
end
function luadebug:wait(time)
if not self.proc then return end
return self.proc:wait(time)
@ -143,7 +86,6 @@ function luadebug:read_stderr()
end
function luadebug:kill()
if self.mdb then self.mdb:kill() end
if not self.proc then return end
self.proc:kill()
end
@ -153,5 +95,104 @@ function luadebug:terminate()
self.proc:terminate()
end
-- --------------- Lua Process -----------------------------------
-- Main lua process spawner
function luadebug:spawn_lua_process(entry, lua, cwd, env)
local host = "localhost"
local port = 8172
-- Resolve vendor/?.lua so "require('mobdebug')" finds the bundled file
local vendor_glob = join(get_plugin_root(), "vendor/?.lua")
-- Build the inline lua launcher
local dbg_call = string.format([[
local ok, m = pcall(require, "mobdebug"); if ok then
print("Connecting to "..%q..":"..tostring(%d))
m.connecttimeout = 0.1
local connected = m.start(%q, %d)
if not connecten then m.off() end
end
print("Test123")
]], host, port, host, port)
local launcher = string.format([[
package.path = %q .. ";" .. package.path
%s
dofile(%q)
os.exit()
]], vendor_glob, dbg_call, entry)
-- Spawn the process
local cmd = {}
if type(lua) == "table" then
for i=1, #lua do table.insert(cmd, lua[i]) end
else
table.insert(cmd, lua)
end
table.insert(cmd, "-e")
table.insert(cmd, launcher)
local proc = process.start(cmd, {
cwd = cwd,
env = env,
stdout = process.REDIRECT_PIPE,
stderr = process.REDIRECT_PIPE,
})
return proc
end
-- ---------------- Mobdebug -------------------------------------
function luadebug:spawn_mdb(lua)
local host = "localhost"
local port = 8172
-- Resolve vendor/?.lua so "require('mobdebug')" finds the bundled file
local vendor_glob = join(get_plugin_root(), "vendor/?.lua")
local cmd = {}
if type(lua) == "table" then
for i=1, #lua do table.insert(cmd, lua[i]) end
else
table.insert(cmd, lua)
end
table.insert(cmd, "-e")
table.insert(cmd, string.format([[
package.path = %q .. ";" .. package.path
require("mobdebug").listen(%s, %d)
os.exit()
]], vendor_glob, host, port))
local proc = process.start(cmd, {
stdout = process.REDIRECT_PIPE,
stderr = process.REDIRECT_PIPE,
})
if proc == nil then
self.error("Failed to start debugger")
return
end
self.mdb = proc
self.mdb:write('run\n')
-- output pump
core.add_thread(function()
while true do
core.redraw = true
coroutine.yield(0.016) -- 60FPS
local sout = self.mdb:read_stdout()
local serr = self.mdb:read_stderr()
if sout == nil or serr == nil then
-- Make sure to read stderr for the last time
if serr and serr~="" then self.on_stderr(serr) end
local exitcode = self.mdb:wait(process.WAIT_INFINITE)
self.on_exit(exitcode)
break
end
if sout and sout~="" then self.on_stdout('mdb> '..sout) end
if serr and serr~="" then self.on_stderr('mdb> '..serr) end
end
end)
end
return luadebug

View File

@ -1,120 +0,0 @@
local core = require "core"
local process = require "process"
-- tiny helpers
local function join(a, b) return (a:sub(-1) == "/" and a or (a .. "/")) .. b end
---@class mdb
local mdb = {
proc = nil, ---@type process|nil
state = 'idle',
}
---@meta
function mdb.log(msg) end
---@meta
function mdb.error(msg) end
---@meta
function mdb.on_connected() end
---@meta
function mdb.on_pause(file, line) end
function mdb:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function mdb:set_state(newstate)
self.state = newstate
end
function mdb:parse_line(line)
self.log('mdb> '..line)
local words = {}
for w in line:gmatch("%w+") do table.insert(words, w) end
if words[1] == 'Paused' then
-- Breakpoint hit
if #words ~= 7 then return end
local file = words[4]
local linenr = tonumber(words[7])
self:set_state("paused")
core.add_thread(function() self.on_pause(file, linenr) end)
elseif words[1] == "Type" then
-- mobdebug started
self:set_state("paused")
core.add_thread(function() self.on_connected() end)
end
end
function mdb:spawn(lua, root)
local vendor_glob = join(root, "vendor/?.lua")
local cmd = {}
if type(lua) == "table" then
for i=1, #lua do table.insert(cmd, lua[i]) end
else
table.insert(cmd, lua)
end
table.insert(cmd, "-e")
table.insert(cmd, string.format([[
package.path = %q .. ";" .. package.path
require("mobdebug").listen()
]], vendor_glob))
self:set_state('spawning')
local proc = process.start(cmd, {
stdout = process.REDIRECT_PIPE,
stderr = process.REDIRECT_PIPE,
})
self.proc = proc
self:set_state('connecting')
core.add_thread(function()
while true do
core.redraw = true
coroutine.yield(0.016) -- 60FPS
local sout = self.proc:read_stdout()
local serr = self.proc:read_stderr()
if sout == nil and serr == nil then
-- mdb exited
break
end
if sout and sout~="" then
for l in string.gmatch(sout, "([^\n]+)") do
self:parse_line(l)
end
end
end
end)
end
function mdb:cmd(c)
-- commands are only possible when mdb is paused
if self.state == "paused" then
self.log('>>>'..c)
self.proc:write(c..'\n')
else
self.error('mdb not paused')
end
end
function mdb:run()
self:cmd("run")
end
function mdb:setb(file, line)
self:cmd(string.format("setb %s %d", file, line))
end
function mdb:kill()
self.proc:kill()
self.proc:kill()
end
return mdb

View File

@ -34,7 +34,9 @@ function shell:run(target, name)
coroutine.yield(0.016) -- 60FPS
local sout = self.proc:read_stdout()
local serr = self.proc:read_stderr()
if sout == nil and serr == nil then
if sout == nil or serr == nil then
-- Make sure to read stderr for the last time
if serr and serr~="" then self.on_stderr(serr) end
local exitcode = self.proc:wait(process.WAIT_INFINITE)
self.on_exit(exitcode)
break