Skip to content

Instantly share code, notes, and snippets.

@N64N64
Last active August 27, 2017 07:57
Show Gist options
  • Save N64N64/1a2fd90a4921a399b71c5c76941d622c to your computer and use it in GitHub Desktop.
Save N64N64/1a2fd90a4921a399b71c5c76941d622c to your computer and use it in GitHub Desktop.
OpenResty + Fengari debug console
local js = require 'js'.global
function js.window:onload()
local stdin = js.document:getElementById('stdin')
local stdout = js.document:getElementById('stdout')
stdin:focus()
local conn
local indicator = js.document:getElementById('connecting')
local connected = false
local remote = true
local function append(s, color)
local item = js.document:createElement('span')
item.innerText = s
item.innerHTML = item.innerHTML..'<br/>'
if color then
item.innerHTML = '<span style="color:'..color..';">'..item.innerHTML..'</span>'
end
stdout:appendChild(item)
js.window:scrollTo(0, js.document.body.scrollHeight);
end
_G.print = append
local f = {}
function f.clear()
stdout.innerText = ''
end
function f.reset()
conn:close()
end
function f.swap()
remote = not remote
append('remote = '..tostring(remote), 'lightblue')
end
local history = {}
local hist_idx = nil
local saved_text
local function run_cmd(cmd)
if remote then
conn:send(cmd)
else
local f, err = load('return '..cmd)
if not f then
f, err = load(cmd)
end
if not f then
append(err, 'red')
else
local success, result = pcall(f)
if success then
_G._ = result
append(tostring(result), 'lightgreen')
else
append(tostring(result), 'red')
end
end
end
end
function stdin:onkeydown(e)
if #history == 0 then return end
if e.keyCode == 38 then -- up
if not hist_idx then
hist_idx = #history
saved_text = stdin.value
else
hist_idx = hist_idx - 1
if hist_idx < 1 then
hist_idx = 1
end
end
elseif e.keyCode == 40 and hist_idx then -- down
hist_idx = hist_idx + 1
if hist_idx > #history then
hist_idx = nil
end
else
return
end
if hist_idx then
stdin.value = history[hist_idx]
else
stdin.value = saved_text
saved_text = nil
end
end
function stdin:onkeypress(e)
-- enter
if not(e.keyCode == 13) or not connected then return end
append('> '..stdin.value)
if f[stdin.value] then
f[stdin.value]()
else
run_cmd(stdin.value)
end
table.insert(history, stdin.value)
stdin.value = ''
hist_idx = nil
end
local function connect()
conn = js:eval('new WebSocket("ws://localhost:8080/ws/console");')
function conn:onclose(event)
indicator.style.visibility = 'visible'
connected = true
js:setTimeout(connect, 1000)
end
function conn:onopen(event)
indicator.style.visibility = 'hidden'
connected = true
end
function conn:onmessage(event)
local json = js.JSON:parse(event.data)
append(json.text, json.color)
end
end
function js.document.body:onclick()
stdin:focus()
end
append('LOL LUA CONSOLE', 'lightblue')
connect()
end
#console {
width:100%;
min-height:100%;
background:rgba(0,0,0,0.6);
color:#ffffff;
}
#connecting {
visibility:visible;
}
.console{
font-family:courier new;
font-size:20px;
color:#ffffff;
}
#stdin{
background-color:transparent;
border:0;
width:100%;
}
.input_container {
width:100%;
display:table;
}
.carrot {
display:table-cell;
width:21px;
}
.input {
display:table-cell;
}
input:focus {
outline:none;
outline-width: 0;
}
</style>
<div id="console" class="console">
<span id="connecting">Connecting...</span>
<div id="stdout"></div>
<div class="input_container">
<div class="carrot">&gt;</div>
<div class="input"><input id="stdin" class="console"/></div>
</div>
</div>
<script type="text/lua" src="/client.lua"></script>
local websocket = require 'resty.websocket.server'
local cjson = require 'cjson'
return function()
local ws, err = websocket:new{timeout = 30000, max_payload_len = 65535}
-- recieve loop
while true do
local bytes, typ, err = ws:recv_frame()
if ws.fatal then
break
elseif not bytes then
ws:send_ping()
elseif typ == 'close' then
break
elseif typ == 'text' then
local f, err = load('return '..bytes)
if not f then
f, err = load(bytes)
end
if not f then
ws:send_text(cjson.encode{text = err, color = 'red'})
else
local success, result = xpcall(f, debug.traceback)
if success then
_G._ = result
ws:send_text(cjson.encode{text = tostring(result), color = 'lightgreen'})
else
ws:send_text(cjson.encode{text = tostring(result), color = 'red'})
end
end
end
end
ws:send_close()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment