forked from mvoidex/UnicodeMath
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unicodecomplete.py
109 lines (93 loc) · 3.56 KB
/
unicodecomplete.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
import sublime
import sublime_plugin
import re
from mathsymbols import maths, inverse_maths, synonims, inverse_synonims
def log(message):
print(u'UnicodeMath: {0}'.format(message))
def get_line_contents(view, location):
"""
Returns the contents of the line at the given location
"""
return view.substr(sublime.Region(view.line(location).a, location))
UNICODE_RE = re.compile(r'.*(\\([^\s]+)\s)$')
UNICODE_PREFIX_RE = re.compile(r'.*(\\([^\s]+))$')
def get_unicode_prefix(view, location, leadspace):
"""
Returns unicode prefix at given location and it's region
or None if there is no unicode prefix
"""
cts = get_line_contents(view, location)
RE = UNICODE_RE if leadspace else UNICODE_PREFIX_RE
res = RE.match(cts)
if res:
(full_, pref_) = res.groups()
return (pref_, sublime.Region(location - len(full_), location))
else:
return None
def is_unicode_prefix(view, location):
"""
Returns True if prefix at given location is prefixed with backslash
"""
cts = get_line_contents(view, location)
return UNICODE_PREFIX_RE.match(cts) != None
class UnicodeMathComplete(sublime_plugin.EventListener):
supress_replace = False
def on_query_completions(self, view, prefix, locations):
# is prefix starts with '\\'
if not is_unicode_prefix(view, locations[0]):
return
# returns completions
return [(k, k + ' ') for k in filter(lambda s: s.startswith(prefix), maths.keys())]
def on_modified(self, view):
if UnicodeMathComplete.supress_replace:
UnicodeMathComplete.supress_replace = False
return
edit = view.begin_edit()
try:
for r in view.sel():
if r.a == r.b:
p = get_unicode_prefix(view, r.a, True)
if p:
if p[0] in maths:
view.replace(edit, p[1], maths[p[0]])
elif p[0] in synonims:
view.replace(edit, p[1], maths[synonims[p[0]]])
finally:
view.end_edit(edit)
def on_selection_modified(self, view):
pass
class UnicodeMathSwap(sublime_plugin.TextCommand):
def run(self, edit):
for r in self.view.sel():
upref = get_unicode_prefix(self.view, self.view.word(r).b, False)
if upref and upref[0] in maths:
self.view.replace(edit, upref[1], maths[upref[0]])
elif r.b - r.a <= 1:
u = sublime.Region(r.b - 1, r.b)
usym = self.view.substr(u)
if usym in inverse_maths:
UnicodeMathComplete.supress_replace = True
self.view.replace(edit, u, u'\\' + inverse_maths[usym])
else:
self.view.replace(edit, u, u'\\u%04X' % ord(usym))
class UnicodeMathInsert(sublime_plugin.WindowCommand):
def run(self):
self.menu_items = []
self.symbols = []
for k, v in maths.items():
value = v + ' ' + k
if k in inverse_synonims:
value += ' ' + ' '.join(inverse_synonims[k])
self.menu_items.append(value)
self.symbols.append(v)
self.window.show_quick_panel(self.menu_items, self.on_done)
def on_done(self, idx):
if idx == -1:
return
view = self.window.active_view()
if not view:
return
edit = view.begin_edit()
for r in view.sel():
view.replace(edit, r, self.symbols[idx])
view.end_edit(edit)