0.188.1: copy commands prefix task checkboxes + color/alias metadata; tight task-list copy

This commit is contained in:
GB 2026-07-19 20:45:04 -07:00
parent 5d8ef26dfc
commit b9bb5426fc
7 changed files with 82 additions and 11 deletions

13
main.js

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
{
"id": "stashpad",
"name": "Stashpad",
"version": "0.187.0",
"version": "0.188.1",
"minAppVersion": "1.13.0",
"description": "A chat-style, nested-notes workspace: rapid capture, outliner navigation, fast search, tasks, and per-folder templates, with one-click Open Knowledge Format (OKF) export for LLMs and agents.",
"author": "Human",

View file

@ -1,6 +1,6 @@
{
"name": "stashpad-obsidian",
"version": "0.187.0",
"version": "0.188.1",
"private": true,
"scripts": {
"dev": "node esbuild.config.mjs",

16
release-notes/0.188.0.md Normal file
View file

@ -0,0 +1,16 @@
# 0.188.0
## Copying
- **Copies now carry task checkboxes and colour metadata.** Copying notes — plain
**Copy**, **Copy tree** (indented list), or **Copy outline** (`![[embed]]` links) —
prefixes each note so it renders and round-trips in a regular Obsidian note:
- A task becomes a checkbox: `- [ ]` (incomplete) or `- [x]` (completed). The
leading dash is added so the checkbox renders, and the empty checkbox keeps its
inner space.
- A coloured note carries its colour inline: `[color: #ffe243 | alias: boogers]`
(the alias appears only when you've named that colour).
Put together: `- [x] [color: #ffe243 | alias: boogers] the note text`. On the
list/link formats the checkbox and metadata sit right after the bullet dash. Notes
that aren't tasks and have no colour copy exactly as before.

8
release-notes/0.188.1.md Normal file
View file

@ -0,0 +1,8 @@
# 0.188.1
## Copying
- **Copied task lists stay tight.** Plain **Copy** no longer puts a blank line
between every copied note — consecutive single-line items (like tasks) now join
with a single newline, so a copied checklist reads as one list. The blank-line
separator is kept only around a multi-line note, where the gap still helps.

View file

@ -19,9 +19,24 @@ export async function cmdCopy(view: StashpadView): Promise<void> {
if (!t.file) continue;
const raw = await view.app.vault.cachedRead(t.file);
const body = view.stripFrontmatter(raw).trim();
out.push(prefix ? `${view.formatTimeInline(t.created)} ${body}` : body);
// 0.188.0: task checkbox + color/alias metadata prefix. Plain-copy has no
// leading dash, so add one ("- ") ONLY for a task (a checkbox needs it to
// render); a colour-only prefix renders fine inline without a dash.
const { needsDash, checkbox, meta } = view.copyMetaPrefix(t);
const lead = `${needsDash ? "- " : ""}${checkbox}${meta}`;
const ts = prefix ? `${view.formatTimeInline(t.created)} ` : "";
out.push(`${lead}${ts}${body}`);
}
await navigator.clipboard.writeText(out.join("\n\n"));
// 0.188.1: join consecutive SINGLE-LINE items (tasks / short notes) with a
// single newline so a copied task list stays a tight checklist — the old blank
// line between every item split the checkboxes into a loose list. The blank-line
// separator is kept only around a multi-line item, where prose wants the gap.
let joined = out[0] ?? "";
for (let i = 1; i < out.length; i++) {
const gap = out[i - 1].includes("\n") || out[i].includes("\n") ? "\n\n" : "\n";
joined += gap + out[i];
}
await navigator.clipboard.writeText(joined);
view.plugin.notifications.show({
message: `Copied ${view.titleList(targets)} to clipboard`,
kind: "success",
@ -122,7 +137,10 @@ export async function cmdCopyTree(view: StashpadView): Promise<void> {
const raw = await view.app.vault.cachedRead(node.file);
const body = view.stripFrontmatter(raw).trim().split(/\r?\n/).join(" ");
const ts = prefix ? `${view.formatTimeInline(node.created)} ` : "";
lines.push(`${" ".repeat(depth)}- ${ts}${body}`);
// 0.188.0: checkbox + colour metadata go AFTER the bullet dash this format
// already emits (needsDash ignored — the "- " is always present here).
const { checkbox, meta } = view.copyMetaPrefix(node);
lines.push(`${" ".repeat(depth)}- ${checkbox}${meta}${ts}${body}`);
}
for (const c of view.tree.getChildren(node.id)) await walk(c, depth + 1);
};
@ -159,7 +177,9 @@ export async function cmdCopyOutline(view: StashpadView): Promise<void> {
const walk = (node: TreeNode, depth: number) => {
if (!node.file) return;
const indent = " ".repeat(depth);
lines.push(`${indent}- ![[${node.file.basename}]]`);
// 0.188.0: checkbox + colour metadata after the bullet dash, before the embed.
const { checkbox, meta } = view.copyMetaPrefix(node);
lines.push(`${indent}- ${checkbox}${meta}![[${node.file.basename}]]`);
for (const c of view.tree.getChildren(node.id)) walk(c, depth + 1);
};
for (const r of roots) walk(r, 0);

View file

@ -8221,6 +8221,30 @@ export class StashpadView extends ItemView {
cmdCopyTree(): Promise<void> { return clipboardCmds.cmdCopyTree(this); }
cmdCopyOutline(): Promise<void> { return clipboardCmds.cmdCopyOutline(this); }
/** 0.188.0: inline task/color metadata prefix for a COPIED note, so a task
* pastes as a real Obsidian checkbox and a note's color (+ its alias) survive
* as inline metadata in a plain note. Public so the clipboard commands can
* reuse the private task/color getters. Returns the pieces so each copy
* format places them correctly relative to its own leading dash:
* - `needsDash` true when the note is a task (a checkbox needs a "- " to
* render as a checkbox). Formats that ALREADY emit "- " ignore this.
* - `checkbox` "[ ] " (incomplete) / "[x] " (completed), or "".
* - `meta` "[color: #hex | alias: name] " (alias only when the color
* has one), or "".
* Compose as `<dash?><checkbox><meta><body>`; empty-checkbox keeps the space
* between brackets so Obsidian renders it. */
copyMetaPrefix(node: TreeNode): { needsDash: boolean; checkbox: string; meta: string } {
const task = this.isTask(node);
const checkbox = task ? (this.isCompleted(node) ? "[x] " : "[ ] ") : "";
const color = this.colorForNode(node);
let meta = "";
if (color) {
const alias = this.plugin.getColorAlias(this.noteFolder, color);
meta = alias ? `[color: ${color} | alias: ${alias}] ` : `[color: ${color}] `;
}
return { needsDash: task, checkbox, meta };
}
/** Toggle the "Show more / show less" clamp for the current target(s).
* Targets follow getActionTargets (selection > cursor row). Each
* target's id is added to or removed from this.expandedNotes; if any