diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 3384f79c..66e75083 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -1582,6 +1582,24 @@ export const range2 = register('range2', function (min, max, pat) { return pat.fromBipolar()._range(min, max); }); +/** + * Allows dividing numbers via list notation using ":". + * Returns a new pattern with just numbers. + * @name ratio + * @memberof Pattern + * @returns Pattern + * @example + * ratio("1, 5:4, 3:2").mul(110).freq().s("piano").slow(2) + */ +export const ratio = register('ratio', (pat) => + pat.fmap((v) => { + if (!Array.isArray(v)) { + return v; + } + return v.slice(1).reduce((acc, n) => acc / n, v[0]); + }), +); + ////////////////////////////////////////////////////////////////////// // Structural and temporal transformations diff --git a/packages/react/src/components/CodeMirror6.jsx b/packages/react/src/components/CodeMirror6.jsx index ebe3dd11..651c7c88 100644 --- a/packages/react/src/components/CodeMirror6.jsx +++ b/packages/react/src/components/CodeMirror6.jsx @@ -2,12 +2,12 @@ import React, { useMemo } from 'react'; import _CodeMirror from '@uiw/react-codemirror'; import { EditorView, Decoration } from '@codemirror/view'; import { StateField, StateEffect } from '@codemirror/state'; -import { javascript } from '@codemirror/lang-javascript'; +import { javascript, javascriptLanguage } from '@codemirror/lang-javascript'; import strudelTheme from '../themes/strudel-theme'; import './style.css'; import { useCallback } from 'react'; import { autocompletion } from '@codemirror/autocomplete'; -//import { strudelAutocomplete } from './Autocomplete'; +import { strudelAutocomplete } from './Autocomplete'; import { vim } from '@replit/codemirror-vim'; import { emacs } from '@replit/codemirror-emacs'; @@ -92,9 +92,7 @@ const staticExtensions = [ javascript(), highlightField, flashField, - // javascriptLanguage.data.of({ autocomplete: strudelAutocomplete }), - // autocompletion({ override: [strudelAutocomplete] }), - autocompletion({ override: [] }), // wait for https://github.com/uiwjs/react-codemirror/pull/458 + javascriptLanguage.data.of({ autocomplete: strudelAutocomplete }), ]; export default function CodeMirror({ @@ -105,6 +103,7 @@ export default function CodeMirror({ theme, keybindings, isLineNumbersDisplayed, + isAutoCompletionEnabled, fontSize = 18, fontFamily = 'monospace', options, @@ -116,12 +115,14 @@ export default function CodeMirror({ }, [onChange], ); + const handleOnCreateEditor = useCallback( (view) => { onViewChanged?.(view); }, [onViewChanged], ); + const handleOnUpdate = useCallback( (viewUpdate) => { if (viewUpdate.selectionSet && onSelectionChange) { @@ -130,16 +131,27 @@ export default function CodeMirror({ }, [onSelectionChange], ); + const extensions = useMemo(() => { + let _extensions = [...staticExtensions]; let bindings = { vim, emacs, }; + if (bindings[keybindings]) { - return [...staticExtensions, bindings[keybindings]()]; + _extensions.push(bindings[keybindings]()); } - return staticExtensions; - }, [keybindings]); + + if (isAutoCompletionEnabled) { + _extensions.push(javascriptLanguage.data.of({ autocomplete: strudelAutocomplete })); + } else { + _extensions.push(autocompletion({ override: [] })); + } + + return _extensions; + }, [keybindings, isAutoCompletionEnabled]); + return (
<_CodeMirror diff --git a/packages/react/src/components/style.css b/packages/react/src/components/style.css index 6d5d0805..d61c6619 100644 --- a/packages/react/src/components/style.css +++ b/packages/react/src/components/style.css @@ -24,3 +24,7 @@ .cm-theme-light { width: 100%; } + +footer { + z-index: 0 !important; +} diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index db375804..d452cabd 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -3193,6 +3193,23 @@ exports[`runs examples > example "rarely" example index 0 1`] = ` ] `; +exports[`runs examples > example "ratio" example index 0 1`] = ` +[ + "[ (0/1 → 1/1) ⇝ 2/1 | freq:110 s:piano ]", + "[ (0/1 → 1/1) ⇝ 2/1 | freq:137.5 s:piano ]", + "[ (0/1 → 1/1) ⇝ 2/1 | freq:165 s:piano ]", + "[ 0/1 ⇜ (1/1 → 2/1) | freq:110 s:piano ]", + "[ 0/1 ⇜ (1/1 → 2/1) | freq:137.5 s:piano ]", + "[ 0/1 ⇜ (1/1 → 2/1) | freq:165 s:piano ]", + "[ (2/1 → 3/1) ⇝ 4/1 | freq:110 s:piano ]", + "[ (2/1 → 3/1) ⇝ 4/1 | freq:137.5 s:piano ]", + "[ (2/1 → 3/1) ⇝ 4/1 | freq:165 s:piano ]", + "[ 2/1 ⇜ (3/1 → 4/1) | freq:110 s:piano ]", + "[ 2/1 ⇜ (3/1 → 4/1) | freq:137.5 s:piano ]", + "[ 2/1 ⇜ (3/1 → 4/1) | freq:165 s:piano ]", +] +`; + exports[`runs examples > example "release" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c3 release:0 ]", diff --git a/website/src/pages/functions/value-modifiers.mdx b/website/src/pages/functions/value-modifiers.mdx index 81874672..94372e75 100644 --- a/website/src/pages/functions/value-modifiers.mdx +++ b/website/src/pages/functions/value-modifiers.mdx @@ -139,6 +139,10 @@ This group of functions allows to modify the value of events. +## ratio + + + # Custom Parameters You can also create your own parameters: diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index c31e167a..30e2f3a1 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -364,7 +364,8 @@ const fontFamilyOptions = { }; function SettingsTab({ scheduler }) { - const { theme, keybindings, isLineNumbersDisplayed, fontSize, fontFamily } = useSettings(); + const { theme, keybindings, isLineNumbersDisplayed, isAutoCompletionEnabled, fontSize, fontFamily } = useSettings(); + return (
{/* @@ -406,7 +407,7 @@ function SettingsTab({ scheduler }) { />
-
+
settingsMap.setKey('isLineNumbersDisplayed', cbEvent.target.checked)} value={isLineNumbersDisplayed} /> + settingsMap.setKey('isAutoCompletionEnabled', cbEvent.target.checked)} + value={isAutoCompletionEnabled} + />