From fa0c8d5a2cac46fbe851727f940a59a443ca8a10 Mon Sep 17 00:00:00 2001 From: "U-ENGINEERO\\joppe.blondel" Date: Mon, 27 Oct 2025 14:39:55 +0100 Subject: [PATCH] Went back to single script for luadebug --- .lite_project.lua | 5 +- init.lua | 31 ++-- runners/{luadebug/init.lua => luadebug.lua} | 187 ++++++++++++-------- runners/luadebug/mdb.lua | 120 ------------- runners/shell.lua | 4 +- 5 files changed, 141 insertions(+), 206 deletions(-) rename runners/{luadebug/init.lua => luadebug.lua} (60%) delete mode 100644 runners/luadebug/mdb.lua diff --git a/.lite_project.lua b/.lite_project.lua index 073027d..fc773ad 100644 --- a/.lite_project.lua +++ b/.lite_project.lua @@ -4,7 +4,7 @@ config.plugins.jpdebug = { targets = { ["test - msys"] = { type = "shell", - cmd = {"C:\\msys64\\msys2_shell.cmd", "-defterm", "-here", "-no-start", "-ucrt64", "-shell", "bash", "-c", "lua test.lua"} + cmd = {"C:\\msys64\\ucrt64\\bin\\lua.exe", "test.lua"} }, ["test"] = { type = "shell", @@ -14,7 +14,8 @@ config.plugins.jpdebug = { type = "luadebug", entry = "test.lua", cwd = ".", - lua = {"lua"}, + -- lua = {"lua"}, + lua = {"C:\\msys64\\ucrt64\\bin\\lua.exe"}, }, }, default_target = "luadebug" diff --git a/init.lua b/init.lua index 1e4d32c..efbc1dd 100644 --- a/init.lua +++ b/init.lua @@ -153,19 +153,30 @@ local function get_selected_target() end -- ---------- run target & pipe stdout/stderr into the view ---------- +local function ensure_debug_view() + if active_view then + return active_view + end + + local node = core.root_view:get_active_node() + local view = JPDebugView() + + -- Defer the add until the node is unlocked (next tick). + core.add_thread(function() + -- Wait until the layout is safe to mutate + while node.locked do coroutine.yield(0) end + node:add_view(view) + core.redraw = true + end) + + active_view = view + return view +end + local function run_target(target, name) -- Create/get view to push text to -- TODO fix this, it throws a node is locked error once in a while - local view = nil - if active_view then - -- If there is already a view use that one - view = active_view - else - -- Otherwhise lets make one - view = JPDebugView() - core.root_view:get_active_node():add_view(view) - active_view = view - end + local view = ensure_debug_view() -- Check if we have a runner for runner_name,runner in pairs(core.jpdebug.runners) do diff --git a/runners/luadebug/init.lua b/runners/luadebug.lua similarity index 60% rename from runners/luadebug/init.lua rename to runners/luadebug.lua index f9003b1..b6d1450 100644 --- a/runners/luadebug/init.lua +++ b/runners/luadebug.lua @@ -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 diff --git a/runners/luadebug/mdb.lua b/runners/luadebug/mdb.lua deleted file mode 100644 index 7c02f40..0000000 --- a/runners/luadebug/mdb.lua +++ /dev/null @@ -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 - diff --git a/runners/shell.lua b/runners/shell.lua index 12d9ab9..a659567 100644 --- a/runners/shell.lua +++ b/runners/shell.lua @@ -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