Skip to content

Commit 2951e8c

Browse files
authored
feat(gui): add error message for failed rectangle/dimension drawing (#109)
* wip fatal error handling in gui * feat(gui): add error message for failed rectangle/dimension drawing * revert sky130 pdk * cleanup
1 parent 1c12aa4 commit 2951e8c

File tree

8 files changed

+101
-35
lines changed

8 files changed

+101
-35
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ To open an example Argon workspace, run the following from the root directory of
6161
vim core/compiler/examples/argon_workspace/lib.ar
6262
```
6363

64-
Start the GUI by running `:Argon startGui`.
64+
Start the GUI by running `:Argon gui`.
6565

6666
From within the GUI, type `:openCell test()` to open the `test` cell. You should now be able to edit layouts
6767
in both Neovim and the GUI.
Lines changed: 1 addition & 0 deletions
Loading

core/gui/src/editor/canvas.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ impl LayoutCanvas {
12671267
let p0p = Point::new(f32::min(p0.x, p1.x), f32::min(p0.y, p1.y));
12681268
let p1p = Point::new(f32::max(p0.x, p1.x), f32::max(p0.y, p1.y));
12691269
self.state.update(cx, |state, cx| {
1270-
state.solved_cell.update(cx, {
1270+
let error = state.solved_cell.update(cx, {
12711271
|cell, cx| {
12721272
if let Some(cell) = cell.as_mut() {
12731273
// TODO update in memory representation of code
@@ -1293,26 +1293,39 @@ impl LayoutCanvas {
12931293
.find(|name| !names.contains(name))
12941294
.unwrap();
12951295

1296-
state.lang_server_client.draw_rect(
1297-
scope.span.clone(),
1298-
rect_name,
1299-
compile::BasicRect {
1300-
layer: state
1301-
.layers
1302-
.read(cx)
1303-
.selected_layer
1304-
.clone()
1305-
.map(|s| s.to_string()),
1306-
x0: p0p.x as f64,
1307-
y0: p0p.y as f64,
1308-
x1: p1p.x as f64,
1309-
y1: p1p.y as f64,
1310-
construction: false,
1311-
},
1312-
);
1296+
if state
1297+
.lang_server_client
1298+
.draw_rect(
1299+
scope.span.clone(),
1300+
rect_name,
1301+
compile::BasicRect {
1302+
layer: state
1303+
.layers
1304+
.read(cx)
1305+
.selected_layer
1306+
.clone()
1307+
.map(|s| s.to_string()),
1308+
x0: p0p.x as f64,
1309+
y0: p0p.y as f64,
1310+
x1: p1p.x as f64,
1311+
y1: p1p.y as f64,
1312+
construction: false,
1313+
},
1314+
)
1315+
.is_none()
1316+
{
1317+
Some("inconsistent editor and GUI state".into())
1318+
} else {
1319+
None
1320+
}
1321+
} else {
1322+
Some("no cell to edit".into())
13131323
}
13141324
}
13151325
});
1326+
if state.fatal_error.is_none() {
1327+
state.fatal_error = error;
1328+
}
13161329
});
13171330
} else {
13181331
let p0 = self.px_to_layout(event.position);

core/gui/src/editor/mod.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub struct Layers {
7171
pub struct EditorState {
7272
pub hierarchy_depth: usize,
7373
pub dark_mode: bool,
74+
pub fatal_error: Option<SharedString>,
7475
pub solved_cell: Entity<Option<CompileOutputState>>,
7576
pub hide_external_geometry: bool,
7677
pub layers: Entity<Layers>,
@@ -236,11 +237,13 @@ impl EditorState {
236237
{
237238
self.lang_server_client
238239
.show_message(MessageType::ERROR, "Open cell is invalid");
240+
self.fatal_error = Some(SharedString::from("open cell is invalid"));
239241
return;
240242
}
241243
d
242244
}
243245
_ => {
246+
self.fatal_error = Some(SharedString::from("static compile errors encountered"));
244247
return;
245248
}
246249
};
@@ -307,6 +310,7 @@ impl EditorState {
307310
});
308311
cx.notify();
309312
});
313+
self.fatal_error = None;
310314
}
311315
}
312316

@@ -327,6 +331,7 @@ impl Editor {
327331
EditorState {
328332
hierarchy_depth: usize::MAX,
329333
dark_mode: true,
334+
fatal_error: None,
330335
solved_cell,
331336
hide_external_geometry: false,
332337
tool,
@@ -472,7 +477,45 @@ impl Render for Editor {
472477
.flex_1()
473478
.min_h_0()
474479
.child(self.hierarchy_sidebar.clone())
475-
.child(div().flex_1().overflow_hidden().child(self.canvas.clone()))
480+
.child({
481+
let mut d = div()
482+
.flex_1()
483+
.relative()
484+
.overflow_hidden()
485+
.child(self.canvas.clone());
486+
487+
if let Some(fatal_error) = &self.state.read(cx).fatal_error {
488+
d = d.child(
489+
div()
490+
.id("error_modal")
491+
.bg(theme.bg)
492+
.border_1()
493+
.border_color(theme.divider)
494+
.rounded_sm()
495+
.absolute()
496+
.p_2()
497+
.child(
498+
div().flex().flex_row().text_color(theme.error).child(
499+
div().flex().flex_col().child(div().flex_1()).child(
500+
svg()
501+
.path("icons/circle-exclamation-solid-full.svg")
502+
.w(px(20.))
503+
.h_auto()
504+
.mr_1()
505+
.text_color(theme.error)).child(div().flex_1())
506+
)
507+
.child(div().child("Error"))
508+
)
509+
.child(format!("Editing disabled due to error: {fatal_error}."))
510+
.whitespace_normal()
511+
.top_2()
512+
.left_2()
513+
.right_2()
514+
);
515+
}
516+
517+
d
518+
})
476519
.child(self.layer_sidebar.clone()),
477520
)
478521
.child(self.text_input.clone())

core/gui/src/theme.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub struct Theme {
1010
pub selection: Rgba,
1111
pub input_bg: Rgba,
1212
pub axes: Rgba,
13+
pub error: Rgba,
1314
}
1415

1516
lazy_static! {
@@ -22,6 +23,7 @@ lazy_static! {
2223
selection: rgba(0x7236ff22),
2324
input_bg: rgb(0xEEEEEE),
2425
axes: rgb(0xcdb8ff),
26+
error: rgb(0xff00000),
2527
};
2628
pub static ref DARK_THEME: Theme = Theme {
2729
titlebar: rgb(0x1a1a1a),
@@ -32,5 +34,6 @@ lazy_static! {
3234
selection: rgba(0x7236ff66),
3335
input_bg: rgb(0x1a1a1a),
3436
axes: rgb(0x7236ff),
37+
error: rgb(0xff00000),
3538
};
3639
}

core/lang-server/src/rpc.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,24 @@ impl LangServer for State {
9393
) -> Option<Span> {
9494
let state_mut = self.state_mut.lock().await;
9595
let url = Url::from_file_path(&scope_span.path).unwrap();
96+
97+
if state_mut.ast.values().any(|ast| {
98+
ast.text
99+
!= state_mut
100+
.editor_files
101+
.get(&url)
102+
.map(|file| file.contents())
103+
.unwrap_or_default()
104+
}) {
105+
self.editor_client
106+
.show_message(
107+
MessageType::ERROR,
108+
"Editor buffer state is inconsistent with GUI state.",
109+
)
110+
.await;
111+
return None;
112+
}
113+
96114
if let Some(ast) = state_mut
97115
.ast
98116
.values()
@@ -166,18 +184,6 @@ impl LangServer for State {
166184
)
167185
};
168186

169-
if let Some(file) = state_mut.editor_files.get(&url)
170-
&& file.contents() != doc.contents()
171-
{
172-
self.editor_client
173-
.show_message(
174-
MessageType::ERROR,
175-
"Editor buffer state is inconsistent with GUI state.",
176-
)
177-
.await;
178-
return None;
179-
}
180-
181187
self.editor_client
182188
.show_document(ShowDocumentParams {
183189
uri: url.clone(),

plugins/nvim/lua/argon/commands/init.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ local gui = require('argon.commands.gui')
1313

1414
---@type argon.command_tbl[]
1515
local argon_command_tbl = {
16-
startGui = {
16+
gui = {
1717
impl = function(_, opts)
1818
gui.start_gui()
1919
end,
@@ -31,7 +31,7 @@ local argon_command_tbl = {
3131
log = {
3232
impl = function(args, opts)
3333
-- TODO: allow configuration of log file name.
34-
vim.cmd('tabnew ~/.local/state/argon/log')
34+
vim.cmd('tabnew ~/.local/state/argon/lang-server.log')
3535
end
3636
}
3737
}

plugins/vscode/src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export function activate(context: ExtensionContext) {
102102

103103
const log = async () => {
104104
// TODO: allow configuration via ARGON_HOME environment variable.
105-
const doc = await workspace.openTextDocument(path.join(os.homedir(), ".local/state/argon/log"));
105+
const doc = await workspace.openTextDocument(path.join(os.homedir(), ".local/state/argon/lang-server.log"));
106106
await window.showTextDocument(doc, {
107107
preview: false // ensures it's a new tab, not replacing the preview tab
108108
});

0 commit comments

Comments
 (0)