mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-29 08:01:50 -04:00
Compare commits
8 Commits
name
...
soloshortcut
| Author | SHA1 | Date | |
|---|---|---|---|
| 90c05ec38a | |||
| 7e0eed87cb | |||
| 1a1197f67a | |||
| 3c5afb32f3 | |||
| 76cbd23859 | |||
| b436ae789c | |||
| 275731afc7 | |||
| 5cb2214d88 |
@@ -24,7 +24,12 @@ import { sliderPlugin, updateSliderWidgets } from './slider.mjs';
|
|||||||
import { activateTheme, initTheme, theme } from './themes.mjs';
|
import { activateTheme, initTheme, theme } from './themes.mjs';
|
||||||
import { isTooltipEnabled } from './tooltip.mjs';
|
import { isTooltipEnabled } from './tooltip.mjs';
|
||||||
import { updateWidgets, widgetPlugin } from './widget.mjs';
|
import { updateWidgets, widgetPlugin } from './widget.mjs';
|
||||||
import { jumpToCharacter } from './labelJump.mjs';
|
import {
|
||||||
|
deleteAllInlineBeforeCharacter,
|
||||||
|
InsertCharBeforeChar,
|
||||||
|
jumpToCharacter,
|
||||||
|
jumpToNextCharacter,
|
||||||
|
} from './labelJump.mjs';
|
||||||
|
|
||||||
export { toggleBlockComment, toggleBlockCommentByLine, toggleComment, toggleLineComment } from '@codemirror/commands';
|
export { toggleBlockComment, toggleBlockCommentByLine, toggleComment, toggleLineComment } from '@codemirror/commands';
|
||||||
|
|
||||||
@@ -74,6 +79,10 @@ export const codemirrorSettings = persistentAtom('codemirror-settings', defaultS
|
|||||||
decode: JSON.parse,
|
decode: JSON.parse,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ANON_LABEL = '$';
|
||||||
|
const SOLO_LABEL = 'S';
|
||||||
|
const MUTE_LABEL = '_';
|
||||||
|
|
||||||
// https://codemirror.net/docs/guide/
|
// https://codemirror.net/docs/guide/
|
||||||
export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, root, mondo }) {
|
export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, root, mondo }) {
|
||||||
const settings = codemirrorSettings.get();
|
const settings = codemirrorSettings.get();
|
||||||
@@ -122,12 +131,75 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'Alt-w',
|
key: 'Alt-w',
|
||||||
run: (view) => jumpToCharacter(view, '$', 1),
|
run: (view) => jumpToNextCharacter(view, ANON_LABEL, 1),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'Alt-q',
|
key: 'Alt-q',
|
||||||
run: (view) => jumpToCharacter(view, '$', -1),
|
run: (view) => {
|
||||||
|
return jumpToNextCharacter(view, ANON_LABEL, -1);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
// clear all muted
|
||||||
|
{
|
||||||
|
key: `Alt-Ctrl-0`,
|
||||||
|
run: (view) => {
|
||||||
|
return deleteAllInlineBeforeCharacter(view, MUTE_LABEL + ANON_LABEL);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// clear all solod
|
||||||
|
{
|
||||||
|
key: `Alt-Shift-0`,
|
||||||
|
run: (view) => {
|
||||||
|
return deleteAllInlineBeforeCharacter(view, SOLO_LABEL + ANON_LABEL);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// clear all solo and mute
|
||||||
|
{
|
||||||
|
key: `Ctrl-Shift-0`,
|
||||||
|
run: (view) => {
|
||||||
|
return deleteAllInlineBeforeCharacter(view, ANON_LABEL);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...Array.from({ length: 9 }).map((_, i) => {
|
||||||
|
let num = i + 1;
|
||||||
|
return {
|
||||||
|
key: `Alt-${num}`,
|
||||||
|
run: (view) => {
|
||||||
|
return jumpToCharacter(view, ANON_LABEL, i);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
// handle solo toggles 1-9
|
||||||
|
...Array.from({ length: 9 }).map((_, i) => {
|
||||||
|
let num = i + 1;
|
||||||
|
return {
|
||||||
|
key: `Alt-Shift-${num}`,
|
||||||
|
run: (view) => {
|
||||||
|
return InsertCharBeforeChar(view, ANON_LABEL, SOLO_LABEL, i);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
// handle mute toggles 1-9
|
||||||
|
...Array.from({ length: 9 }).map((_, i) => {
|
||||||
|
let num = i + 1;
|
||||||
|
return {
|
||||||
|
key: `Alt-Ctrl-${num}`,
|
||||||
|
run: (view) => {
|
||||||
|
return InsertCharBeforeChar(view, ANON_LABEL, MUTE_LABEL, i);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
// Handle clearing mutes and solos 1-9
|
||||||
|
...Array.from({ length: 9 }).map((_, i) => {
|
||||||
|
let num = i + 1;
|
||||||
|
return {
|
||||||
|
key: `Ctrl-Shift-${num}`,
|
||||||
|
run: (view) => {
|
||||||
|
return InsertCharBeforeChar(view, ANON_LABEL,'', i);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
/* {
|
/* {
|
||||||
key: 'Ctrl-Shift-.',
|
key: 'Ctrl-Shift-.',
|
||||||
run: () => (onPanic ? onPanic() : onStop?.()),
|
run: () => (onPanic ? onPanic() : onStop?.()),
|
||||||
|
|||||||
@@ -1,18 +1,54 @@
|
|||||||
import { EditorSelection } from '@codemirror/state';
|
import { EditorSelection } from '@codemirror/state';
|
||||||
import { SearchCursor } from '@codemirror/search';
|
import { SearchCursor } from '@codemirror/search';
|
||||||
|
import { EditorView } from '@codemirror/view';
|
||||||
|
import { syntaxTree } from '@codemirror/language';
|
||||||
|
|
||||||
export function jumpToCharacter(view, character, direction = 1) {
|
/**
|
||||||
|
* gets all of the positions of a character in a document, excluding commented out lines
|
||||||
|
* @param { EditorState} state
|
||||||
|
* @param {String} character
|
||||||
|
* @returns {number[]}
|
||||||
|
*/
|
||||||
|
function getCharacterPositions(state, character) {
|
||||||
|
const cursor = new SearchCursor(state.doc, character);
|
||||||
|
|
||||||
|
const characterPositions = [];
|
||||||
|
while (!cursor.next().done) {
|
||||||
|
|
||||||
|
const linestartpos = state.doc.lineAt(cursor.value.to).from
|
||||||
|
if (!isLineCommentedOut(state, linestartpos)) {
|
||||||
|
|
||||||
|
characterPositions.push(cursor.value.to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return characterPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLineCommentedOut(state, pos) {
|
||||||
|
|
||||||
|
const line = state.doc.lineAt(pos);
|
||||||
|
// remove white space
|
||||||
|
pos = line.from + line.text.search(/\S/)
|
||||||
|
|
||||||
|
const tree = syntaxTree(state);
|
||||||
|
const node = tree.resolveInner(pos, 1)
|
||||||
|
return node.name.includes("Comment")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jump to the next character in a document
|
||||||
|
* @param {EditorView} view
|
||||||
|
* @param {String} character
|
||||||
|
* @param {number} direction 0 or 1
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export function jumpToNextCharacter(view, character, direction = 1) {
|
||||||
const { state, dispatch } = view;
|
const { state, dispatch } = view;
|
||||||
const pos = state.selection.main.head;
|
const pos = state.selection.main.head;
|
||||||
const cursor = new SearchCursor(state.doc, character);
|
|
||||||
|
|
||||||
let characterPositions = [];
|
|
||||||
let jumpPos;
|
let jumpPos;
|
||||||
while (!cursor.next().done) {
|
const characterPositions = getCharacterPositions(state, character);
|
||||||
characterPositions.push(cursor.value.to);
|
|
||||||
}
|
|
||||||
if (!characterPositions.length) {
|
if (!characterPositions.length) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
if (direction > 0) {
|
if (direction > 0) {
|
||||||
jumpPos = characterPositions.find((x) => x > pos + 1) ?? characterPositions.at(0); // Loop back around for convenience
|
jumpPos = characterPositions.find((x) => x > pos + 1) ?? characterPositions.at(0); // Loop back around for convenience
|
||||||
@@ -21,11 +57,97 @@ export function jumpToCharacter(view, character, direction = 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (jumpPos == null) {
|
if (jumpPos == null) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
const selection = EditorSelection.cursor(jumpPos - 1);
|
||||||
dispatch({
|
dispatch({
|
||||||
selection: EditorSelection.cursor(jumpPos - 1),
|
selection,
|
||||||
scrollIntoView: true,
|
effects: EditorView.scrollIntoView(
|
||||||
|
selection.head,
|
||||||
|
{ y: "start" }
|
||||||
|
)
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {EditorView} view
|
||||||
|
* @param {String} character
|
||||||
|
* @param {number} index the instance of the character
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function jumpToCharacter(view, character, index) {
|
||||||
|
const { state, dispatch } = view;
|
||||||
|
const characterPositions = getCharacterPositions(state, character);
|
||||||
|
const pos = characterPositions.at(index) ?? characterPositions.at(-1);
|
||||||
|
if (pos == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selection = EditorSelection.cursor(pos - 1);
|
||||||
|
dispatch({
|
||||||
|
selection,
|
||||||
|
effects: EditorView.scrollIntoView(
|
||||||
|
selection.head,
|
||||||
|
{ y: "start" }
|
||||||
|
)
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {EditorView} view
|
||||||
|
* @param {String} character
|
||||||
|
* @returns {true}
|
||||||
|
*/
|
||||||
|
export function deleteAllInlineBeforeCharacter(view, character) {
|
||||||
|
const { state, dispatch } = view;
|
||||||
|
const characterPositions = getCharacterPositions(state, character);
|
||||||
|
|
||||||
|
const changes = [];
|
||||||
|
characterPositions.forEach((pos) => {
|
||||||
|
const line = state.doc.lineAt(pos);
|
||||||
|
if (state.doc.sliceString(line.from, line.from + 2) === COMMENT_STRING) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
changes.push({
|
||||||
|
from: line.from,
|
||||||
|
to: pos - 1,
|
||||||
|
insert: '',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
dispatch({ changes });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {EditorView} view
|
||||||
|
* @param {String} character
|
||||||
|
* @param {String} character2
|
||||||
|
* @param {number} index
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function InsertCharBeforeChar(view, character, character2, index) {
|
||||||
|
const { state, dispatch } = view;
|
||||||
|
|
||||||
|
const changes = [];
|
||||||
|
const characterPositions = getCharacterPositions(state, character);
|
||||||
|
const labelpos = characterPositions.at(index) ?? characterPositions.at(-1);
|
||||||
|
const line = state.doc.lineAt(labelpos);
|
||||||
|
|
||||||
|
//delete preceeding characters
|
||||||
|
changes.push({
|
||||||
|
from: line.from,
|
||||||
|
to: labelpos - 1,
|
||||||
|
insert: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
changes.push({
|
||||||
|
insert: character2,
|
||||||
|
from: line.from,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({ changes });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user