-
Notifications
You must be signed in to change notification settings - Fork 0
/
go-def.lua
90 lines (71 loc) · 1.95 KB
/
go-def.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
-- shell quoting
local function Q(s) --> quoted string
return "'" .. s:gsub("'", "'\\''") .. "'"
end
-- fail with a message
local function die(msg, ...)
if select("#", ...) > 0 then
msg = msg:format(...)
end
io.stderr:write(arg[0]:match("[^/]+$"), ": [error] ", msg, "\n")
os.exit(false)
end
-- conditional failure
local function die_if(cond, msg, ...)
if cond then
die(msg, ...)
end
end
-- check return of a system function
local function just(ok, err, code, ...) --> all parameters
if ok then
return ok, err, code, ...
end
if math.type(code) == "integer" then
die_if(err == "signal", "interrupted with signal %u", code)
if err == "exit" then
os.exit(code)
end
end
die(err)
end
-- convert string to a positive integer
local function as_number(s) --> integer
die_if(not s:match("^%d+$"), "invalid parameter: %q", s)
return s | 0
end
-- get offset from line and column
local function offset(fname, line, col) --> integer
local n, i = 0, 0
local src = just(io.open(fname))
local s = src:read("L")
while s and i < line do
n = n + #s
i = i + 1
s = src:read("L")
end
just(src:close())
die_if(i < line, "file %q has only got %u lines in it", fname, i)
if s then
die_if(col >= #s,
"invalid column %u: line %u is only %u bytes long", col, line, #s)
elseif col > 0 then
die("invalid column %u: line %u is empty", col, line)
end
return n + col
end
-- ask "guru" tool for definition location
local function ask_guru(fname, line, col) --> string
local src = just(io.popen("guru definition " .. Q(fname) .. ":#" .. offset(fname, line, col)))
local s = src:read("a")
just(src:close())
return s
end
-- check parameters
if not arg[1] or not arg[2] or not arg[3] or arg[4] then
die("This is a tool for Kate editor, do not use it standalone.")
end
-- get definition location string
local loc = ask_guru(arg[1], as_number(arg[2]), as_number(arg[3]))
-- launch editor
just(os.execute('kate 2>/dev/null ' .. Q(loc:match("^.-:%d+:%d+"))))