feat: Add playback commands

The new commands can be bound to hotkeys.
Also includes minor naming corrections.
This commit is contained in:
Anton Duda 2025-10-26 21:58:06 +03:00
parent 803422a4e9
commit ef35cafca1
4 changed files with 53 additions and 20 deletions

View file

@ -122,7 +122,7 @@ const buildStrudelDecorations = (state: EditorState): DecorationSet => {
continue
}
const codePosFrom = state.doc.lineAt(block.from).to + 1
const codeFrom = state.doc.lineAt(block.from).to + 1
const existingBlock = GlobalStore.getInstance().strudelBlocks.value.find(
(t) => t.id === block.id
@ -130,8 +130,9 @@ const buildStrudelDecorations = (state: EditorState): DecorationSet => {
if (existingBlock) {
existingBlock.code = code
existingBlock.posFrom = block.from
existingBlock.codePosFrom = codePosFrom
existingBlock.from = block.from
existingBlock.to = block.to
existingBlock.codeFrom = codeFrom
}
const widget = new StrudelHeaderWidget(
@ -140,23 +141,22 @@ const buildStrudelDecorations = (state: EditorState): DecorationSet => {
id: block.id,
code,
filePath: currentFile.path,
posFrom: block.from,
codePosFrom,
from: block.from,
to: block.to,
codeFrom,
})
)
widgets.push(widget)
}
widgets.sort((a, b) => a.getBlock().posFrom - b.getBlock().posFrom)
console.log('Building Strudel decorations for widgets:', widgets.length)
widgets.sort((a, b) => a.getBlock().from - b.getBlock().from)
for (const widget of widgets) {
// add widget at the start of the code block
builder.add(
widget.getBlock().posFrom,
widget.getBlock().posFrom,
widget.getBlock().from,
widget.getBlock().from,
Decoration.widget({
widget,
block: true,

View file

@ -2,10 +2,11 @@ export class Strudel {
public id: string
public code: string
public filePath: string
public posFrom: number
public from: number
public to: number
// posFrom now points to the beginning of the code block (```strudel)
// This property returns the position where the actual code starts
public codePosFrom: number
public codeFrom: number
public drawContext: CanvasRenderingContext2D | null = null
private shown = true
@ -14,14 +15,16 @@ export class Strudel {
id: string
code: string
filePath: string
posFrom: number
codePosFrom: number
from: number
to: number
codeFrom: number
}) {
this.id = data.id
this.code = data.code
this.filePath = data.filePath
this.posFrom = data.posFrom
this.codePosFrom = data.codePosFrom
this.from = data.from
this.to = data.to
this.codeFrom = data.codeFrom
}
setDrawContext(ctx: CanvasRenderingContext2D) {

View file

@ -1,4 +1,4 @@
import { App, Plugin, PluginSettingTab, Setting } from 'obsidian'
import { App, Editor, Plugin, PluginSettingTab, Setting } from 'obsidian'
import './styles.css'
import { GlobalStore } from './stores/GlobalStore'
import { createApp, App as VueApp } from 'vue'
@ -50,6 +50,24 @@ export default class StrudelPlugin extends Plugin {
GlobalStore.getInstance().initStrudel()
this.addCommand({
id: 'play',
name: 'Play strudel block at cursor',
editorCallback: (editor: Editor) => {
const cursor = editor.getCursor()
GlobalStore.getInstance().playAt(editor.posToOffset(cursor))
},
})
this.addCommand({
id: 'stop',
name: 'Stop playback',
callback: () => {
GlobalStore.getInstance().stop()
},
})
// this.addCommand({
// id: 'create-strudel-block',
// name: 'Create new strudel block',

View file

@ -16,7 +16,6 @@ export class GlobalStore {
public readonly strudelInitialized = ref(false)
public readonly initialized = ref(false)
public readonly currentFile = ref(null)
public readonly strudelBlocks = ref<Strudel[]>([])
@ -55,6 +54,20 @@ export class GlobalStore {
this.isPlaying.value = true
}
public playAt(position: number) {
const currentFile = this.app.workspace.getActiveViewOfType(MarkdownView)?.file
if (!currentFile) return
const strudelBlock = this.strudelBlocks.value.find((block) => {
return block.filePath === currentFile.path && position >= block.from && position <= block.to
}) as Strudel | undefined
if (strudelBlock) {
this.play(strudelBlock)
}
}
public stop() {
this.repl.stop()
this.isPlaying.value = false
@ -69,7 +82,7 @@ export class GlobalStore {
const locations = options.meta.miniLocations
const editor = this.getActiveEditor()
if (this.currentBlock.value && editor) {
updateMiniLocations(editor, locations || [], this.currentBlock.value.codePosFrom)
updateMiniLocations(editor, locations || [], this.currentBlock.value.codeFrom)
}
}
@ -150,7 +163,6 @@ export class GlobalStore {
}
this.initialized.value = false
this.currentFile.value = null
this.strudelBlocks.value.splice(0, this.strudelBlocks.value.length)
}
}