Skip to content

feat(files): smarter bullet delete/indent and untitled-file title sync#5971

Open
mzxchandra wants to merge 5 commits into
realtime-roomsfrom
files-untitled-rename-and-bullets
Open

feat(files): smarter bullet delete/indent and untitled-file title sync#5971
mzxchandra wants to merge 5 commits into
realtime-roomsfrom
files-untitled-rename-and-bullets

Conversation

@mzxchandra

@mzxchandra mzxchandra commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Two files-module improvements to the markdown editor. Based on realtime-rooms (not staging) so it integrates directly with the live co-editing work and lands together with it — the only overlap was additive prop wiring in files.tsx / file-viewer.tsx / rich-markdown-editor.tsx, resolved here so that branch inherits these fixes conflict-free.

Bullet delete/indent + round-trip fix (improvement)

  • Backspace at the start of a list item now outdents a nested item or clears a top-level item to a paragraph in place instead of deleting the row and jumping the caret to the previous block. Enter on an empty nested item outdents. Empty non-trailing top-level items still collapse cleanly (they can't round-trip as a lifted paragraph). Emptiness counts inline atoms (images/mentions), and an empty first block in a multi-block item removes only that block.
  • Fixes a data-corruption round-trip bug: a nested empty bullet ( -) serialized directly under a parent's text and re-parsed as a Setext heading underline, silently turning the parent line into an H2 and dropping the bullet. Serialize now strips nested empty list-item lines only; top-level empty items (placeholders, imported blanks) are preserved and round-trip faithfully.

Untitled file → filename sync (feat)

  • While a file is still named untitled(.md), typing a leading heading auto-renames the file after it (debounced 600ms). One-shot: coupling stops once the file has a real name.
  • The reverse direction (rename → auto-insert an H1) was implemented but removed during review: on the collaborative Files page every open client observed the rename and seeded into the shared doc, producing duplicate headings, and it could re-insert a heading a user had just deleted mid-rename. Seeding document content from an async rename transition is the wrong model on a shared editor; the safe, read-only direction (heading → filename) is kept.

Test Coverage

Round-trip-verified unit tests for every list Backspace/Enter branch and every stripEmptyListItemLines rule, plus the untitled→filename derivation helpers. New/updated: keymap.test.ts, markdown-fidelity.test.ts, untitled-title.test.ts, title-heading.test.ts. Full files-feature + editor-consumer suite: 652 tests pass on the rebased realtime-rooms base. Typecheck + Biome clean.

Review

Greptile 5/5. Cursor Bugbot findings across rounds — all resolved:

  • isEmpty counted only text, so a bullet holding an inline atom could be deleted → now uses the caret block's content.size.
  • an empty first block in a multi-block item lifted the whole item → now removes only that block.
  • collaborative duplicate-heading race + in-flight-rename re-insert → resolved by removing the name→heading seed (see Summary).

Test plan

  • Full files-feature + editor-consumer suite (652) on the rebased realtime-rooms base
  • Typecheck clean; Biome clean
  • Manual E2E: bullet clear/outdent, untitled→heading auto-rename

@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 27, 2026 5:15am

Request Review

@cursor

cursor Bot commented Jul 27, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches editor keymaps and save-path markdown post-processing (data integrity), plus async file renames on the collaborative Files surface; behavior is heavily tested but rename timing could still race with manual naming.

Overview
Markdown list editing — Backspace at the start of a list/task item now outdents nested rows, lifts items with text into a normal paragraph (keeping content), or clears a lone/trailing empty bullet in place instead of deleting the row and jumping the caret. Empty middle items still use the existing remove path so markdown round-trips. Enter on an empty nested item outdents one level. Emptiness uses block content.size (inline atoms count as content); multi-block items only drop an empty first block.

Serialize fixpostProcessSerializedMarkdown now strips nested empty list marker lines that would re-parse as a Setext underline and corrupt the parent into a heading; top-level empty bullets and fenced code are preserved.

Untitled files — While the name still matches untitled(.md), typing a leading heading (debounced) triggers onDeriveTitleFromHeading → unique .md rename in the folder. New helpers: untitled-title, firstHeadingTitle, shared uniqueMarkdownName for create.

Reviewed by Cursor Bugbot for commit f9b2f9b. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR improves Markdown list editing and derives filenames from headings for untitled files.

  • Backspace now clears top-level list items or outdents nested items while preserving inline atoms and sibling blocks.
  • Enter on an empty nested list item now outdents it.
  • Serialized Markdown strips hazardous nested empty list markers while preserving top-level placeholders, child-bearing items, and fenced code.
  • Editable untitled Markdown files are renamed from their leading heading after a 600 ms debounce.
  • Shared helpers centralize untitled-name detection, filename derivation, and sibling-name deduplication.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/keymap.ts Adds context-aware list-item clearing and outdenting behavior for Backspace and Enter.
apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/markdown-fidelity.ts Removes nested empty list markers that can corrupt Markdown round trips while preserving safe structures.
apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/rich-markdown-editor.tsx Debounces leading-heading extraction and forwards it to the filename derivation callback while the file remains untitled.
apps/sim/app/workspace/[workspaceId]/files/files.tsx Wires heading-based automatic renaming and centralizes unique untitled Markdown filename generation.
apps/sim/app/workspace/[workspaceId]/files/untitled-title.ts Defines untitled-name recognition, sanitized Markdown filename derivation, and collision handling.

Reviews (4): Last reviewed commit: "fix(files): drop the name-to-heading see..." | Re-trigger Greptile

@mzxchandra mzxchandra changed the title feat(files): Notion-style bullet editing and untitled-file title sync feat(files): smarter bullet delete/indent and untitled-file title sync Jul 27, 2026
@mzxchandra
mzxchandra force-pushed the files-untitled-rename-and-bullets branch from 8a904f1 to c2357d6 Compare July 27, 2026 04:28
…llet heading corruption

Backspace at the start of a list item now outdents a nested item or clears a
top-level item to a paragraph in place instead of deleting the row and jumping
the caret to the previous block; Enter on an empty nested item outdents. Empty
non-trailing top-level items still collapse cleanly since they cannot round-trip
as a lifted paragraph.

Also strips nested empty list-item marker lines on serialize: a nested empty
bullet re-parsed as a Setext heading underline, silently turning its parent line
into an H2 and dropping the bullet. Top-level empty items are preserved.
While a file is still named untitled(.md), typing a leading heading auto-renames
the file after it (debounced), and renaming the file first seeds a leading H1
from the new name. One-shot: coupling stops once the file has a real name, and
the heading seed always prepends so existing content is never clobbered.
@mzxchandra
mzxchandra force-pushed the files-untitled-rename-and-bullets branch from c2357d6 to b5b30f6 Compare July 27, 2026 04:34
…ck items on Backspace

Addresses review findings on the list Backspace logic:
- Emptiness now uses the caret block's content.size (counts inline images/mentions),
  not textContent, so a bullet holding only a non-text atom is no longer treated as
  empty and deleted.
- An empty first block whose item has sibling blocks removes only that block instead
  of lifting the whole item out of the list.
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 2d39f67. Configure here.

…me during editor load

The parent captures the file name at mount (before content/session finish loading) and
passes it as the transition baseline, so a rename that lands in the loading window is still
seen as an untitled to named transition and the leading heading seed is not skipped.
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

Removes the effect that inserted a leading H1 when an untitled file was renamed. On the
collaborative Files page every open client observed the untitled-to-named transition and
inserted into the shared doc, producing duplicate headings; it could also re-insert a heading
a user had just deleted while a rename was in flight. Seeding document content from an async
rename transition is the wrong model on a shared editor. The primary direction — typing a
leading heading renames a still-untitled file — is unaffected (it never mutates the doc).
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit f9b2f9b. Configure here.

@mzxchandra
mzxchandra requested a review from waleedlatif1 July 27, 2026 16:29
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