Skip to content

feat(docs insert): add --markdown for positional formatted-markdown insertion (parity with docs update --markdown) #851

Description

@sebsnyk

Summary

gog docs insert places content at an arbitrary position (--index, --at <text>, --occurrence), but it is plain text only — there is no --markdown flag, so a heading, fenced code block, or list inserted via insert lands as literal unformatted text.

The converted-markdown path that insert is missing already exists in the codebase and is already exposed on a sibling command. Adding --markdown to insert is a small, consistent extension rather than new machinery.

Current behavior (verified against current main, build 0.29.0)

  • docs insert has flags --index / --at / --occurrence / --match-case / --tab but no --markdown. Its Run emits a single plain InsertTextRequest:

    • internal/cmd/docs_edit.go:883DocsInsertCmd struct (no Markdown field).
    • internal/cmd/docs_edit.go:966 — builds the request via docsedit.BuildInsertRequest(content, insertIndex, c.Tab).
    • internal/docsedit/planner.go:71BuildInsertRequest is a bare InsertText request, no styling.
  • docs write --markdown converts markdown but only at whole-tab (--replace) or end-of-doc (--append) granularity; it rejects positional use:

    • internal/docsedit/markdown.go:114 — returns "--markdown requires --replace or --append".

The capability already exists — just not on insert

docs update --markdown already converts markdown and places it at an arbitrary position:

  • internal/cmd/docs_edit.go:761 — the non-replacing markdown branch of DocsUpdateCmd.Run calls insertPreparedDocsMarkdownAt(ctx, svc, id, insertIndex, markdown, c.Tab, true) and then rewrites heading links over the inserted range.
  • internal/cmd/docs_mutation.go:266insertPreparedDocsMarkdownAt parses the markdown, calls the converter at the supplied index, submits the batchUpdate, and handles tables/images.
  • internal/docsmarkdown/requests.go:33MarkdownToDocsRequests(elements, baseIndex, tabID) is already parameterized on an arbitrary baseIndex; nothing pins it to index 1 or the document end. Fenced code blocks get their styling (Roboto Mono + grey shading) inside the same converter (internal/docsmarkdown/requests.go:77), so a --markdown insert would render code blocks identically to write --markdown.

So positional formatted-markdown insertion is feasible and already implemented internally; the only thing missing is the flag on the command users reach for first.

Why this is worth fixing

insert is the obviously-named command for "put this content here". A user who wants to drop a formatted markdown block mid-document will try docs insert --markdown first, get an unknown-flag error, and then has to discover that the converted path lives on update --markdown instead. That is a discoverability cliff for a capability the tool already has. The two commands diverge for no functional reason: update can do plain-or-markdown at a position; insert can only do plain.

Proposed surface

Add --markdown to docs insert:

gog docs insert <docId> --markdown --at "## Section" --file block.md
gog docs insert <docId> --markdown --index 1 --text $'## Heading\n\n```\ncode\n```\n'

Behavior:

  • Without --markdown: unchanged (plain InsertText).
  • With --markdown: route through the existing insertPreparedDocsMarkdownAt helper at the resolved index, then run the existing heading-link rewrite over the inserted range — i.e. mirror the non-replacing branch of docs update --markdown (internal/cmd/docs_edit.go:761).
  • --at / --index / --occurrence / --tab semantics are unchanged; they just resolve the index that the converted block is inserted at.

This keeps insert = "place at a position, never delete", and leaves update --markdown --replace-range / update --markdown --at as the delete-and-replace path. The split between the two commands stays clean.

API feasibility

Not an API limitation. documents.batchUpdate accepts InsertText plus paragraph/text-style requests at any index, which is exactly what MarkdownToDocsRequests already emits relative to baseIndex. The same converter already runs at index 1 (replace), at the end index (append), and at an arbitrary index (update --markdown).

Acceptance criteria

  • docs insert --markdown converts markdown (headings, fenced code blocks with the standard mono + grey styling, lists, inline styles, tables/images via the existing helper) and inserts it at the index resolved from --index / --at / --occurrence.
  • Output without --markdown is byte-for-byte unchanged.
  • --tab targeting works for the markdown path (the helper already threads tabID).
  • A unit test covering docs insert --markdown --index N asserting the converter requests (heading paragraph-style + code-fence text-style) land at the resolved index, alongside the existing plain-text insert tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low-risk cleanup, docs, polish, ergonomics, or speculative feature.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.no-staleExempts this issue from stale automation.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions