-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathview_patch.mbt
More file actions
184 lines (174 loc) · 5.28 KB
/
view_patch.mbt
File metadata and controls
184 lines (174 loc) · 5.28 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// ViewPatch: Incremental patches for the editor protocol.
///|
/// Visual decoration applied to a half-open text range `[from, to)` in the
/// editor's source view.
///
/// `css_class` is the CSS class the frontend should attach to the range;
/// `widget` indicates that the decoration replaces the range with an inline
/// widget rather than overlaying its character cells. `data` is an opaque
/// string the frontend may use to discriminate between decorations of the
/// same class (e.g. a kind tag for a hover popover).
pub(all) struct Decoration {
from : Int
to : Int
css_class : String
data : String?
widget : Bool
} derive(Debug, Eq)
///|
pub fn Decoration::Decoration(
from~ : Int,
to~ : Int,
css_class~ : String,
data? : String,
widget? : Bool = false,
) -> Decoration {
{ from, to, css_class, data, widget }
}
///|
/// Severity level for a `Diagnostic`. Serialised as the lowercase strings
/// `"error" | "warning" | "info" | "hint"` for frontend consumers.
pub(all) enum Severity {
SevError
SevWarning
SevInfo
SevHint
} derive(Debug, Eq)
///|
pub impl ToJson for Severity with fn to_json(self) {
match self {
SevError => "error".to_json()
SevWarning => "warning".to_json()
SevInfo => "info".to_json()
SevHint => "hint".to_json()
}
}
///|
/// A diagnostic message associated with a half-open text range `[from, to)`.
/// Used to surface compiler/linter findings to the editor frontend.
pub(all) struct Diagnostic {
from : Int
to : Int
severity : Severity
message : String
} derive(Debug, Eq)
///|
pub fn Diagnostic::Diagnostic(
from~ : Int,
to~ : Int,
severity~ : Severity,
message~ : String,
) -> Diagnostic {
{ from, to, severity, message }
}
///|
/// Incremental patches emitted by the editor and applied by the frontend.
///
/// A patch describes one change to the editor's view. Patches are JSON
/// serialisable; the canonical mapping is defined by `ToJson for ViewPatch`
/// below and consumed by `adapters/editor-adapter` on the TypeScript side.
/// Frontends must treat unknown variants as no-ops so the protocol can be
/// extended without a breaking change.
pub(all) enum ViewPatch {
TextChange(from~ : Int, to~ : Int, insert~ : String)
ReplaceNode(node_id~ : @core.NodeId, node~ : ViewNode)
InsertChild(parent_id~ : @core.NodeId, index~ : Int, child~ : ViewNode)
RemoveChild(parent_id~ : @core.NodeId, index~ : Int, child_id~ : @core.NodeId)
UpdateNode(
node_id~ : @core.NodeId,
label~ : String,
css_class~ : String,
text~ : String?
)
SetDecorations(decorations~ : Array[Decoration])
SetDiagnostics(diagnostics~ : Array[Diagnostic])
SetSelection(anchor~ : Int, head~ : Int)
SelectNode(node_id~ : @core.NodeId)
FullTree(root~ : ViewNode?)
} derive(Debug, Eq)
///|
pub impl ToJson for Decoration with fn to_json(self) {
let m : Map[String, Json] = {}
m["from"] = self.from.to_json()
m["to"] = self.to.to_json()
m["css_class"] = self.css_class.to_json()
m["data"] = match self.data {
Some(d) => d.to_json()
None => Json::null()
}
m["widget"] = self.widget.to_json()
Json::object(m)
}
///|
pub impl ToJson for Diagnostic with fn to_json(self) {
let m : Map[String, Json] = {}
m["from"] = self.from.to_json()
m["to"] = self.to.to_json()
m["severity"] = self.severity.to_json()
m["message"] = self.message.to_json()
Json::object(m)
}
///|
pub impl ToJson for ViewPatch with fn to_json(self) {
let m : Map[String, Json] = {}
match self {
TextChange(from~, to~, insert~) => {
m["type"] = "TextChange".to_json()
m["from"] = from.to_json()
m["to"] = to.to_json()
m["insert"] = insert.to_json()
}
ReplaceNode(node_id~, node~) => {
m["type"] = "ReplaceNode".to_json()
m["node_id"] = node_id.to_json()
m["node"] = node.to_json()
}
InsertChild(parent_id~, index~, child~) => {
m["type"] = "InsertChild".to_json()
m["parent_id"] = parent_id.to_json()
m["index"] = index.to_json()
m["child"] = child.to_json()
}
RemoveChild(parent_id~, index~, child_id~) => {
m["type"] = "RemoveChild".to_json()
m["parent_id"] = parent_id.to_json()
m["index"] = index.to_json()
m["child_id"] = child_id.to_json()
}
UpdateNode(node_id~, label~, css_class~, text~) => {
m["type"] = "UpdateNode".to_json()
m["node_id"] = node_id.to_json()
m["label"] = label.to_json()
m["css_class"] = css_class.to_json()
m["text"] = match text {
Some(t) => t.to_json()
None => Json::null()
}
}
SetDecorations(decorations~) => {
m["type"] = "SetDecorations".to_json()
m["decorations"] = Json::array(decorations.map(fn(d) { d.to_json() }))
}
SetDiagnostics(diagnostics~) => {
m["type"] = "SetDiagnostics".to_json()
m["diagnostics"] = Json::array(diagnostics.map(fn(d) { d.to_json() }))
}
SetSelection(anchor~, head~) => {
m["type"] = "SetSelection".to_json()
m["anchor"] = anchor.to_json()
m["head"] = head.to_json()
}
SelectNode(node_id~) => {
m["type"] = "SelectNode".to_json()
m["node_id"] = node_id.to_json()
}
FullTree(root~) => {
m["type"] = "FullTree".to_json()
m["root"] = match root {
Some(r) => r.to_json()
None => Json::null()
}
}
}
Json::object(m)
}