forked from ameyp/CscopeSublime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cscope.py
123 lines (104 loc) · 4.28 KB
/
cscope.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
111
112
113
114
115
116
117
118
119
120
121
122
123
import sublime, sublime_plugin
import os
import re
import subprocess
class CscopeCommand(sublime_plugin.TextCommand):
def __init__(self, view):
self.view = view
self.database = None
self.settings = sublime.load_settings("Cscope.sublime-settings")
self.verbose = self.settings.get("verbose", False)
self.panel = self.view.window().get_output_panel("cscope")
def run(self, edit, mode):
self.log("Called: %d" % mode)
# self.word_separators = self.view.settings().get('word_separators')
# print self.view.sel()
# self.view.insert(edit, 0, "Hello, World!")
one = self.view.sel()[0].a
two = self.view.sel()[0].b
self.view.sel().add(sublime.Region(one,
two))
for sel in self.view.sel():
word = self.view.substr(self.view.word(sel))
self.log("running cscope on %s" % word)
options = self.run_cscope(mode, word)
self.view.window().show_quick_panel(options, self.on_done)
def on_done(self, picked):
self.log("Selection: %d" % picked)
if picked == -1:
return
line = self.matches[picked]["line"]
filepath = os.path.join(self.root, self.matches[picked]["file"])
if os.path.isfile(filepath):
sublime.active_window().open_file(filepath + ":" + line, sublime.ENCODED_POSITION)
def log(self, text):
if self.verbose:
print "Cscope: " + text
def find_database(self):
cdir = os.path.dirname(self.view.file_name())
while cdir != os.path.dirname(cdir):
if ("cscope.out" in os.listdir(cdir)):
self.database = os.path.join(cdir, "cscope.out")
self.root = cdir
#print "Database found: ", self.database
break
cdir = os.path.dirname(cdir)
if self.database == None:
sublime.status_message("Could not find cscope database: cscope.out")
def run_cscope(self, mode, word):
# 0 ==> C symbol
# 1 ==> function definition
# 2 ==> functions called by this function
# 3 ==> functions calling this function
# 4 ==> text string
# 5 ==> egrep pattern
# 6 ==> files
if self.database == None:
self.find_database()
newline = ''
if sublime.platform() == "windows":
newline = '\r\n'
else:
newline = '\n'
cscope_arg_list = ['cscope', '-dL', '-f', self.database, '-' + str(mode) + word]
popen_arg_list = {
"shell": False,
"stdout": subprocess.PIPE,
"stderr": subprocess.PIPE
}
if (sublime.platform() == "windows"):
popen_arg_list["creationflags"] = 0x08000000
proc = subprocess.Popen(cscope_arg_list, **popen_arg_list)
output = proc.communicate()[0].split(newline)
#print output
self.matches = []
for i in output:
match = self.match_output_line(i, mode)
if match != None:
self.matches.append(match)
#print "File ", match.group(1), ", Line ", match.group(2), ", Instance ", match.group(3)
#self.view.window().run_command("show_overlay", {"overlay": "goto", "text": "@"})
options = []
for match in self.matches:
options.append("%(file)s:%(line)s - %(instance)s" % match)
return options
def match_output_line(self, line, mode):
match = None
if mode == 0:
match = re.match('(\S+?)\s+?(<global>)?\s+(\d+)\s+(.+)', line)
elif mode == 1:
match = re.match('(\S+?)\s+?\S+\s+(\d+)\s+(.+)', line)
if match != None:
if match.lastindex == 4:
return {
"file": match.group(1),
"line": match.group(3),
"instance": match.group(4)
}
else:
return {
"file": match.group(1),
"line": match.group(2),
"instance": match.group(3)
}
return None