-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdrepl-lua.lua
105 lines (92 loc) · 2.48 KB
/
drepl-lua.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
local json = require 'dkjson'
local repl = require 'repl'
local concat = table.concat
local error = error
local format = string.format
local stdin, stdout = io.stdin, io.stdout
local drepl = repl:clone()
drepl.keep_running = true
drepl:loadplugin 'autoreturn'
drepl:loadplugin 'completion'
drepl._features.console = true -- Lie about this to make pretty_print happy.
drepl:loadplugin 'pretty_print'
function drepl:displayerror(err)
stdout:write(err, "\n")
stdout:flush()
end
local function sendmsg(data)
stdout:write(format("\x1b]5161;%s\x1b\\", json.encode(data)))
stdout:flush()
end
local function readmsg()
sendmsg{op="status", status="ready"}
local buffer, c = {}, nil
while c ~= "=" do
local line = stdin:read()
if line == nil then return end
c = line:match("^\x1b([+=])") or error(format("Unexpected input: %q", line))
buffer[#buffer+1] = line:sub(3)
end
return json.decode(concat(buffer))
end
local function no_op(_, args)
sendmsg{id=args.id}
end
function drepl:showprompt(prompt)
stdout:write(prompt .. ' ')
stdout:flush()
end
function drepl:process_message()
local message = readmsg()
if message == nil then -- Got an EOF signal
self.keep_running = false
return
end
local method = self["drepl_" .. message.op] or no_op
method(self, message)
end
function drepl:drepl_eval(args)
sendmsg{op="status", status="rawio"}
self._buffer = ""
local v = self:handleline(args.code)
if v == 2 then
local _, err = self:compilechunk(args.code)
self:displayerror(err or "incomplete input")
end
self:prompt(1)
end
function drepl:drepl_checkinput(args)
local _, err = self:compilechunk(args.code)
local cont = err and self:detectcontinue(err)
sendmsg{
id=args.id,
status=not err and "complete" or cont and "incomplete" or "invalid",
prompt=err and self:getprompt(2) .. " " or nil,
indent=""
}
end
function drepl:drepl_complete(args)
local prefix = args.code:sub(1, args.pos)
local cands = {}
self:complete(
prefix,
function(line)
local suffix = line:sub(-1, -1)
local type = (suffix == "." and "table") or (suffix=="(" and "function") or nil
local _, _, cand = line:find("([%a%d_]+)[.(]?$")
cands[#cands+1] = {text=cand, type=type}
end
)
sendmsg{
id=args.id,
candidates=cands
}
end
function drepl:main()
self:prompt(1)
while self.keep_running do
local ok, err = pcall(self.process_message, self)
if not ok then sendmsg{op="log", text=err} end
end
end
return drepl