Hoist

by Michael
5
4
3
2
1
Score: 50/100

Description

Hoist values from a list item's children into its parent to create viewable summaries when folded.

Reviews

No reviews yet.

Stats

0
stars
65
downloads
0
forks
41
days
41
days
41
days
0
total PRs
0
open PRs
0
closed PRs
0
merged PRs
0
total issues
0
open issues
0
closed issues
5
commits

Latest Version

a month ago

Changelog

Initial release.

Added

  • Inline summaries in the editor (Live Preview) — the resolved summary replaces a parent item's {placeholder} template on every line except the one the cursor is on. On by default.
  • Fold-aware summaries in Reading view — expanded shows the faint template; collapsed shows the resolved values.
  • Dot-notation placeholders — reference nested child values like {storage.internal.ssd}. Bare keys ({ssd}) match the first occurrence anywhere, and paths can skip intermediate levels ({ram.slot2} finds slot2 even under a ram-slots group).
  • Templates at any level — any list item with children can summarize its own subtree.
  • Plain containers — intermediate bullets don't need :: to be traversable.

Settings

  • Inline summary in editor (Live Preview) — default on.
  • Maximum nesting depth — 10–50 (default 10).
  • Match keys anywhere (bare keys & partial paths) — default on; strict full-path mode when off.
  • Hide empty placeholders — default off; drops empty placeholders and tidies spacing.
  • Optional segments [ … ] — default off; a bracketed chunk shows only if every placeholder inside it resolves.

README file from

Github

Obsidian is great at outlining, but a folded bullet tells you nothing about what's inside it. This plugin lets a parent item carry a small template that pulls values from its child bullets, so the collapsed line becomes a readable summary instead of just a name.

- Mac Mini {cpu} — {ram} / {disk}
    - cpu:: Intel i5
    - ram:: 4gb
    - disk:: 256gb
  • Folded: Mac Mini Intel i5 — 4gb / 256gb
  • Expanded: Mac Mini {cpu} — {ram} / {disk} (template shown faint, so you can still edit it)

The values live in the outline as ordinary nested bullets. The summary is computed from them and rendered on the item's own line — nowhere else.


Why this exists

Structured detail and a scannable overview usually pull in opposite directions. You either keep the details visible (and drown in them) or fold them away (and lose the at-a-glance facts). Spec sheets, inventories, character sheets, config notes, gear lists, comparison tables-as-outlines — all have this shape: a thing, with attributes, that you want to skim collapsed and inspect expanded.

This plugin closes that gap without changing how you write. You keep one plain outline; the parent line just gains a computed view of its own children.

Key properties that make it useful in practice:

  • The data is the outline. No frontmatter, no separate metadata block, no query pane. Child bullets are the source of truth.
  • It works while you write. The inline summary shows in the Live Preview editor by default, and gets out of the way (showing the raw template) on the line your cursor is on.
  • It's fold-aware in Reading view. The resolved summary appears on collapse and reverts to the template on expand.
  • It reads deep. Placeholders are dot-paths that can skip intervening levels: {ram.slot2} finds slot2 even if it sits under a ram-slots group. Bare keys ({slot2}) match the first one anywhere. Up to 50 levels deep.
  • Templates work at any level. Not just the top item — any node with children can summarize its own subtree.

How it compares to what Obsidian already offers

Several existing features and plugins touch parts of this, but none combine "computed from child bullets" + "rendered on the item's own line" + "surfaced inline / on fold." Here's where each stops.

Tool What it does well Why it doesn't cover this
Native list folding Cleanly hides/reveals children A folded line shows only its own text — there's no concept of a summary
Dataview (queries) Powerful querying of fields across your vault Output is a separate TABLE/LIST block, not painted back onto your outline line
Dataview (inline = …) Renders a computed value inline in text Resolves page/frontmatter fields (this.…), not a specific bullet's own child bullets with path lookup; inline fields inside lists also have known rendering issues
Better Inline Fields / Key-Value List Nicer display of key:: value items Styling only — no rollup, no path lookup
Fold plugins (Smart Fold, List Fold, Outline Level Fold) More control over how things fold They move fold state around; they don't compute or display anything
Tag Summary Collects tagged lines into an aggregated block A separate collected view, not an in-place summary on the parent line

The through-line: existing tools either query into a separate view (Dataview, Tag Summary), style what's already there (inline-field plugins), or control folding (fold plugins). None render a value derived from an item's own descendants back onto that item's line.

Why the gap exists

This is less an oversight than a consequence of Obsidian's data model. Obsidian stores structure as markdown text plus page-level frontmatter; per-node attributes on an individual list item aren't a first-class concept. Outliner-first tools built around a node-with-attributes model — Logseq (block properties) and Tana (fields on nodes) — do "show a computed rollup on a node" natively, because it's baked into how they represent data.

This plugin brings a thin slice of that behavior to Obsidian's outline: attributes as child bullets, a rollup as a template, surfaced inline as you write and on the line when you fold.


Syntax

- Mac Mini {cpu} - {ram}/{disk}
    - ram:: 4gb
    - disk:: 256gb
    - cpu:: i7
  • Parent line: a template using {path} placeholders. Any surrounding text (Mac Mini, -, /) is kept literally.
  • Children: key:: value (double colon, same as Dataview inline fields). The value is optional, so storage:: can be a container for deeper items.
  • Matching is case-insensitive. A {path} that doesn't resolve is left as-is.

Nested values & dot-notation

Children can nest up to the Maximum nesting depth setting (default 10). Reference nested values with dotted paths:

- mac mini {ram.slot1} + {ram.slot2} / {storage.internal.ssd}
    - ram::
        - slot1:: 2gb
        - slot2:: 2gb
    - storage::
        - internal::
            - ssd:: 128 gb

mac mini 2gb + 2gb / 128 gb

Resolution rules (when Match keys anywhere is on, the default):

  • {ssd} — a bare key matches the first ssd at any depth, in document order.
  • {ram.slot2} — each dot segment is a descendant search, so intermediate generations can be skipped. If slot2 sits under ram > ram-slots, {ram.slot2} still finds it. Direct children win over deeper ones (shallowest-first).
  • {internal.ssd} — partial paths work too (it anchors anywhere and backtracks).
  • Use a bare key when it's unique; add leading path to point at a later/duplicate one.

Turn Match keys anywhere off for strict mode: every placeholder must be a full literal path from a top-level key with every generation named and direct-child descent ({ram.ram-slots.slot2}); bare keys, partial paths, and generation-skipping won't resolve. Precise and unambiguous — best for notes you edit a lot, since it can't silently repoint.

Templates on any level

A template isn't limited to the top item — any node with children can carry one and resolves against its own subtree. So you can fold at any level:

- Mac Mini {cpu} — RAM {ram.slot1}+{ram.slot2}
    - cpu:: M2
    - ram {slot1} + {slot2}
        - slot1:: 8gb
        - slot2:: 8gb

Folding ram shows ram 8gb + 8gb; folding Mac Mini shows Mac Mini M2 — RAM 8gb+8gb.

Containers don't need ::

An intermediate node can be a plain item (no ::) and still be traversed, so these are equivalent:

- ram:: 16gb              - ram:: 16gb
    - specs::                 - specs
        - type:: DDR5             - type:: DDR5

Only the leaves you actually reference need a value.

Views

Editor (Live Preview) — on by default

In Live Preview, the resolved summary replaces the template inline — except on the line your cursor is on, which shows raw source so you can edit it. This is "always on" (not tied to folding), which keeps it robust. It does not run in Source mode. Turn it off in settings to leave the editor untouched.

Reading view

  • Expanded: the parent shows the template in faint grey — {cpu} - {ram}/{disk}.
  • Collapsed: the parent shows resolved values as normal text — i7 - 4gb/256gb.

Settings

  • Inline summary in editor (Live Preview) — on by default. Off leaves the editor untouched (Reading view still works).
  • Maximum nesting depth — 10–50 in steps of 10 (default 10). Reopen a note after changing it for Reading view to pick up the new depth.
  • Match keys anywhere (bare keys & partial paths) — on by default; strict full-path mode when off (see "Nested values & dot-notation").

Install (manual)

  1. Copy this folder to <your vault>/.obsidian/plugins/outline-hoist/. It must contain manifest.json, main.js, and styles.css.
  2. In Obsidian: Settings → Community plugins → enable Hoist!. (Turn off Restricted/Safe mode if prompted.)
  3. Open sample-test-note.md. You'll see inline summaries in the editor by default; switch to Reading view and fold an item to see the collapse behavior.

Scope & honesty

  • The Live Preview editor is the primary surface and is on by default: the resolved summary shows inline as you work, flipping to raw source on the line you're editing. Reading view is also fully supported, adding the fold-tied collapse/expand swap. The editor feature uses Obsidian's editor internals and is wrapped so that, if it can't load in your build, Reading view keeps working.
  • The fold-tied swap relies on Obsidian's own fold state; the plugin detects it defensively (class or hidden/removed child list), but the exact behavior can vary by version — worth a quick check in your vault.
  • Bare-key matching is convenient but positional: if you later insert a duplicate key earlier, a bare {key} can repoint. Use dotted paths (or Strict mode) for notes you edit heavily.

If this overlaps with a plugin not listed above, that's entirely possible — the community catalog is large. The comparison reflects the tools known at release time, and where each genuinely stops.

Files

  • manifest.json — plugin metadata
  • main.js — the compiled plugin (built from src/main.ts)
  • styles.css — collapsed/expanded styling
  • sample-test-note.md — a note to test against

Development

Written in TypeScript, bundled with esbuild.

npm install      # install dev dependencies
npm run dev      # rebuild on change (watch mode)
npm run build    # type-check, then produce a production main.js

The source lives in src/main.ts; the committed main.js is the compiled output.