Skip to content

fix: prevent backspace from merging content into code/quote blocks #167

@oobagi

Description

@oobagi

Problem

When a block sits directly below a code block or quote block, pressing backspace at position 0 merges that block's content into the container via mergeBlockUp(). This is almost never what the user wants — the text becomes trapped inside the code/quote block with no way to extract it (until #164 undo/redo lands).

Other block editors (Notion, VS Code notebooks) treat container blocks as hard boundaries that resist absorbing adjacent content on backspace.

Context

handleBackspace() in editor.go:642–655 handles the merge path. After the list-unwrap logic (line 630–640) and divider-delete (line 648–651), the code falls through to mergeBlockUp() unconditionally at line 654. There is no check on the target block's type.

The fix is a guard before mergeBlockUp(): if the previous block is a CodeBlock or Quote, skip the merge.

Key file: internal/editor/editor.gohandleBackspace() (line 642–655)

Proposed approach

Add a guard clause after line 647 (before the divider check or merged with it):

// Don't merge into container blocks — content gets trapped.
if m.blocks[m.active-1].Type == block.CodeBlock || m.blocks[m.active-1].Type == block.Quote {
    return false
}

This prevents the merge entirely. The cursor stays put, the content stays in its own block.

Tasks

  • Add container-block guard in handleBackspace() before mergeBlockUp() call
  • Verify backspace still works normally between two paragraphs
  • Verify backspace still deletes dividers above (line 648–651)
  • Verify backspace at pos 0 inside a code/quote block still works (different code path)

Test plan

  • Paragraph below code block → backspace at pos 0 → nothing happens (no merge)
  • Paragraph below quote block → backspace at pos 0 → nothing happens (no merge)
  • Paragraph below paragraph → backspace at pos 0 → merges normally
  • Paragraph below divider → backspace at pos 0 → divider deleted (existing behavior)
  • Inside code block → backspace at pos 0 → existing behavior unchanged
  • Empty block below code block → backspace → block deleted, cursor moves up (but doesn't merge into code block)

References

Scope

Type: bug
Size: small

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingphase-13Block Editor Core

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions