Skip to content

Preserve inline formatting while typing - #31

Merged
Chefski merged 1 commit into
devfrom
agent/inline-typing-formatting
Aug 1, 2026
Merged

Preserve inline formatting while typing#31
Chefski merged 1 commit into
devfrom
agent/inline-typing-formatting

Conversation

@Chefski

@Chefski Chefski commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • preserve active inline marks for collapsed selections while typing
  • synchronize platform typing attributes on iOS and macOS
  • add editor mutation and inline-typing regression coverage

Validation

  • git diff --check
  • swiftlint lint --strict --quiet --cache-path /private/tmp/docmostly-swiftlint-cache

Xcode builds and tests were not run, per repository instructions.

@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge, with no concrete changed-code failure established.

The inline-typing state, attributed-text mutation, native typing-attribute synchronization, and focus handoff paths preserve the relevant editing and read-only invariants.

Important Files Changed

Filename Overview
docmostly/Features/Editor/NativeRichEditorViewModel+BlockEditing.swift Introduces collapsed-selection mark tracking while retaining undoable attributed-text mutations for selected ranges.
docmostly/Features/Editor/NativeEditorTextMutation.swift Applies optional typing marks to replacement text and extends focus reconciliation for responder handoffs.
docmostly/Features/Editor/NativeEditorTextInputView+iOS.swift Synchronizes UIKit typing attributes, editability, focus handoffs, and typing-context invalidation.
docmostly/Features/Editor/NativeEditorTextInputView+macOS.swift Synchronizes AppKit typing attributes after selection updates and adds equivalent focus and context handling.
docmostly/Features/Editor/NativeEditorInlineMark.swift Adds mark activation queries, explicit setters, selection-derived active marks, and mutually exclusive baseline marks.
docmostly/Features/Editor/NativeEditorBlockRow.swift Keeps native text surfaces mounted for editable block kinds while controlling platform editability separately.
docmostlyTests/Editor/NativeRichEditorInlineTypingTests.swift Covers collapsed-selection mark toggling and selected-range formatting behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Collapsed editor selection] --> B[Toggle inline mark]
    B --> C[Store marks in inline typing context]
    C --> D[Synchronize native typing attributes]
    D --> E[User inserts text]
    E --> F[Apply marks to inserted range only]
    F --> G[Update attributed document]
    H[Explicit cursor movement] --> I[Invalidate typing context]
Loading

Reviews (1): Last reviewed commit: "Preserve inline formatting while typing" | Re-trigger Greptile

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 18 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docmostly/Features/Editor/NativeEditorBodyView.swift">

<violation number="1" location="docmostly/Features/Editor/NativeEditorBodyView.swift:65">
P2: Pasting or otherwise activating a non-text block leaves the previous text view as first responder, because every inactive text row treats any non-nil active block as a focus handoff. Limit responder preservation to an editable target so keyboard input cannot remain in the old block after a table/media block becomes active.</violation>
</file>

<file name="docmostly/Features/Editor/NativeEditorTextInputView+iOS.swift">

<violation number="1" location="docmostly/Features/Editor/NativeEditorTextInputView+iOS.swift:42">
P2: Programmatic focus or bound-selection updates clear the just-configured `typingAttributes`, so the next input can use UIKit’s default/caret attributes instead of `typingInlineMarks`. Configure after `applySource`/`updateFromBoundBlock` and their selection synchronization, matching the macOS ordering.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

focusRequestID: textInputFocusRequest?.blockID == block.id
? textInputFocusRequest?.id
: nil,
retainsResponderDuringFocusHandoff: viewModel.activeBlockID != nil &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Pasting or otherwise activating a non-text block leaves the previous text view as first responder, because every inactive text row treats any non-nil active block as a focus handoff. Limit responder preservation to an editable target so keyboard input cannot remain in the old block after a table/media block becomes active.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docmostly/Features/Editor/NativeEditorBodyView.swift, line 65:

<comment>Pasting or otherwise activating a non-text block leaves the previous text view as first responder, because every inactive text row treats any non-nil active block as a focus handoff. Limit responder preservation to an editable target so keyboard input cannot remain in the old block after a table/media block becomes active.</comment>

<file context>
@@ -62,6 +62,8 @@ struct NativeEditorBodyView: View {
                         focusRequestID: textInputFocusRequest?.blockID == block.id
                             ? textInputFocusRequest?.id
                             : nil,
+                        retainsResponderDuringFocusHandoff: viewModel.activeBlockID != nil &&
+                            viewModel.activeBlockID != block.id,
                         isSelected: viewModel.selectedBlockID == block.id,
</file context>

textView.backspaceAtStartAction = { [weak coordinator = context.coordinator] in
coordinator?.mergeBlockBackward() ?? false
}
context.coordinator.configure(textView)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Programmatic focus or bound-selection updates clear the just-configured typingAttributes, so the next input can use UIKit’s default/caret attributes instead of typingInlineMarks. Configure after applySource/updateFromBoundBlock and their selection synchronization, matching the macOS ordering.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docmostly/Features/Editor/NativeEditorTextInputView+iOS.swift, line 42:

<comment>Programmatic focus or bound-selection updates clear the just-configured `typingAttributes`, so the next input can use UIKit’s default/caret attributes instead of `typingInlineMarks`. Configure after `applySource`/`updateFromBoundBlock` and their selection synchronization, matching the macOS ordering.</comment>

<file context>
@@ -33,6 +39,7 @@ struct NativeEditorTextInputView: UIViewRepresentable {
         textView.backspaceAtStartAction = { [weak coordinator = context.coordinator] in
             coordinator?.mergeBlockBackward() ?? false
         }
+        context.coordinator.configure(textView)
         context.coordinator.applySource(to: textView)
         context.coordinator.updateFocus(textView)
</file context>

@Chefski
Chefski merged commit 534216a into dev Aug 1, 2026
7 of 8 checks passed
@Chefski
Chefski deleted the agent/inline-typing-formatting branch August 1, 2026 22:46
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