{#if output.length > 0}
- {@html output.replaceAll('\n', '
').replaceAll(' ', ' ')}
+ {@html replaceWithHTMLCharacterCodes(output)}
{/if}
{#if data !== undefined}
- {#if data.exitCode !== 0 && output.length > 0}
+ {#if !data.success}
{/if}
{#each data.errors as err}
@@ -90,11 +138,15 @@
{/each}
{#if data.modeRun}
- Homescript stopped with exit code
- {data.exitCode}
+ {#if data.success}
+ Homescript executed successfully
+ {:else}
+ Homescript failed with interrupt
+ {/if}
+ {:else if data.success}
+ Analyzer detected no issues
{:else}
- Lint finished with exit code
- {data.exitCode}
+ Analyzer detected issues
{/if}
{:else}
@@ -123,7 +175,7 @@
}
.cyan {
- color: #4cd1e0;
+ color: #4ad0df;
}
.gray {
diff --git a/web/src/components/Homescript/HmsEditor/HmsEditor.svelte b/web/src/components/Homescript/HmsEditor/HmsEditor.svelte
index 56e81198..dce9b866 100644
--- a/web/src/components/Homescript/HmsEditor/HmsEditor.svelte
+++ b/web/src/components/Homescript/HmsEditor/HmsEditor.svelte
@@ -2,10 +2,12 @@
import { EditorView, basicSetup } from 'codemirror'
import { EditorState } from '@codemirror/state'
import { indentWithTab } from '@codemirror/commands'
- import { keymap } from '@codemirror/view'
+ import { keymap, drawSelection, dropCursor } from '@codemirror/view'
import { linter, lintGutter, type Diagnostic } from '@codemirror/lint'
import { createEventDispatcher, onMount } from 'svelte'
- import { Homescript } from 'codemirror-lang-homescript'
+ import { indentUnit } from '@codemirror/language'
+ //import { Homescript } from 'codemirror-lang-homescript'
+ import {Homescript} from './index'
import { oneDark } from './oneDark'
import { lintHomescriptCode } from '../../../homescript'
import { createSnackbar } from '../../../global'
@@ -55,6 +57,8 @@
// eslint-disable-next-line no-undef
let timer: NodeJS.Timeout
+ // TODO: check filenames + syntaax erorrs in imported module
+
const HMSlinter = linter(async () => {
let diagnostics: Diagnostic[] = []
@@ -62,11 +66,37 @@
const result = await lintHomescriptCode(code, [], moduleName)
diagnostics = result.errors.map(e => {
let severity = 'error'
- if (e.kind === 'Warning') {
- severity = 'warning'
- } else if (e.kind === 'Info') {
- severity = 'info'
+ let message = 'error: unknown'
+ let kind = 'error: unknown'
+
+ // everything except diagnostics will be a standard `error`
+ if (e.syntaxError !== null) {
+ message = e.syntaxError.message
+ kind = 'SyntaxError'
+ } else if (e.diagnosticError !== null) {
+ message = e.diagnosticError.message
+ switch (e.diagnosticError.kind) {
+ case 0:
+ kind = 'Hint'
+ severity = 'hint'
+ break
+ case 1:
+ kind = 'Info'
+ severity = 'info'
+ break
+ case 2:
+ kind = 'Warning'
+ severity = 'warning'
+ break
+ case 3:
+ kind = 'Error'
+ severity = 'error'
+ break
+ }
+ } else if (e.runtimeError) {
+ throw 'A runtime error cannot occur during analysis'
}
+
return Object.create({
from: e.span.start.index,
to:
@@ -74,7 +104,7 @@
? e.span.end.index + 1
: e.span.end.index,
severity: severity,
- message: `${e.kind}: ${e.message}`,
+ message: `${kind}: ${message}`,
source: 'Homescript analyzer',
})
})
@@ -94,10 +124,14 @@
dispatch('update', code)
}
})
+
editor = new EditorView({
state: EditorState.create({
extensions: [
basicSetup,
+ drawSelection(),
+ dropCursor(),
+ indentUnit.of(' '),
keymap.of([indentWithTab]),
Homescript(),
oneDark,
@@ -124,15 +158,6 @@
}),
parent: editorDiv,
})
-
- /*
- editor.dispatch(
- editor.state.changeByRange((range) => ({
- changes: [{ from: range.from, insert: "switch('id', on)" }],
- range: EditorSelection.range(range.from + 2, range.to + 2),
- }))
- );
- */
})
@@ -153,5 +178,13 @@
.cm-lint-marker-error {
content: url('data:image/svg+xml,
') !important;
}
+
+ .ΝΌ4 .cm-line ::selection {
+ background-color: rgba(255, 255, 255, 0.2) !important;
+ }
+
+ .cm-selectionMatch {
+ background-color: rgba(100, 255, 0, 0.05) !important;
+ }
}
diff --git a/web/src/components/Homescript/HmsEditor/oneDark.ts b/web/src/components/Homescript/HmsEditor/oneDark.ts
index 730dfedd..f445110d 100644
--- a/web/src/components/Homescript/HmsEditor/oneDark.ts
+++ b/web/src/components/Homescript/HmsEditor/oneDark.ts
@@ -100,6 +100,7 @@ export const oneDarkTheme = EditorView.theme({
/// The highlighting style for code in the One Dark theme.
export const oneDarkHighlightStyle = HighlightStyle.define([
+ { tag: t.namespace, color: yellow },
{ tag: t.keyword, color: purple },
{ tag: t.className, color: yellow },
{ tag: [t.variableName, t.operator], color: fg },
diff --git a/web/src/homescript.ts b/web/src/homescript.ts
index 66c3748e..e8fef14d 100644
--- a/web/src/homescript.ts
+++ b/web/src/homescript.ts
@@ -47,19 +47,33 @@ export interface homescriptResponseWrapper {
}
export interface homescriptResponse {
- success: boolean
id: string
- exitCode: number
- message: string
+ success: boolean
output: string
fileContents: {}
errors: homescriptError[]
}
export interface homescriptError {
+ syntaxError: syntaxError
+ diagnosticError: diagnosticError
+ runtimeError: runtimeError
+ span: span
+}
+
+export interface syntaxError {
+ message: string
+}
+
+export interface diagnosticError {
+ kind: number
+ message: string
+ notes: string[]
+}
+
+export interface runtimeError {
kind: string
message: string
- span: span
}
export interface span {
diff --git a/web/src/pages/dash/App.svelte b/web/src/pages/dash/App.svelte
index 8861891d..2c7302c2 100644
--- a/web/src/pages/dash/App.svelte
+++ b/web/src/pages/dash/App.svelte
@@ -50,7 +50,14 @@
Widget Crashed
- {res.errors[0].kind}: {res.errors[0].message}
+ {#if res.errors[0].syntaxError !== null}
+ SyntaxError: {res.errors[0].syntaxError.message}
+ {:else if res.errors[0].diagnosticError !== null}
+ SemanticError: {res.errors[0].diagnosticError.message}
+ {:else}
+ {res.errors[0].runtimeError.kind}: {res.errors[0]
+ .runtimeError.message}
+ {/if}
{/if}
{/await}
diff --git a/web/src/pages/hmsEditor/App.svelte b/web/src/pages/hmsEditor/App.svelte
index ad3434be..3580a0d4 100644
--- a/web/src/pages/hmsEditor/App.svelte
+++ b/web/src/pages/hmsEditor/App.svelte
@@ -207,26 +207,32 @@
currentExecutionCount++
currentExecutionHandles++
try {
- if (currentData.data.code === '') output = 'Nothing to lint.'
- else {
- const currentExecResTemp = await lintHomescriptCode(
- currentData.data.code,
- [],
- currentData.data.id,
- )
- let diagnostics = currentExecResTemp.errors
- // If Info diagnostics should be hidden, do it here
- if (!showLintInfo) diagnostics = diagnostics.filter(d => d.kind !== 'Info')
- currentExecRes = {
- code: currentData.data.code,
- modeRun: false,
- exitCode: currentExecResTemp.exitCode,
- errors: diagnostics,
- fileContents: currentExecResTemp.fileContents,
- success: currentExecResTemp.success,
- }
- output = currentExecResTemp.output
+ const currentExecResTemp = await lintHomescriptCode(
+ currentData.data.code,
+ [],
+ currentData.data.id,
+ )
+ let errs = currentExecResTemp.errors
+
+ // If hint and info diagnostics should be hidden, do it here
+ if (!showLintInfo)
+ errs = errs.filter(d => {
+ if (d.diagnosticError !== null) {
+ if (d.diagnosticError.kind <= 1) {
+ return false
+ }
+ }
+ return true
+ })
+
+ currentExecRes = {
+ code: currentData.data.code,
+ modeRun: false,
+ errors: errs,
+ fileContents: currentExecResTemp.fileContents,
+ success: currentExecResTemp.success,
}
+ output = currentExecResTemp.output
} catch (err) {
$createSnackbar(`Failed to lint '${currentScript}': ${err}`)
}
@@ -299,7 +305,6 @@
currentExecRes = {
code: currentData.data.code,
modeRun: true,
- exitCode: message.exitCode,
errors: message.errors,
fileContents: message.fileContents,
success: message.success,
@@ -372,9 +377,7 @@
id="header__left__errors"
class:error={!currentExecRes.modeRun && !currentExecRes.success}
>
-
{currentExecRes.success ? 'done' : 'error'}
+
{currentExecRes.success ? 'done' : 'error'}
{currentExecRes.success ? 'working' : 'errors'}
{/if}
@@ -506,7 +509,8 @@
}
}
- &__save, &__errors {
+ &__save,
+ &__errors {
color: var(--clr-text-disabled);
display: flex;
align-items: center;
@@ -521,7 +525,8 @@
font-size: 1.25em;
}
- &.unsaved, &.error {
+ &.unsaved,
+ &.error {
color: var(--clr-error);
}
}
diff --git a/web/src/pages/hmsEditor/websocket.ts b/web/src/pages/hmsEditor/websocket.ts
index ff1dde3c..74cc6c5d 100644
--- a/web/src/pages/hmsEditor/websocket.ts
+++ b/web/src/pages/hmsEditor/websocket.ts
@@ -14,7 +14,6 @@ export interface hmsResMessage {
export interface hmsResWrapper {
code: string
modeRun: boolean
- exitCode: number
fileContents: {}
errors: homescriptError[]
success: boolean