This repository has been archived by the owner on May 9, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
/
gotools_goto_def.py
110 lines (87 loc) · 3.72 KB
/
gotools_goto_def.py
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
106
107
108
109
110
import sublime
import sublime_plugin
import os
import json
from .gotools_util import Buffers
from .gotools_util import GoBuffers
from .gotools_util import Logger
from .gotools_util import ToolRunner
from .gotools_settings import GoToolsSettings
class GotoolsGotoDef(sublime_plugin.TextCommand):
def is_enabled(self):
return GoBuffers.is_go_source(self.view)
# Capture mouse events so users can click on a definition.
def want_event(self):
return True
def run(self, edit, event=None):
sublime.set_timeout_async(lambda: self.godef(event), 0)
def godef(self, event):
# Find and store the current filename and byte offset at the
# cursor or mouse event location.
if event:
filename, row, col, offset = Buffers.location_for_event(self.view, event)
else:
filename, row, col, offset, offset_end = Buffers.location_at_cursor(self.view)
backend = GoToolsSettings.get().goto_def_backend if GoToolsSettings.get().goto_def_backend else ""
try:
if backend == "oracle":
file, row, col = self.get_oracle_location(filename, offset)
elif backend == "godef":
file, row, col = self.get_godef_location(filename, offset)
else:
Logger.log("Invalid godef backend '" + backend + "' (supported: godef, oracle)")
Logger.status("Invalid godef configuration; see console log for details")
return
except Exception as e:
Logger.status(str(e))
return
if not os.path.isfile(file):
Logger.log("WARN: file indicated by godef not found: " + file)
Logger.status("godef failed: Please enable debugging and check console log")
return
Logger.log("opening definition at " + file + ":" + str(row) + ":" + str(col))
w = self.view.window()
new_view = w.open_file(file + ':' + str(row) + ':' + str(col), sublime.ENCODED_POSITION)
group, index = w.get_view_index(new_view)
if group != -1:
w.focus_group(group)
def get_oracle_location(self, filename, offset):
args = ["-pos="+filename+":#"+str(offset), "-format=json", "definition"]
# Build up a package scope contaning all packages the user might have
# configured.
# TODO: put into a utility
package_scope = []
for p in GoToolsSettings.get().build_packages:
package_scope.append(os.path.join(GoToolsSettings.get().project_package, p))
for p in GoToolsSettings.get().test_packages:
package_scope.append(os.path.join(GoToolsSettings.get().project_package, p))
for p in GoToolsSettings.get().tagged_test_packages:
package_scope.append(os.path.join(GoToolsSettings.get().project_package, p))
if len(package_scope) > 0:
args = args + package_scope
location, err, rc = ToolRunner.run("oracle", args)
if rc != 0:
raise Exception("no definition found")
Logger.log("oracle output:\n" + location.rstrip())
# cut anything prior to the first path separator
location = json.loads(location.rstrip())['definition']['objpos'].rsplit(":", 2)
if len(location) != 3:
raise Exception("no definition found")
file = location[0]
row = int(location[1])
col = int(location[2])
return [file, row, col]
def get_godef_location(self, filename, offset):
location, err, rc = ToolRunner.run("godef", ["-f", filename, "-o", str(offset)])
if rc != 0:
raise Exception("no definition found")
Logger.log("godef output:\n" + location.rstrip())
# godef is sometimes returning this junk as part of the output,
# so just cut anything prior to the first path separator
location = location.rstrip().rsplit(":", 2)
if len(location) != 3:
raise Exception("no definition found")
file = location[0]
row = int(location[1])
col = int(location[2])
return [file, row, col]