package.nounload.zbs = true
package.nounload.mobdebug = true
local farprint, dbgprint = print, nil
local mobdebug = require("mobdebug")
local status = {attached=false,on=false}
local os_exit = os.exit
local function attach(on_detach,...)
if status.attached then return false, "Already attached" end
local lasterror
print = function(...) lasterror = table.concat({...},"\t")end
local success = mobdebug.start(...)
mobdebug.on()
dbgprint = print~=farprint and print
print = farprint
if success then
status = {attached=true; on=true}
os.exit = function()
mobdebug.done()
os.exit = os_exit
status = {attached=false; on=false}
if on_detach then on_detach() end
end
return success
else
return false, lasterror or "Server is not available"
end
end
local function detach()
if status.attached then
os.exit()
return true
else
return false, "Not attached"
end
end
local projectroot = ""
local function setprojectroot(path)
projectroot = assert(path,"Project root path expected")
end
local function normpath (name)
return name:lower():gsub(projectroot,""):gsub("\\","/")
end
local function breakhere()
if not status.attached then return false, "Not attached" end
local info = debug.getinfo(1)
local name,line = normpath(info.source:match"@(.+)"),info.lastlinedefined-1
mobdebug.on()
mobdebug.setbreakpoint(name,line)
mobdebug.removebreakpoint(name,line)
end
local bp = {}
local function setbreakpoint(file,line)
file = normpath(file)
bp[file] = bp[file] or {}; bp[file][line] = true
return mobdebug.setbreakpoint(file,line)
end
local function removebreakpoint(file,line)
file = normpath(file)
if bp[file] and bp[file][line] then bp[file][line] = false end
return mobdebug.setbreakpoint(file,line)
end
local function hasbreakpoint(file,line)
file = normpath(file)
return bp[file] and bp[file][line]
end
local function on()
status.on = true
mobdebug.on()
end
local function off()
status.on = false
mobdebug.off()
end
local function corostub(stub)
return function(f, ...)
return stub(function(...)
on()
return f(...)
end, ...)
end
end
local cocreate, cowrap = coroutine.create, coroutine.wrap
local cocreate_dbg, cowrap_dbg = corostub(cocreate, cowrap)
local function coro(set)
if set == nil then
if coroutine.create==cocreate then
coroutine.create, coroutine.wrap = cocreate_dbg, cowrap_dbg
end
elseif set == true then
return cocreate_dbg, cowrap_dbg
elseif set == false then
return cocreate, cowrap
end
end
return {
attach = attach,
detach = detach,
on = on, off = off,
status = function (param) return status[param] end,
coro = coro,
breakhere = breakhere,
hasbreakpoint = hasbreakpoint,
setbreakpoint = setbreakpoint,
removebreakpoint = removebreakpoint,
setprojectroot = setprojectroot,
dbgprint = function(...) (dbgprint or far.Show)(...) end,
}