-
Notifications
You must be signed in to change notification settings - Fork 26
/
hyper_click_command.py
88 lines (73 loc) · 2.82 KB
/
hyper_click_command.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
import sublime_plugin
import sublime
import re
from .hyper_click.path_resolver import HyperClickPathResolver
import webbrowser
def get_cursor(view, event=None):
if event:
vector = (event['x'], event['y'])
point = view.window_to_text(vector)
return sublime.Region(point)
else:
return view.sel()[0]
class HyperClickJumpCommand(sublime_plugin.TextCommand):
def __init__(self, view):
self.current_line = (-1, -1)
self.view = view
self.settings = sublime.load_settings('HyperClick.sublime-settings')
self.window = view.window()
def want_event(self):
return True
def run(self, edit, event=None):
self.window = self.view.window()
view = self.view
if len(view.sel()) != 1:
return
# Setting self.roots here (instead of in `__init__`) fixes a bug with files opened through the quick panel
self.roots = self.window and self.window.folders()
cursor = get_cursor(view, event).b
line_range = view.line(cursor)
line_content = view.substr(line_range).strip()
matched = self.is_valid_line(line_content)
if matched:
destination_str = matched.group(1)
file_path = HyperClickPathResolver(
view,
destination_str,
self.roots,
self.settings
)
resolved_path = file_path.resolve()
if resolved_path:
if resolved_path.startswith('http://') or resolved_path.startswith('https://'):
webbrowser.open_new_tab(resolved_path)
else:
self.window.open_file(resolved_path)
return
self.window.status_message("File not found")
def is_valid_line(self, line_content):
view = self.view
scopes = self.settings.get('scopes', {})
for selector in scopes:
if view.match_selector(view.sel()[0].b, selector):
for regex_str in scopes[selector]['regexes']:
pattern = re.compile(regex_str)
matched = pattern.match(line_content)
if matched:
return matched
return False
def is_visible(self, event=None):
view = self.view
selector = "(" + ")|(".join(self.settings.get('selectors')) + ")"
if not view.match_selector(view.sel()[0].b, selector):
return False
else:
cursor = get_cursor(view, event)
if not (len(view.sel()) == 1 and cursor.empty()):
return False
line_range = view.line(cursor)
line_content = view.substr(line_range).strip()
matched = self.is_valid_line(line_content)
if matched:
return True
return False