-
Notifications
You must be signed in to change notification settings - Fork 8
/
project_syntax.py
121 lines (83 loc) · 3.56 KB
/
project_syntax.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
import json
import os.path
import re
import sublime
import sublime_plugin
class ProjectSpecificSyntax(sublime_plugin.EventListener):
def on_load(self, view):
self._ensure_project_specific_syntax(view)
def on_post_save(self, view):
self._ensure_project_specific_syntax(view)
def _ensure_project_specific_syntax(self, view):
filename = view.file_name()
if not filename:
return
syntax = self._get_project_specific_syntax(view, filename)
if syntax:
self._set_syntax(view, syntax)
def _get_project_specific_syntax(self, view, filename):
project_data = _resolve_window(view).project_data()
if not project_data:
return None
syntax_settings = project_data.get('syntax_override', {})
for regex, syntax in syntax_settings.items():
if re.search(regex, filename):
return syntax
return None
def _set_syntax(self, view, syntax):
syntax_path = '/'.join(syntax)
# prefer the newer .sublime-syntax files over .tmLanguage
ss_path = 'Packages/{0}.sublime-syntax'.format(syntax_path)
if os.path.isfile(ss_path):
view.set_syntax_file(ss_path)
else:
view.set_syntax_file('Packages/{0}.tmLanguage'.format(syntax_path))
print('Switched syntax to: {0}'.format(syntax_path))
class ProjectSpecificSyntaxToClipboardCommand(sublime_plugin.TextCommand):
def __init__(self, view):
super().__init__(view)
self._view = view
def run(self, edit):
suggested_setting = self._build_suggested_setting()
if not suggested_setting:
sublime.set_clipboard('Unable to create syntax setting')
else:
sublime.set_clipboard(suggested_setting)
def _build_suggested_setting(self):
suggested_setting = self._build_syntax_setting_for_current_file()
if not suggested_setting:
return None
return self._enclose_in_syntax_override_block_if_not_present_in_settings(suggested_setting)
def _build_syntax_setting_for_current_file(self):
syntax_path_parts = self._get_syntax_path_parts()
if not syntax_path_parts:
return None
syntax_path_json = json.dumps(syntax_path_parts)
file_regex = self._get_example_file_regex_for_current_file()
return '"{0}": {1}'.format(file_regex, syntax_path_json)
def _get_syntax_path_parts(self):
syntax = self.view.settings().get('syntax')
match = re.search(r'^Packages/(.*)\.(tmLanguage|sublime-syntax)$', syntax)
if not match:
print('Syntax does not match expected format: {0}'.format(syntax))
return None
return match.group(1).split('/')
def _enclose_in_syntax_override_block_if_not_present_in_settings(self, suggested_setting):
if self._is_syntax_override_already_present_in_settings():
return suggested_setting
return '"syntax_override": {{\n\t{0}\n}}'.format(suggested_setting)
def _is_syntax_override_already_present_in_settings(self):
project_data = _resolve_window(self._view).project_data()
return 'syntax_override' in project_data
def _get_example_file_regex_for_current_file(self):
file_name = self.view.file_name()
if file_name:
ext = os.path.splitext(file_name)[1]
else:
ext = '.xyz'
return '\\\\{0}$'.format(ext)
def _resolve_window(view):
window = view.window()
if window:
return window
return sublime.active_window()