Skip to content

Commit

Permalink
Merge pull request #102 from mindofmatthew/codemirror-6-highlights
Browse files Browse the repository at this point in the history
Work on Codemirror 6 highlighting
  • Loading branch information
felixroos committed Apr 28, 2022
2 parents f97f8be + ef42ca6 commit f00e28c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 47 deletions.
28 changes: 26 additions & 2 deletions repl/src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useCallback, useLayoutEffect, useRef, useState, useEffect } from 'react';
import CodeMirror6, { highlightEvent } from './CodeMirror6';
import CodeMirror6, { setHighlights } from './CodeMirror6';
import cx from './cx';
import logo from './logo.svg';
import playStatic from './static.mjs';
Expand Down Expand Up @@ -91,7 +91,8 @@ function App() {
tune: decoded || randomTune,
defaultSynth,
// onDraw: useCallback((time, event) => markEvent(editor)(time, event), [editor]),
onDraw: useCallback((_, e, code) => code && highlightEvent(e, view, code), [view]),
// onDraw: useCallback((_, e, code) => code && highlightEvent(e, view, code), [view]),
onDraw: () => {},
});
const [uiHidden, setUiHidden] = useState(false);
const logBox = useRef();
Expand All @@ -118,6 +119,29 @@ function App() {
return () => window.removeEventListener('keydown', handleKeyPress);
}, [pattern, code, activateCode, cycle]);

useEffect(() => {
if (view) {
if (pattern && cycle.started) {
let frame = requestAnimationFrame(updateHighlights);

function updateHighlights() {
let audioTime = Tone.Transport.seconds;
let timespan = new strudel.TimeSpan(audioTime, audioTime + 1 / 60);
let events = pattern.query(new strudel.State(timespan));
view.dispatch({ effects: setHighlights.of(events) });

frame = requestAnimationFrame(updateHighlights);
}

return () => {
cancelAnimationFrame(frame);
};
} else {
view.dispatch({ effects: setHighlights.of([]) });
}
}
}, [pattern, cycle.started]);

useWebMidi({
ready: useCallback(
({ outputs }) => {
Expand Down
60 changes: 15 additions & 45 deletions repl/src/CodeMirror6.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { javascript } from '@codemirror/lang-javascript';
import { materialPalenight } from './themes/material-palenight';

const highlightMark = Decoration.mark({ class: 'cm-highlight' });
const addHighlight = StateEffect.define();
const removeHighlight = StateEffect.define();
export const setHighlights = StateEffect.define();
const highlightTheme = EditorView.baseTheme({
'.cm-highlight': { outline: '1px solid #FFCA28' },
// '.cm-highlight': { background: '#FFCA28' },
Expand All @@ -19,60 +18,29 @@ const highlightField = StateField.define({
},
update(highlights, tr) {
try {
highlights = highlights.map(tr.changes);
for (let e of tr.effects) {
if (e.is(addHighlight)) {
highlights = highlights.update({
add: [highlightMark.range(e.value.from, e.value.to)],
});
}
if (e.is(removeHighlight)) {
highlights = highlights.update({
filter: (f, t, value) => {
if (f === e.value.from && t === e.value.to) {
return false;
}
return true;
// console.log('filter', f,t,value, e.value.from, e.value.to);
},
});
if (e.is(setHighlights)) {
highlights = Decoration.set(
e.value
.flatMap((event) => event.context.locations || [])
.map(({ start, end }) => {
let from = tr.newDoc.line(start.line).from + start.column;
let to = tr.newDoc.line(end.line).from + end.column;
return highlightMark.range(from, to);
}),
true,
);
}
}
return highlights;
} catch (err) {
// console.warn('highlighting error', err);
console.warn('highlighting error', err);
return highlights;
}
},
provide: (f) => EditorView.decorations.from(f),
});

// let timeouts = [];

export const highlightEvent = (event, view, code) => {
if (!view) {
return;
}
const ranges = event.context?.locations?.map(({ start, end }) => {
return [start, end].map(({ line, column }) => positionToOffset({ line: line - 1, ch: column }, code));
});
const effects = ranges.map(([from, to]) => addHighlight.of({ from, to }));

if (!effects.length) return false;
if (!view.state.field(highlightField, false)) {
effects.push(StateEffect.appendConfig.of([highlightField, highlightTheme]));
}
view.dispatch({ effects });
// const index = timeouts.length;
// timeouts = timeouts.filter(time)
/* const timeout = */ setTimeout(() => {
const effects = ranges.map(([from, to]) => removeHighlight.of({ from, to }));
view.dispatch({ effects });
// timeouts.splice(index, 1);
}, event.duration * 1000);
// timeouts.pusn({timeout,);
};

export default function CodeMirror({ value, onChange, onViewChanged, onCursor, options, editorDidMount }) {
return (
<>
Expand All @@ -88,6 +56,8 @@ export default function CodeMirror({ value, onChange, onViewChanged, onCursor, o
extensions={[
javascript(),
materialPalenight,
highlightField,
highlightTheme,
// theme, language, ...
]}
/>
Expand Down

0 comments on commit f00e28c

Please sign in to comment.