Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
147 lines (127 sloc) 3.85 KB
local js = require "js"
-- Save references to lua baselib functions used
local _G = _G
local load = load
local pack, unpack, tinsert, tremove = table.pack, table.unpack, table.insert, table.remove
local tostring = tostring
local traceback = debug.traceback
local xpcall = xpcall
local document = js.global.document
local hljs = js.global.hljs
local output = document:getElementById("fengari-console")
local prompt = document:getElementById("fengari-prompt")
local input = document:getElementById("fengari-input")
assert(output and prompt and input)
local function triggerEvent(el, type)
local e = document:createEvent("HTMLEvents")
e:initEvent(type, false, true)
el:dispatchEvent(e)
end
local history = {}
local historyIndex = nil
local historyLimit = 100
_G.print = function(...)
local toprint = pack(...)
local line = document:createElement("pre")
line.style["white-space"] = "pre-wrap"
output:appendChild(line)
for i = 1, toprint.n do
if i ~= 1 then
line:appendChild(document:createTextNode("\t"))
end
line:appendChild(document:createTextNode(tostring(toprint[i])))
end
output.scrollTop = output.scrollHeight
end
local function doREPL()
do
local line = document:createElement("span")
line:appendChild(document:createTextNode(prompt.textContent))
local item = document:createElement("pre")
item.className = "lua"
item.style.padding = "0"
item.style.display = "inline"
item.style["white-space"] = "pre-wrap"
item.textContent = input.value
hljs:highlightBlock(item)
line:appendChild(item)
output:appendChild(line)
output:appendChild(document:createElement("br"))
output.scrollTop = output.scrollHeight
end
if input.value.length == 0 then
return
end
local line = input.value
if history[#history] ~= line then
tinsert(history, line)
if #history > historyLimit then
tremove(history, 1)
end
end
local fn, err = load("return " .. line, "stdin")
if not fn then
fn, err = load(line, "stdin")
end
if fn then
local results = pack(xpcall(fn, traceback))
if results[1] then
if results.n > 1 then
_G.print(unpack(results, 2, results.n))
end
else
_G.print(results[2])
end
else
_G.print(err)
end
input.value = ""
triggerEvent(output, "change")
end
function input:onkeydown(e)
if not e then
e = js.global.event
end
local key = e.key or e.which
if key == "Enter" and not e.shiftKey then
historyIndex = nil
doREPL()
return false
elseif key == "ArrowUp" or key == "Up" then
if historyIndex then
if historyIndex > 1 then
historyIndex = historyIndex - 1
end
else -- start with more recent history item
local hist_len = #history
if hist_len > 0 then
historyIndex = hist_len
end
end
input.value = history[historyIndex]
return false
elseif key == "ArrowDown" or key == "Down" then
local newvalue = ""
if historyIndex then
if historyIndex < #history then
historyIndex = historyIndex + 1
newvalue = history[historyIndex]
else -- no longer in history
historyIndex = nil
end
end
input.value = newvalue
return false
elseif key == "l"
and e.ctrlKey
and not e.shiftKey
and not e.altKey
and not e.metaKey
and not e.isComposing then
-- Ctrl+L clears screen like you would expect in a terminal
output.innerHTML = ""
_G.print(_G._COPYRIGHT)
return false
end
end
_G.print(_G._COPYRIGHT)