forked from joneshf/sublime-grasp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
grasp.py
63 lines (48 loc) · 2.04 KB
/
grasp.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
import os
from json import loads
from subprocess import PIPE, Popen
from sublime import platform, Region
from sublime_plugin import TextCommand
class GraspCommand(TextCommand):
def run(self, crap):
self.view.window().show_input_panel('Enter your grasp command', '',
self.run_grasp, None, None)
def run_grasp(self, raw_command):
'''This is the workhorse of the command.'''
if platform() == 'windows':
command = ['grasp.cmd']
else:
command = ['grasp']
# We're going to want a json object back with tons of data.
command.extend(['-j'])
command.extend(raw_command.split())
# Grab the cwd and the file.
cwd, file_name = os.path.split(self.view.file_name())
command.append(file_name)
# Run the command.
pipe = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd)
result, error = pipe.communicate()
# TODO: Handle errors.
# Build up our selected regions.
if result:
self.view.sel().clear()
for match in loads(result.decode()):
start, stop = self.raw_to_abs(match)
# Add it to the region.
self.view.sel().add(Region(start, stop))
self.view.show(self.view.sel()[0])
def raw_to_abs(self, raw):
'''
Takes in a dict with grasp metadata,
and returns 2-tuple of (start, stop).
Grasp provides a very nice start and end property with each match.
It'd be ideal to use that.
Unfortunately, windows uses \r\n for line endings,
and sublime may not be set up for that, so it can lead to funky errors.
It's easier to parse the row and col and build the values from there.
'''
raw_start = raw['loc']['start']
raw_end = raw['loc']['end']
s = self.view.text_point(raw_start['line'] - 1, raw_start['column'])
e = self.view.text_point(raw_end['line'] - 1, raw_end['column'])
return s, e