Moved PrebakeCodeMirror to its own file
This commit is contained in:
parent
6707c7893b
commit
a60a54147c
4 changed files with 96 additions and 88 deletions
|
|
@ -19,7 +19,7 @@ import { basicSetup } from './basicSetup.mjs';
|
||||||
import { evalBlock } from './block_utilities.mjs';
|
import { evalBlock } from './block_utilities.mjs';
|
||||||
import { flash, isFlashEnabled } from './flash.mjs';
|
import { flash, isFlashEnabled } from './flash.mjs';
|
||||||
import { highlightMiniLocations, isPatternHighlightingEnabled, updateMiniLocations } from './highlight.mjs';
|
import { highlightMiniLocations, isPatternHighlightingEnabled, updateMiniLocations } from './highlight.mjs';
|
||||||
import { keybindings, prebakeField } from './keybindings.mjs';
|
import { keybindings } from './keybindings.mjs';
|
||||||
import { jumpToCharacter } from './labelJump.mjs';
|
import { jumpToCharacter } from './labelJump.mjs';
|
||||||
import { getSliderWidgets, sliderPlugin, updateSliderWidgets } from './slider.mjs';
|
import { getSliderWidgets, sliderPlugin, updateSliderWidgets } from './slider.mjs';
|
||||||
import { activateTheme, initTheme, theme } from './themes.mjs';
|
import { activateTheme, initTheme, theme } from './themes.mjs';
|
||||||
|
|
@ -476,90 +476,6 @@ export class StrudelMirror {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PrebakeCodeMirror {
|
|
||||||
constructor(initialCode, storePrebake, containerRef, editorRef, settings) {
|
|
||||||
this.storePrebake = storePrebake;
|
|
||||||
const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()]));
|
|
||||||
const initialSettings = Object.keys(compartments).map((key) =>
|
|
||||||
compartments[key].of(extensions[key](parseBooleans(settings[key]))),
|
|
||||||
);
|
|
||||||
initTheme(settings.theme);
|
|
||||||
let state = EditorState.create({
|
|
||||||
doc: initialCode,
|
|
||||||
extensions: [
|
|
||||||
...initialSettings,
|
|
||||||
basicSetup,
|
|
||||||
javascript(),
|
|
||||||
javascriptLanguage.data.of({
|
|
||||||
closeBrackets: { brackets: ['(', '[', '{', "'", '"', '<'] },
|
|
||||||
bracketMatching: { brackets: ['(', '[', '{', "'", '"', '<'] },
|
|
||||||
}),
|
|
||||||
syntaxHighlighting(defaultHighlightStyle),
|
|
||||||
EditorView.updateListener.of((v) => {
|
|
||||||
if (v.docChanged) {
|
|
||||||
this.code = v.state.doc.toString();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
drawSelection({ cursorBlinkRate: 0 }),
|
|
||||||
Prec.highest(
|
|
||||||
keymap.of([
|
|
||||||
{
|
|
||||||
mac: 'Meta-Enter',
|
|
||||||
run: () => {
|
|
||||||
this.savePrebake();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'Ctrl-Enter',
|
|
||||||
run: () => {
|
|
||||||
this.savePrebake();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'Alt-Enter',
|
|
||||||
run: () => {
|
|
||||||
this.savePrebake();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
prebakeField,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
editorRef.current = state;
|
|
||||||
this.code = initialCode;
|
|
||||||
this.view = new EditorView({
|
|
||||||
state,
|
|
||||||
parent: containerRef.current,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async savePrebake() {
|
|
||||||
flash(this.view);
|
|
||||||
this.storePrebake(this.code);
|
|
||||||
logger('[prebake] prebake saved');
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleComment() {
|
|
||||||
try {
|
|
||||||
// Honor selections; toggleLineComment handles both selections and
|
|
||||||
// single line
|
|
||||||
toggleLineComment(this.view);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error handling repl-toggle-comment event', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setCode(code) {
|
|
||||||
const changes = {
|
|
||||||
from: 0,
|
|
||||||
to: this.view.state.doc.length,
|
|
||||||
insert: code,
|
|
||||||
};
|
|
||||||
this.view.dispatch({ changes });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function parseBooleans(value) {
|
export function parseBooleans(value) {
|
||||||
return { true: true, false: false }[value] ?? value;
|
return { true: true, false: false }[value] ?? value;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,5 @@ export * from './flash.mjs';
|
||||||
export * from './slider.mjs';
|
export * from './slider.mjs';
|
||||||
export * from './themes.mjs';
|
export * from './themes.mjs';
|
||||||
export * from './widget.mjs';
|
export * from './widget.mjs';
|
||||||
|
export * from './basicSetup.mjs';
|
||||||
export { Vim, prebakeField } from './keybindings.mjs';
|
export { Vim, prebakeField } from './keybindings.mjs';
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import { defaultSettings, settingsMap, useSettings, storePrebakeScript, setSettingsTab } from '../../../settings.mjs';
|
import { defaultSettings, settingsMap, useSettings, storePrebakeScript, setSettingsTab } from '../../../settings.mjs';
|
||||||
import { themes, codemirrorSettings, PrebakeCodeMirror } from '@strudel/codemirror';
|
import { themes, codemirrorSettings } from '@strudel/codemirror';
|
||||||
|
import { PrebakeCodeMirror } from '../../../repl/prebakeCodeMirror.mjs';
|
||||||
import { confirmAndReloadPage, isUdels } from '../../util.mjs';
|
import { confirmAndReloadPage, isUdels } from '../../util.mjs';
|
||||||
import { ButtonGroup } from './Forms.jsx';
|
import { ButtonGroup } from './Forms.jsx';
|
||||||
import { AudioDeviceSelector } from './AudioDeviceSelector.jsx';
|
import { AudioDeviceSelector } from './AudioDeviceSelector.jsx';
|
||||||
import { AudioEngineTargetSelector } from './AudioEngineTargetSelector.jsx';
|
import { AudioEngineTargetSelector } from './AudioEngineTargetSelector.jsx';
|
||||||
import { confirmDialog } from '../../util.mjs';
|
import { confirmDialog } from '../../util.mjs';
|
||||||
import { DEFAULT_MAX_POLYPHONY, setMaxPolyphony, setMultiChannelOrbits } from '@strudel/webaudio';
|
import { DEFAULT_MAX_POLYPHONY, setMaxPolyphony, setMultiChannelOrbits } from '@strudel/webaudio';
|
||||||
import { ActionButton, IconButton, SpecialActionButton } from '../button/action-button.jsx';
|
import { ActionButton, SpecialActionButton } from '../button/action-button.jsx';
|
||||||
import { exportScript, ImportPrebakeScriptButton } from './ImportPrebakeScriptButton.jsx';
|
import { exportScript, ImportPrebakeScriptButton } from './ImportPrebakeScriptButton.jsx';
|
||||||
import { useCallback, useEffect, useRef } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { Code } from '../Code.jsx';
|
import { Code } from '../Code.jsx';
|
||||||
import { DocumentArrowUpIcon, DocumentCheckIcon } from '@heroicons/react/16/solid';
|
|
||||||
|
|
||||||
function cx(...classes) {
|
function cx(...classes) {
|
||||||
// : Array<string | undefined>
|
// : Array<string | undefined>
|
||||||
|
|
|
||||||
91
website/src/repl/prebakeCodeMirror.mjs
Normal file
91
website/src/repl/prebakeCodeMirror.mjs
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { toggleLineComment } from '@codemirror/commands';
|
||||||
|
import { javascript, javascriptLanguage } from '@codemirror/lang-javascript';
|
||||||
|
import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
|
||||||
|
import { Compartment, EditorState, Prec } from '@codemirror/state';
|
||||||
|
import { drawSelection, EditorView, keymap } from '@codemirror/view';
|
||||||
|
import { logger } from '@strudel/core';
|
||||||
|
import { basicSetup, flash, prebakeField, initTheme, extensions } from '@strudel/codemirror';
|
||||||
|
|
||||||
|
export class PrebakeCodeMirror {
|
||||||
|
constructor(initialCode, storePrebake, containerRef, editorRef, settings) {
|
||||||
|
this.storePrebake = storePrebake;
|
||||||
|
const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()]));
|
||||||
|
const initialSettings = Object.keys(compartments).map((key) =>
|
||||||
|
compartments[key].of(extensions[key](parseBooleans(settings[key]))),
|
||||||
|
);
|
||||||
|
initTheme(settings.theme);
|
||||||
|
let state = EditorState.create({
|
||||||
|
doc: initialCode,
|
||||||
|
extensions: [
|
||||||
|
...initialSettings,
|
||||||
|
basicSetup,
|
||||||
|
javascript(),
|
||||||
|
javascriptLanguage.data.of({
|
||||||
|
closeBrackets: { brackets: ['(', '[', '{', "'", '"', '<'] },
|
||||||
|
bracketMatching: { brackets: ['(', '[', '{', "'", '"', '<'] },
|
||||||
|
}),
|
||||||
|
syntaxHighlighting(defaultHighlightStyle),
|
||||||
|
EditorView.updateListener.of((v) => {
|
||||||
|
if (v.docChanged) {
|
||||||
|
this.code = v.state.doc.toString();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
drawSelection({ cursorBlinkRate: 0 }),
|
||||||
|
Prec.highest(
|
||||||
|
keymap.of([
|
||||||
|
{
|
||||||
|
mac: 'Meta-Enter',
|
||||||
|
run: () => {
|
||||||
|
this.savePrebake();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Ctrl-Enter',
|
||||||
|
run: () => {
|
||||||
|
this.savePrebake();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Alt-Enter',
|
||||||
|
run: () => {
|
||||||
|
this.savePrebake();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
prebakeField,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
editorRef.current = state;
|
||||||
|
this.code = initialCode;
|
||||||
|
this.view = new EditorView({
|
||||||
|
state,
|
||||||
|
parent: containerRef.current,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async savePrebake() {
|
||||||
|
flash(this.view);
|
||||||
|
this.storePrebake(this.code);
|
||||||
|
logger('[prebake] prebake saved');
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleComment() {
|
||||||
|
try {
|
||||||
|
// Honor selections; toggleLineComment handles both selections and
|
||||||
|
// single line
|
||||||
|
toggleLineComment(this.view);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error handling repl-toggle-comment event', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCode(code) {
|
||||||
|
const changes = {
|
||||||
|
from: 0,
|
||||||
|
to: this.view.state.doc.length,
|
||||||
|
insert: code,
|
||||||
|
};
|
||||||
|
this.view.dispatch({ changes });
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue