Merge branch 'main' into daslyfe/gainmod

This commit is contained in:
daslyfe 2025-07-19 04:06:31 +02:00
commit 2d855cf5e8
6 changed files with 43 additions and 3 deletions

View file

@ -1,7 +1,7 @@
import { closeBrackets } from '@codemirror/autocomplete'; import { closeBrackets } from '@codemirror/autocomplete';
export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands'; export { toggleComment, toggleBlockComment, toggleLineComment, toggleBlockCommentByLine } from '@codemirror/commands';
// import { search, highlightSelectionMatches } from '@codemirror/search'; // import { search, highlightSelectionMatches } from '@codemirror/search';
import { history } from '@codemirror/commands'; import { history, indentWithTab } from '@codemirror/commands';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language'; import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from '@codemirror/language';
import { Compartment, EditorState, Prec } from '@codemirror/state'; import { Compartment, EditorState, Prec } from '@codemirror/state';
@ -37,6 +37,14 @@ const extensions = {
isActiveLineHighlighted: (on) => (on ? [highlightActiveLine(), highlightActiveLineGutter()] : []), isActiveLineHighlighted: (on) => (on ? [highlightActiveLine(), highlightActiveLineGutter()] : []),
isFlashEnabled, isFlashEnabled,
keybindings, keybindings,
isTabIndentationEnabled: (on) => (on ? keymap.of([indentWithTab]) : []),
isMultiCursorEnabled: (on) =>
on
? [
EditorState.allowMultipleSelections.of(true),
EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey),
]
: [],
}; };
const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()]));
@ -51,6 +59,8 @@ export const defaultSettings = {
isFlashEnabled: true, isFlashEnabled: true,
isTooltipEnabled: false, isTooltipEnabled: false,
isLineWrappingEnabled: false, isLineWrappingEnabled: false,
isTabIndentationEnabled: false,
isMultiCursorEnabled: false,
theme: 'strudelTheme', theme: 'strudelTheme',
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 18, fontSize: 18,

View file

@ -21,11 +21,11 @@ const vscodeExtension = (options) => [vscodePlugin].concat(options ?? []);
const keymaps = { const keymaps = {
vim, vim,
emacs, emacs,
codemirror: () => keymap.of(defaultKeymap),
vscode: vscodeExtension, vscode: vscodeExtension,
}; };
export function keybindings(name) { export function keybindings(name) {
const active = keymaps[name]; const active = keymaps[name];
return [keymap.of(defaultKeymap), keymap.of(historyKeymap), active ? active() : []]; return [active ? active() : [], keymap.of(historyKeymap)];
// keymap.of(searchKeymap),
} }

View file

@ -42,6 +42,7 @@ lib['%'] = pace;
lib['?'] = degradeBy; // todo: default 0.5 not working.. lib['?'] = degradeBy; // todo: default 0.5 not working..
lib[':'] = tail; lib[':'] = tail;
lib['..'] = range; lib['..'] = range;
lib['def'] = () => silence;
lib['or'] = (...children) => chooseIn(...children); // always has structure but is cyclewise.. e.g. "s oh*8.dec[.04 | .5]" lib['or'] = (...children) => chooseIn(...children); // always has structure but is cyclewise.. e.g. "s oh*8.dec[.04 | .5]"
//lib['or'] = (...children) => chooseOut(...children); // "s oh*8.dec[.04 | .5]" is better but "dec[.04 | .5].s oh*8" has no struct //lib['or'] = (...children) => chooseOut(...children); // "s oh*8.dec[.04 | .5]" is better but "dec[.04 | .5].s oh*8" has no struct

View file

@ -176,3 +176,16 @@ $ chord <Dm9!3 Db7> # voicing
/> />
The `$` sign is an alias for `,` so it will create a stack behind the scenes. The `$` sign is an alias for `,` so it will create a stack behind the scenes.
## variables
using the `def` keyword, you can define variables:
<MiniRepl
client:idle
mondo
tune={`
$ def melody [0 1 2 3]
$ n melody # scale C:minor
`}
/>

View file

@ -109,6 +109,8 @@ export function SettingsTab({ started }) {
togglePanelTrigger, togglePanelTrigger,
maxPolyphony, maxPolyphony,
multiChannelOrbits, multiChannelOrbits,
isTabIndentationEnabled,
isMultiCursorEnabled,
} = useSettings(); } = useSettings();
const shouldAlwaysSync = isUdels(); const shouldAlwaysSync = isUdels();
const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; const canChangeAudioDevice = AudioContext.prototype.setSinkId != null;
@ -262,6 +264,16 @@ export function SettingsTab({ started }) {
onChange={(cbEvent) => settingsMap.setKey('isLineWrappingEnabled', cbEvent.target.checked)} onChange={(cbEvent) => settingsMap.setKey('isLineWrappingEnabled', cbEvent.target.checked)}
value={isLineWrappingEnabled} value={isLineWrappingEnabled}
/> />
<Checkbox
label="Enable Tab indentation"
onChange={(cbEvent) => settingsMap.setKey('isTabIndentationEnabled', cbEvent.target.checked)}
value={isTabIndentationEnabled}
/>
<Checkbox
label="Enable Multi-Cursor (Cmd/Ctrl+Click)"
onChange={(cbEvent) => settingsMap.setKey('isMultiCursorEnabled', cbEvent.target.checked)}
value={isMultiCursorEnabled}
/>
<Checkbox <Checkbox
label="Enable flashing on evaluation" label="Enable flashing on evaluation"
onChange={(cbEvent) => settingsMap.setKey('isFlashEnabled', cbEvent.target.checked)} onChange={(cbEvent) => settingsMap.setKey('isFlashEnabled', cbEvent.target.checked)}

View file

@ -21,6 +21,8 @@ export const defaultSettings = {
isSyncEnabled: false, isSyncEnabled: false,
isLineWrappingEnabled: false, isLineWrappingEnabled: false,
isPatternHighlightingEnabled: true, isPatternHighlightingEnabled: true,
isTabIndentationEnabled: false,
isMultiCursorEnabled: false,
theme: 'strudelTheme', theme: 'strudelTheme',
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 18, fontSize: 18,
@ -77,6 +79,8 @@ export function useSettings() {
isLineWrappingEnabled: parseBoolean(state.isLineWrappingEnabled), isLineWrappingEnabled: parseBoolean(state.isLineWrappingEnabled),
isFlashEnabled: parseBoolean(state.isFlashEnabled), isFlashEnabled: parseBoolean(state.isFlashEnabled),
isSyncEnabled: isUdels() ? true : parseBoolean(state.isSyncEnabled), isSyncEnabled: isUdels() ? true : parseBoolean(state.isSyncEnabled),
isTabIndentationEnabled: parseBoolean(state.isTabIndentationEnabled),
isMultiCursorEnabled: parseBoolean(state.isMultiCursorEnabled),
fontSize: Number(state.fontSize), fontSize: Number(state.fontSize),
panelPosition: state.activeFooter !== '' && !isUdels() ? state.panelPosition : 'bottom', // <-- keep this 'bottom' where it is! panelPosition: state.activeFooter !== '' && !isUdels() ? state.panelPosition : 'bottom', // <-- keep this 'bottom' where it is!
isPanelPinned: parseBoolean(state.isPanelPinned), isPanelPinned: parseBoolean(state.isPanelPinned),