Skip to content

Add selected editor code to the chat draft with file and buffer-line context #416

Closed

Description

@wheregmis

Problem and benefit

After finding code in Threadlane’s editor, asking the agent about a fragment requires copying it, switching to Chat, pasting, and adding its filename/location. A path mention cannot capture a partial selection or unsaved edits.

Add Add selection to chat to both file-editor hosts: append selected buffer text with its checkout-relative path and buffer line range to the current draft, then reveal/focus the composer. This is editable text, not an automatic send, live attachment, file write, or GitHub review comment.

Source inspiration

Source-code research only; no application was launched or visually inspected. Reviewed pinned snapshots, not necessarily the latest source HEADs:

  • Synara: WorkspaceFilePreview.tsx:832–881 distinguishes exact source selections from rendered Markdown snippets and passes path plus selection to onReferenceInChat. The source-selection action here is limited to noneditable documents with a chat target. useCodeSelectionAction.ts:19–71 implements the handoff. Borrow precise file context, not its floating web toolbar or assumptions about editable buffers.
  • T3 Code: FilePreviewPanel.tsx:759–838 normalizes selected line ranges and submits file review comments to a specific composerDraftTarget, carrying file path, range, text, and contents. Edit handling accounts for buffer changes and annotation remapping. Borrow explicit destination and provenance; do not adopt autosave, an annotation store, or persistent remapping.

The common useful idea is precisely identified file context in a draft without a clipboard round trip. Plain editable excerpts are a smaller fit than persistent reference chips or line-comment threads.

Current Threadlane architecture

Inspected ab06c9a373c777c8bc646ff3f89ef7c9fe42a82e, matching upstream HEAD during research:

  • EditorTab/EditorView own checkout, relative path, dirty/loading state and EditorState. Current actions expose save/tab management, not selection-to-chat.
  • The Files panel is a second editable host: RightPanelView::render_files composes shared panel_document_header and editor_buffer. Include both real file editors; exclude Review patch documents.
  • threadlane-ui-kit/src/editor.rs owns presentation; hosts retain buffers, file access and guards.
  • ChatListView::append_draft_text_for already checks (work_dir, session_id), appends through an undoable edit, preserves images/clipboard, clears recall/completion, reveals Chat and focuses the composer. Reuse it, not another draft store or an unscoped queued insert.
  • add_terminal_selection_to_chat provides the guarded host-to-chat precedent; bounded safe-fence formatting is an existing reuse opportunity.
  • The pinned GPUI dependency exposes selected_range as a UTF-8 byte range for the active selection and selected_value. No clipboard reads or new editor dependency are necessary. API availability alone does not prove focus behavior; test it in GPUI.

UX and interaction states

  1. Invoke: a quiet labeled Add selection to chat Button beside file actions in both hosts, plus the same editor-scoped Action in a keyboard-operable command surface. No hover-only or floating toolbar. Explain in tooltip/accessibility description that multiple cursors contribute only the active selection. Moving focus to the command must preserve the selection.
  2. Result: append File excerpt: src/config.rs · buffer lines 12–18, a provenance label (Unsaved buffer when dirty, otherwise Buffer snapshot), and a safely fenced exact excerpt. Preserve partial lines and whitespace. One-based inclusive line numbers refer to the captured buffer, not guaranteed current disk contents. Preserve prior draft/images/clipboard; reveal Chat and focus the composer only after success. One Undo removes the insertion without losing the prior draft.
  3. Unavailable: disabled with textual reasons for empty active selection, loading/failed/non-text documents, Review/diff documents, no valid composer checkout, or source/destination checkout mismatch. Reject selections exceeding 32 KiB UTF-8 with Select less code (maximum 32 KiB); never truncate silently. New-task drafts are eligible only with a matching checkout. A running agent does not change the action into send/queue/steer.
  4. Stale activation: capture source entity/buffer, checkout, path, selection and destination key together. Revalidate source and destination immediately before append; stale tab/project/session changes leave drafts/files unchanged. Prefer synchronous capture/dispatch. Never replace selected unsaved text with a disk reread. Failures retain source selection and show a concise reason. Menus dismiss with Escape and restore focus; successful commands transfer focus after dismissal so menus cannot steal it back.
  5. Accessibility/scope: standard kit focus, hover, pressed and disabled states; semantic theme tokens, accessible names, no color-only status. Narrow widths retain a keyboard-reachable overflow command. No whole-file fallback, rendered Markdown/diff-side selection, GitHub comments, persistent citations/jump-back anchors, or automatic excerpt refresh.

