Skip to content

Commit 4bda38b

Browse files
Rich-HarrisRich Harris
and
Rich Harris
authored
show inline diagnostics (#17) (#257)
Co-authored-by: Rich Harris <[email protected]>
1 parent 8ab615a commit 4bda38b

File tree

8 files changed

+105
-5
lines changed

8 files changed

+105
-5
lines changed

content/tutorial/common/src/__client.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,14 @@ if (import.meta.hot) {
118118
'*'
119119
);
120120
});
121+
122+
import.meta.hot.on('svelte:warnings', (data) => {
123+
parent.postMessage(
124+
{
125+
type: 'warnings',
126+
data
127+
},
128+
'*'
129+
);
130+
});
121131
}

content/tutorial/common/svelte.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ const config = {
55
// Don't do this in your own apps unless you know what you're doing!
66
// See https://kit.svelte.dev/docs/configuration#csrf for more info.
77
csrf: false
8+
},
9+
10+
vitePlugin: {
11+
experimental: {
12+
sendWarningsToBrowser: true
13+
}
814
}
915
};
1016

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@codemirror/lang-html": "^6.4.2",
3939
"@codemirror/lang-javascript": "^6.1.4",
4040
"@codemirror/language": "^6.6.0",
41+
"@codemirror/lint": "^6.2.0",
4142
"@codemirror/state": "^6.2.0",
4243
"@codemirror/view": "^6.9.2",
4344
"@fontsource/roboto-mono": "^4.5.10",

pnpm-lock.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/routes/tutorial/[slug]/Editor.svelte

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
import { EditorState } from '@codemirror/state';
77
import { indentWithTab } from '@codemirror/commands';
88
import { indentUnit } from '@codemirror/language';
9+
import { setDiagnostics } from '@codemirror/lint';
910
import { javascript } from '@codemirror/lang-javascript';
1011
import { html } from '@codemirror/lang-html';
1112
import { svelte } from '@replit/codemirror-lang-svelte';
1213
import { tags } from '@lezer/highlight';
1314
import { HighlightStyle } from '@codemirror/language';
1415
import { syntaxHighlighting } from '@codemirror/language';
1516
import { afterNavigate, beforeNavigate } from '$app/navigation';
16-
import { files, selected_file, selected_name, update_file } from './state.js';
17+
import { files, selected_file, selected_name, update_file, warnings } from './state.js';
1718
import './codemirror.css';
1819
1920
// TODO add more styles (selection ranges, etc)
@@ -49,7 +50,31 @@
4950
theme
5051
];
5152
52-
$: if (editor_view) select_state($selected_name);
53+
$: if (editor_view) {
54+
select_state($selected_name);
55+
56+
if ($selected_name) {
57+
const current_warnings = $warnings[$selected_name];
58+
59+
if (current_warnings) {
60+
const diagnostics = current_warnings.map((warning) => {
61+
/** @type {import('@codemirror/lint').Diagnostic} */
62+
const diagnostic = {
63+
from: warning.start.character,
64+
to: warning.end.character,
65+
severity: 'warning',
66+
message: warning.message
67+
};
68+
69+
return diagnostic;
70+
});
71+
72+
const transaction = setDiagnostics(editor_view.state, diagnostics);
73+
74+
editor_view.dispatch(transaction);
75+
}
76+
}
77+
}
5378
5479
$: reset($files);
5580
@@ -178,6 +203,9 @@
178203
reset($files);
179204
180205
select_state($selected_name);
206+
207+
// clear warnings
208+
warnings.set({});
181209
});
182210
</script>
183211

src/routes/tutorial/[slug]/Output.svelte

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import Chrome from './Chrome.svelte';
66
import Loading from './Loading.svelte';
77
import { base, error, logs, progress, subscribe } from './adapter';
8+
import { warnings } from './state';
89
910
/** @type {import('$lib/types').Exercise} */
1011
export let exercise;
@@ -61,6 +62,11 @@
6162
}, 1000);
6263
} else if (e.data.type === 'ping-pause') {
6364
clearTimeout(timeout);
65+
} else if (e.data.type === 'warnings') {
66+
warnings.update(($warnings) => ({
67+
...$warnings,
68+
[e.data.data.normalizedFilename]: e.data.data.allWarnings
69+
}));
6470
}
6571
}
6672

src/routes/tutorial/[slug]/codemirror.css

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,28 @@
4949
color: var(--sk-text-2);
5050
}
5151

52+
.cm-editor .cm-tooltip {
53+
border: none;
54+
border-radius: 2px;
55+
overflow: hidden;
56+
margin: 0.4rem 0;
57+
filter: drop-shadow(1px 2px 5px rgba(0,0,0,0.1));
58+
}
59+
.cm-editor .cm-tooltip-hover {}
60+
.cm-editor .cm-tooltip-below {}
61+
.cm-editor .cm-tooltip-lint {}
62+
.cm-editor .cm-tooltip-section {}
63+
.cm-editor .cm-diagnostic {
64+
border: none;
65+
padding: 0.2rem 0.8rem;
66+
}
67+
.cm-editor .cm-diagnostic-warning {
68+
/* background: hsl(36, 100%, 32%); */
69+
background: hsl(39, 100%, 10%);
70+
}
71+
.cm-editor .cm-diagnosticText {}
72+
73+
5274
@media (prefers-color-scheme: dark) {
5375
.cm-editor .cm-activeLineGutter {
5476
background-color: var(--sk-back-3);
@@ -57,4 +79,8 @@
5779
.cm-editor .cm-activeLine {
5880
background-color: var(--sk-back-2);
5981
}
82+
83+
.cm-editor .cm-diagnostic-warning {
84+
background: hsl(39, 100%, 20%);
85+
}
6086
}

src/routes/tutorial/[slug]/state.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
11
import { derived, writable } from 'svelte/store';
22
import * as adapter from './adapter.js';
33

4-
/** @type {import('svelte/store').Writable<import('$lib/types').Stub[]>} */
4+
/**
5+
* @template T
6+
* @typedef {import('svelte/store').Writable<T>} Writable<T>
7+
*/
8+
9+
// TODO would be nice if svelte exported this type (maybe it does already?)
10+
/**
11+
* @typedef {{
12+
* code: string;
13+
* start: { line: number, column: number, character: number };
14+
* end: { line: number, column: number, character: number };
15+
* pos: number;
16+
* filename: string;
17+
* frame: string;
18+
* message: string;
19+
* }} CompilerWarning
20+
*/
21+
22+
/** @type {Writable<import('$lib/types').Stub[]>} */
523
export const files = writable([]);
624

7-
/** @type {import('svelte/store').Writable<Record<string, import('$lib/types').Stub>>} */
25+
/** @type {Writable<Record<string, import('$lib/types').Stub>>} */
826
export const solution = writable({});
927

10-
/** @type {import('svelte/store').Writable<string | null>} */
28+
/** @type {Writable<Record<string, CompilerWarning[]>>} */
29+
export const warnings = writable({});
30+
31+
/** @type {Writable<string | null>} */
1132
export const selected_name = writable(null);
1233

1334
export const selected_file = derived([files, selected_name], ([$files, $selected_name]) => {

0 commit comments

Comments
 (0)