diff --git a/src/components/editor/util/Commands.ts b/src/components/editor/util/Commands.ts index d8390412f..fc6c8e815 100644 --- a/src/components/editor/util/Commands.ts +++ b/src/components/editor/util/Commands.ts @@ -262,7 +262,7 @@ export const StepForwardInput: Command = { }; export const StepBackNode: Command = { - symbol: '⏴', + symbol: '•←', description: (l) => l.ui.timeline.button.backNode, visible: Visibility.Visible, category: Category.Evaluate, @@ -271,15 +271,15 @@ export const StepBackNode: Command = { control: true, key: 'ArrowLeft', keySymbol: '←', - active: ({ caret }) => caret?.isNode() ?? false, - execute: (context) => - context.caret?.position instanceof Node - ? context.evaluator.stepBackToNode(context.caret.position) - : undefined, + active: ({ caret }) => caret !== undefined, + execute: ({ caret, evaluator }) => { + const target = caret?.getExpressionAt(); + if (target) evaluator.stepBackToNode(target); + }, }; export const StepForwardNode: Command = { - symbol: '⏵', + symbol: '⇢•', description: (l) => l.ui.timeline.button.forwardNode, visible: Visibility.Visible, category: Category.Evaluate, @@ -288,11 +288,11 @@ export const StepForwardNode: Command = { shift: true, alt: true, control: true, - active: (context) => context.caret?.isNode() ?? false, - execute: (context) => - context.caret?.position instanceof Node - ? context.evaluator.stepToNode(context.caret.position) - : undefined, + active: ({ caret }) => caret !== undefined, + execute: ({ caret, evaluator }) => { + const target = caret?.getExpressionAt(); + if (target) evaluator.stepToNode(target); + }, }; export const Restart: Command = { diff --git a/src/components/project/ProjectView.svelte b/src/components/project/ProjectView.svelte index 58c8d69b4..fda856887 100644 --- a/src/components/project/ProjectView.svelte +++ b/src/components/project/ProjectView.svelte @@ -1036,7 +1036,7 @@ caret: layout.isFullscreenNonSource() ? undefined : Array.from($editors.values()).find((editor) => editor.focused) - ?.caret, + ?.caret ?? Array.from($editors.values())[0]?.caret, project, /** We intentionally depend on the evaluation store because it updates when the evaluator's state changes */ evaluator: $evaluation.evaluator, @@ -1048,6 +1048,11 @@ toggleBlocks, help: () => (showHelpDialog = !showHelpDialog), }; + + $: console.log( + Array.from($editors.values()).find((editor) => editor.focused)?.caret + ); + const commandContextStore = writable(commandContext); $: commandContextStore.set(commandContext); setContext(ProjectCommandContextSymbol, commandContextStore); diff --git a/src/edit/Caret.ts b/src/edit/Caret.ts index 726bb0ee4..6bc3b6c79 100644 --- a/src/edit/Caret.ts +++ b/src/edit/Caret.ts @@ -104,6 +104,17 @@ export default class Caret { : undefined; } + getExpressionAt() { + const start = + this.position instanceof Node + ? this.position + : this.tokenExcludingSpace; + if (start === undefined) return undefined; + return this.source.root + .getAncestors(start) + .find((n): n is Expression => n instanceof Expression); + } + getNodeInside() { return typeof this.position === 'number' ? this.insideToken() diff --git a/src/locale/en-US.json b/src/locale/en-US.json index 648734c26..4da27a4e2 100644 --- a/src/locale/en-US.json +++ b/src/locale/en-US.json @@ -3903,11 +3903,11 @@ "play": "evaluate the program to the end, responding to inputs in real time", "pause": "pause the program, enabling stepping forward and backwards", "backStep": "step back one", - "backNode": "step back to previous node evaluation", + "backNode": "step to previous evaluation of cursor", "backInput": "back one input", "out": "step out of this function", "forwardStep": "step forward one", - "forwardNode": "step forward to next node evaluation", + "forwardNode": "step to next evaluation of cursor", "forwardInput": "step forward to next stream input", "present": "to the end", "start": "to the beginning",