Here’s a space script I’ve been using recently to move tasks from one note to another:
async function refile(targetPage, targetHeading) {
try {
const cursorPos = await syscall("editor.getCursor");
const text = await syscall("editor.getText");
const currentItemBounds = await syscall("system.invokeFunction", "editor.determineItemBounds", text, cursorPos, undefined, true);
const currentItemText = text.slice(currentItemBounds.from, currentItemBounds.to);
const targetContent = await syscall("space.readPage", targetPage);
const headingRegex = new RegExp(`^#+\\s${targetHeading}`, 'm');
const headingMatch = targetContent.match(headingRegex);
if (!headingMatch) {
throw new Error("Heading not found.");
}
const headingIndex = headingMatch.index + headingMatch[0].length;
let insertPosition = targetContent.indexOf("\n", headingIndex);
if (insertPosition === -1) {
insertPosition = headingIndex;
} else {
insertPosition += 1;
}
const listEndRegex = /^[^\s(-|\*)]/gm;
let listEndMatch = listEndRegex.exec(targetContent.slice(insertPosition));
listEndMatch = listEndMatch ? insertPosition + listEndMatch.index : targetContent.length;
// Remove any extra new lines between items
const cleanedTargetContent = targetContent.slice(0, listEndMatch).replace(/\n{2,}/g, '\n') + `${currentItemText}\n` + targetContent.slice(listEndMatch);
await syscall("space.writePage", targetPage, cleanedTargetContent);
await syscall("editor.replaceRange", currentItemBounds.from, currentItemBounds.to, "");
await syscall("editor.flashNotification", "Item refiled successfully.");
} catch (error) {
await syscall("editor.flashNotification", error.message, "error");
}
}
Most of my tasks lately are going into a simple TODOs
file with headings of Personal, Work, etc. So I have these commands to easily move tasks to one of these headings:
silverbullet.registerCommand({name: "refile-todos-personal"}, async () => {
const targetPage = "TODOs";
const targetHeading = "Personal";
await refile(targetPage, targetHeading);
});
silverbullet.registerCommand({name: "refile-todos-work"}, async () => {
const targetPage = "TODOs";
const targetHeading = "Work";
await refile(targetPage, targetHeading);
});
Keep in mind this does not work very well when moving tasks on the same page you’re currently editing. The targets are also hardcoded for now, but I don’t think it should be too hard to make a generic ‘refile’ command that opens up a filterbox to select a target page and header to move an item to.