Skip to content

fix(typed-link): scope inline Dataview fields to their bracket span - #737

Merged
michaelpporter merged 1 commit into
mainfrom
731-bug-inline-dataview-creates-unintended-self-loop-edge
Jul 25, 2026
Merged

fix(typed-link): scope inline Dataview fields to their bracket span#737
michaelpporter merged 1 commit into
mainfrom
731-bug-inline-dataview-creates-unintended-self-loop-edge

Conversation

@michaelpporter

@michaelpporter michaelpporter commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Refs #731 — intentionally not an auto-closing keyword; the issue is closed when the fix ships in a release.

Problem

Pass 2 of the typed_link builder (body inline fields) worked at line granularity: it asked "does this line open with an inline field?" and then attributed every link on that line to it.

So (down:: [[y]]) [[x]] in x.md made both [[y]] and [[x]] down children — including a self-loop from the note to itself.

Fix

parse_inline_field (name only) becomes parse_inline_fields, which returns every field on the line plus the character span its value occupies, following Dataview's actual grammar:

  • Wrapped(down:: …) / [down:: …] anywhere on the line; the value ends at the matching close bracket.
  • Baredown:: … at line start (optionally after a list marker); the value runs to end of line, unchanged.

Links are then assigned by column, and a link falling outside every span produces no edge.

find_close_bracket counts depth of only the opening bracket's own type, so nested wikilinks ([down:: [[X]]]) and markdown links ((down:: [y](y.md))) close correctly. An unclosed wrapper falls back to end-of-line.

Behaviour change

Prose links merely near an inline field no longer create edges. That's the correct Dataview reading, but a vault relying on (down:: [[y]]) [[x]] linking both would now need down:: [[y]] [[x]].

Tests

bun run build && bun run test pass. The existing mock gave every link col: 0, which the old code never read — mock_file's links now takes an optional col (defaulting to 0, so list_note tests are unaffected), and a scan_links helper derives real columns from the body text so builder tests mirror what Obsidian's cache supplies.

New cases: the #731 repro, link-before-field, two wrapped fields on one line, bare field still claiming the whole line, multi-line bodies, and span assertions for nested/unclosed brackets.

Pass 2 of the typed_link builder attributed every link on a line to
whichever inline field opened that line, so `(down:: [[y]]) [[x]]` in
x.md made both [[y]] and [[x]] `down` children — including a self-loop.

parse_inline_field (name only) becomes parse_inline_fields, returning
every field on the line plus the character span its value occupies:
bracketed fields end at their matching close bracket, bare line-level
fields still run to end of line. Links are then assigned by column, and
links outside every span produce no edge.

Refs #731
@michaelpporter
michaelpporter force-pushed the 731-bug-inline-dataview-creates-unintended-self-loop-edge branch from c3b318e to 2bbfac9 Compare July 25, 2026 15:28
@michaelpporter
michaelpporter merged commit 7a2bd04 into main Jul 25, 2026
1 check failed
@michaelpporter
michaelpporter deleted the 731-bug-inline-dataview-creates-unintended-self-loop-edge branch July 25, 2026 15:49
michaelpporter added a commit that referenced this pull request Jul 26, 2026
…mpat

Three unrelated fixes bundled from working through today's 1.12-compat
release grill session:

- CI now also runs on push to main, not just pull_request. main went
  two months (444661a landing on 2026-05-28, first caught by #737 on
  2026-07-25) with a broken TypeScript pin and nobody noticed, because
  nothing ran CI against main directly.

- Removed manifest-beta.json and version-bump-beta.mjs. The 4.15.0
  changelog says BRAT reads manifest-beta.json from the repo root —
  true of older BRAT, but BRAT v1.1.0+ ignores it entirely and reads
  manifest.json straight from a pinned release's assets instead
  (confirmed against BRAT's own developer guide). version:beta now
  bumps manifest.json exactly like version:prod; the only thing that
  still needs to differ for a beta release is package.json's version
  carrying a -beta.N suffix, which is what release.yml's tag-name check
  already uses to mark the release a prerelease.

- release:beta no longer pushes to a hardcoded branch. It was
  `main:main`, harmless here, but copied verbatim onto 1.12-compat as
  `master:master` — a branch that doesn't exist, silently broken.
  Now pushes whatever branch is checked out.

Not changed: 1.12-compat's release.yml also attaches manifest-beta.json
to every release (stable included) — investigated as a possible
main/1.12-compat divergence to reconcile, but since BRAT ignores the
file either way it's harmless, not a bug. Left alone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant