-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathui_view.py
159 lines (134 loc) · 4.34 KB
/
ui_view.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import asyncio, uuid, json, math
from datetime import datetime
from sublime import *
import sublime_plugin
from .sly import *
from typing import *
if "VIEWS" not in globals():
VIEWS = {}
class SlyUrlCommand(sublime_plugin.WindowCommand):
def run(self, **kwargs):
asyncio.run_coroutine_threadsafe(
self.async_run(**kwargs),
loop)
async def async_run(self, **q):
try:
view = VIEWS[q["__id"]]
await view.on_url_press(**q)
except e as Exception:
print("GeneralSlyUrlFailure", e)
class UIView:
def __init__ (self, window, session):
try:
global VIEWS
self._name = "UIView"
self.session = session
self.slynk = session.slynk
self.html = "System ready..."
self.id = uuid.uuid4().hex
VIEWS[self.id] = self
self.last_modified = datetime.now()
self.reöpen(window)
except Exception as e:
print(f"UIViewInitialisationFailure: {e}")
def flip(self):
self.sheet.set_contents(str(self.html))
self.last_modified = datetime.now()
@property
def window(self):
return self.sheet.window()
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
self.sheet.set_name(value)
@name.deleter
def name(self):
del self._name
def reöpen(self, window):
self.sheet = window.new_html_sheet(self.name, str(self.html))
@property
def is_open(self):
return self.sheet.window() is not None
def url(self, parameters):
parameters["__id"] = self.id
return f"subl:sly_url {json.dumps(parameters)}"
def destroy(self):
del VIEWS[self.id]
self.html = "[destroyed]"
self.name = "[destroyed]"
self.flip()
def focus(self):
self.window.focus_sheet(self.sheet)
# Sadly sublime text does support `<sub></sub>`
def to_subscript_unicode(string):
map = {
"0": "₀",
"1": "₁",
"2": "₂",
"3": "₃",
"4": "₄",
"5": "₅",
"6": "₆",
"7": "₇",
"8": "₈",
"9": "₉",
}
output = ""
for character in string:
output += map[character]
return output
def url(id, parameters):
parameters["__id"] = id
return f"subl:sly_url {json.dumps(parameters)}"
"""
Second type of UI below, the results panel.
It works just like the Sublime `Find Results` view.
"""
def number_lines(text, prefix="", suffix=" "):
lines = text.split("\n")
width = math.ceil(math.log(len(lines)))
offset = settings().get("line_offset")
return "\n".join([prefix + str(n+offset).rjust(width, ' ') + suffix + line
for n, line in enumerate(lines)])
def get_results_view(window):
view = None
for maybe_view in window.views():
if maybe_view.name() == "Sly Output":
view = maybe_view
break
if view and view.settings().get("is-sly-output-view"):
return view
session = sessions.get_by_window(window)
if session is None:
print("Error session should exist but doesn't 1")
raise Exception("Session should exist but doesn't 1")
view = window.new_file()
view.set_name("Sly Output")
view.set_scratch(True)
view.set_read_only(True)
view.settings().set("is-sly-output-view", True)
return view
def send_result_to_panel(window, text=None, result="[No result]", header="[Command_header]", file_name=None, should_fold=True):
view = get_results_view(window)
out = [header + "\n",
number_lines(text, " ") if text else "",
f"\nfrom: {file_name} is:\n" if file_name else "\n is:\n",
number_lines(result, " "),
"\n\n"]
# We store the position just before the result so
# we can navigate the user there as that's what they actually care about
# we also fold the region of the original text
origin = view.size()
region = Region(origin+len(out[0]), origin+len(out[0])+len(out[1]))
out = "".join(out)
view.run_command("repl_insert_text",
{"pos": view.size(),
"text": out})
window.focus_view(view)
if text and should_fold:
view.fold(region)
view.show(Region(origin, origin+len(out)))
return view