From db9677bcca1ab92821a8bdc9dbeb14edfa356618 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 25 Dec 2020 20:28:35 +0200 Subject: [PATCH] Highlight line that has error --- package.json | 2 +- src/App.tsx | 14 +++++++++----- src/components/CodeEditor.tsx | 26 +++++++++++++++++++++++++- yarn.lock | 8 ++++---- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 463467b..b443f5e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "react-simple-code-editor": "^0.11.0", "styled-components": "^5.2.0", "typescript": "~3.7.2", - "zwiftout": "^0.5.0" + "zwiftout": "^1.0.0" }, "scripts": { "predeploy": "yarn build", diff --git a/src/App.tsx b/src/App.tsx index a428462..c8bc31c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import React, { useState, useCallback } from "react"; import { WorkoutPlot } from "./components/WorkoutPlot"; import { WorkoutStats } from "./components/WorkoutStats"; -import { parse } from "zwiftout"; +import { parse, ParseError, ValidationError, ZwiftoutException } from "zwiftout"; import { ErrorMessage } from "./components/ErrorMessage"; import styled from "styled-components"; import { CodeEditor } from "./components/CodeEditor"; @@ -32,7 +32,7 @@ const AppContainer = styled.div` export function App() { const [text, setText] = useState(defaultWorkout); const [workout, setWorkout] = useState(parse(defaultWorkout)); - const [error, setError] = useState(undefined); + const [error, setError] = useState(undefined); const onChange = useCallback( (value: string) => { @@ -41,7 +41,11 @@ export function App() { setWorkout(parse(value)); setError(undefined); } catch (e) { - setError(e.message); + if (e instanceof ParseError || e instanceof ValidationError) { + setError(e); + } else { + throw e; + } } }, [setText, setWorkout, setError], @@ -50,9 +54,9 @@ export function App() { return ( - + - {error && {error}} + {error && {error.message}} diff --git a/src/components/CodeEditor.tsx b/src/components/CodeEditor.tsx index daad4ce..7303c59 100644 --- a/src/components/CodeEditor.tsx +++ b/src/components/CodeEditor.tsx @@ -1,5 +1,7 @@ +import React, { useCallback } from "react"; import Editor from "react-simple-code-editor"; import styled from "styled-components"; +import { ZwiftoutException } from "zwiftout"; const highlight = (code: string): string => { return code @@ -11,7 +13,7 @@ const highlight = (code: string): string => { .replace(/@(.*?)$/gm, "@$1"); }; -export const CodeEditor = styled(Editor).attrs({ padding: 10, highlight })` +export const BaseCodeEditor = styled(Editor).attrs({ padding: 10 })` font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; line-height: 1.3; @@ -46,4 +48,26 @@ export const CodeEditor = styled(Editor).attrs({ padding: 10, highlight })` font-style: italic; color: #888; } + code.error { + background-color: rgba(252, 152, 152, 0.5); + border-radius: 4px; + } `; + +const highlightErrorLine = (code: string, linenr: number): string => { + const regex = new RegExp(`^((?:[^\\n]*?\\n){${linenr}})([^\\n]*?)\\n`); + return code.replace(regex, "$1$2\n"); +}; + +interface CodeEditorProps { + value: string; + onValueChange: (value: string) => void; + error: ZwiftoutException | undefined; +} + +export const CodeEditor: React.FC = ({ value, onValueChange, error }) => { + const highlightFn = useCallback((code: string) => highlight(error ? highlightErrorLine(code, error.loc.row) : code), [ + error, + ]); + return ; +}; diff --git a/yarn.lock b/yarn.lock index d9170b7..6f88612 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11075,10 +11075,10 @@ yargs@^13.3.0, yargs@^13.3.2: y18n "^4.0.0" yargs-parser "^13.1.2" -zwiftout@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/zwiftout/-/zwiftout-0.5.0.tgz#ca46fa1e0f16fba185bce97ba8f1d3674011ceff" - integrity sha512-GHHd8N27l5AfYs36tl8a5n4sMos8kw7zI5ojA6K3tbyrLRyPAk2EF439CubK0XX5ad0JLr9gnpZwzKrNo5Kd2A== +zwiftout@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/zwiftout/-/zwiftout-1.0.0.tgz#58dd2f2cf556e97a8a0b7385a2429f4cb2f5fabf" + integrity sha512-N1IOERpuInNUwTn8vL97lH/Tuwy8wjTE2XhUybBplmmK9AcPSgSx2Ll4fQXnGHEtEG0Sen5ev9Kv3lgQrdmReQ== dependencies: argparse "^2.0.1" ramda "^0.27.1"