Implementation plan

  1. Extend crates/threadlane-ui-kit/src/editor.rs with shared controlled command/state for both hosts. Put only the minimal shared snapshot/formatting logic needed by both hosts in an appropriate existing shared module; no new service/reference framework. Reuse/extract safe-fence logic where practical. Derive text and line labels from the same byte range, correctly handling an exclusive end at the next line’s start, Unicode and embedded backticks. Bound bytes before copying; do not materialize whole buffers on every render.
  2. Wire capture in crates/threadlane-ui-editor/src/view.rs and crates/threadlane-ui-right-panel/src/view.rs from existing EditorState, checkout/path and dirty status. Observe selection changes for availability. Keep file identity and stale-result guards in hosts. No filesystem reads, saves, or extension to Review documents.
  3. Expose a small typed event/callback from each host. Route the central editor through its parent in crates/threadlane-ui-chat/src/view.rs, and the Files panel through crates/threadlane-ui-workspace/src/view.rs, into append_draft_text_for. This avoids a dependency cycle from editor to chat. Revalidate captured identities and use the boolean success result for focus/error handling; do not introduce an asynchronous unscoped queue.
  4. Add fixture-based enabled/empty/oversized/unsaved states to the existing crates/threadlane-ui-kit/examples/preview gallery without browser-host filesystem access. Add formatting/guard tests and focused GPUI tests near existing editor/right-panel/chat/workspace tests. Follow AGENTS.md’s reuse/leaf-crate rules and native interaction guidance.

Acceptance criteria and validation

  • Both editable file hosts expose the same named keyboard-operable command; Review/diff documents cannot invoke it.
  • Exact selection, correct relative path/range and snapshot provenance reach the intended draft once. No send, queue mutation, save, clipboard change or image loss.
  • Successful activation focuses the composer; Undo restores the prior draft and its existing history.
  • Empty/oversized/loading and mismatched-checkout cases give useful reasons. Stale actions never land in another session or same-named file in another checkout.
  • Unit tests cover forward/reverse and partial-line ranges, end-at-next-line-start, CRLF, Unicode, embedded fences, size boundary, active selection with multiple cursors, dirty buffers and source/destination identity changes.
  • GPUI tests mounted under gpui_component::Root verify command focus does not erase selection, keyboard activation/dismissal, post-insert focus, clipboard/images and Undo. Include same session IDs in different projects.
  • Run focused cargo nextest run -p <affected-package> <filter>, cargo check -p threadlane-gpui and git diff --check using the project toolchain. Manually exercise both hosts at minimum width, larger text and light/dark themes, during an active agent turn and session switching. Do not claim visual verification before doing it.

Duplicate research

Reviewed all 100 destination issues, open and closed, and searched concepts/synonyms including editor, snippet, selected code, code selection, file excerpt, line range, reference and add-to-chat. Inspected the neighboring bodies and discussion; the directly relevant issues below had no additional comments when checked.

  • #32: completed basic editor, with no body/comments; current code lacks this handoff.
  • #310: composer path completion, not selected buffer text or unsaved provenance.
  • #377: find file contents/open matching lines, not editor-to-draft insertion.
  • #320: terminal output, providing a reusable insertion precedent.
  • #405: assistant-response text, not file identity, buffer line ranges, dirty-buffer provenance or either editor host.
  • #350: composer insert identity hardening; reuse project/session scoping rather than reopen it.

Risks/tradeoffs

  • Buffer line labels become stale after edits. Snapshot labeling and exact text are intentional; live remapping is out of scope.
  • Cross-checkout insertion is intentionally rejected, even for deliberate comparisons, to keep v1 provenance/destination unambiguous.
  • Two editor hosts can drift: shared kit presentation and matching tests should prevent divergent UX while hosts retain operational guards.
  • Large-buffer materialization would hurt responsiveness. Use rope/range APIs and bounded extraction.
  • Selected text may contain secrets. Require explicit insertion and a separate send action; add no telemetry/reference persistence channel.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions