Merge pull request #186 from tidalcycles/fix-codemirror-bug

Fix codemirror bug
This commit is contained in:
Felix Roos 2022-08-14 11:30:59 +02:00 committed by GitHub
commit b5e2bdf0f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 43 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback, useMemo, useRef, useLayoutEffect } from 'react';
import React, { useCallback, useState, useEffect, useMemo, useRef, useLayoutEffect } from 'react';
import _CodeMirror from '@uiw/react-codemirror';
import { Decoration, EditorView } from '@codemirror/view';
import { StateEffect, StateField } from '@codemirror/state';
@ -89,41 +89,57 @@ const highlightField = StateField.define({
try {
for (let e of tr.effects) {
if (e.is(setHighlights)) {
highlights = Decoration.set(e.value.flatMap((hap) => (hap.context.locations || []).map(({ start, end }) => {
const color = hap.context.color || "#FFCA28";
let from = tr.newDoc.line(start.line).from + start.column;
let to = tr.newDoc.line(end.line).from + end.column;
const l = tr.newDoc.length;
if (from > l || to > l) {
return;
}
const mark = Decoration.mark({ attributes: { style: `outline: 1.5px solid ${color};` } });
return mark.range(from, to);
})).filter(Boolean), true);
const marks = e.value.map(
(hap) => (hap.context.locations || []).map(({ start, end }) => {
const color = hap.context.color || "#FFCA28";
let from = tr.newDoc.line(start.line).from + start.column;
let to = tr.newDoc.line(end.line).from + end.column;
const l = tr.newDoc.length;
if (from > l || to > l) {
return;
}
const mark = Decoration.mark({ attributes: { style: `outline: 1.5px solid ${color};` } });
return mark.range(from, to);
})
).flat().filter(Boolean) || [];
highlights = Decoration.set(marks, true);
}
}
return highlights;
} catch (err) {
return highlights;
return Decoration.set([]);
}
},
provide: (f) => EditorView.decorations.from(f)
});
const extensions = [javascript(), strudelTheme, highlightField, flashField];
function CodeMirror({ value, onChange, onViewChanged, onSelectionChange, options, editorDidMount }) {
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(_CodeMirror, {
value,
onChange: (value2) => {
onChange(value2);
const handleOnChange = useCallback(
(value2) => {
onChange?.(value2);
},
onCreateEditor: (view) => {
onViewChanged(view);
[onChange]
);
const handleOnCreateEditor = useCallback(
(view) => {
onViewChanged?.(view);
},
onUpdate: (viewUpdate) => {
[onViewChanged]
);
const handleOnUpdate = useCallback(
(viewUpdate) => {
if (viewUpdate.selectionSet && onSelectionChange) {
onSelectionChange(viewUpdate.state.selection);
onSelectionChange?.(viewUpdate.state.selection);
}
},
extensions: [javascript(), strudelTheme, highlightField, flashField]
[onSelectionChange]
);
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(_CodeMirror, {
value,
onChange: handleOnChange,
onCreateEditor: handleOnCreateEditor,
onUpdate: handleOnUpdate,
extensions
}));
}
@ -300,7 +316,7 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP
},
[pattern],
),
onSchedule: useCallback((_events, cycle) => logCycle(_events, cycle), []),
onSchedule: useCallback((_events, cycle) => logCycle(_events), []),
ready: !!pattern && !!activeCode,
});

View File

@ -5,6 +5,7 @@ import { StateField, StateEffect } from '@codemirror/state';
import { javascript } from '@codemirror/lang-javascript';
import strudelTheme from '../themes/strudel-theme';
import './style.css';
import { useCallback } from 'react';
export const setFlash = StateEffect.define();
const flashField = StateField.define({
@ -48,9 +49,9 @@ const highlightField = StateField.define({
try {
for (let e of tr.effects) {
if (e.is(setHighlights)) {
highlights = Decoration.set(
const marks =
e.value
.flatMap((hap) =>
.map((hap) =>
(hap.context.locations || []).map(({ start, end }) => {
const color = hap.context.color || '#FFCA28';
let from = tr.newDoc.line(start.line).from + start.column;
@ -64,37 +65,51 @@ const highlightField = StateField.define({
return mark.range(from, to);
}),
)
.filter(Boolean),
true,
);
.flat()
.filter(Boolean) || [];
highlights = Decoration.set(marks, true);
}
}
return highlights;
} catch (err) {
// console.warn('highlighting error', err);
return highlights;
return Decoration.set([]);
}
},
provide: (f) => EditorView.decorations.from(f),
});
const extensions = [javascript(), strudelTheme, highlightField, flashField];
export default function CodeMirror({ value, onChange, onViewChanged, onSelectionChange, options, editorDidMount }) {
const handleOnChange = useCallback(
(value) => {
onChange?.(value);
},
[onChange],
);
const handleOnCreateEditor = useCallback(
(view) => {
onViewChanged?.(view);
},
[onViewChanged],
);
const handleOnUpdate = useCallback(
(viewUpdate) => {
if (viewUpdate.selectionSet && onSelectionChange) {
onSelectionChange?.(viewUpdate.state.selection);
}
},
[onSelectionChange],
);
return (
<>
<_CodeMirror
value={value}
onChange={(value) => {
onChange(value);
}}
onCreateEditor={(view) => {
onViewChanged(view);
}}
onUpdate={(viewUpdate) => {
if (viewUpdate.selectionSet && onSelectionChange) {
onSelectionChange(viewUpdate.state.selection);
}
}}
extensions={[javascript(), strudelTheme, highlightField, flashField]}
onChange={handleOnChange}
onCreateEditor={handleOnCreateEditor}
onUpdate={handleOnUpdate}
extensions={extensions}
/>
</>
);