Skip to content

feat: pasting a copied file into the terminal inserts its path #368

Description

@yicheng47

Motivation

Copying a file in GoLand (or Finder) and pressing ⌘V over a Runner terminal inserts nothing. Every native terminal — Terminal.app, iTerm2, Ghostty — inserts the file's POSIX path instead, which is how you hand an agent a file without typing its path.

A file copy puts no text on the clipboard: it writes public.file-url / NSFilenamesPboardType to NSPasteboard, and native terminals read those flavors explicitly. Across the WKWebView boundary the paste arrives as a File in DataTransfer with unusable text/plain, so xterm.js's default paste inserts nothing.

Runner already intercepts paste for this exact class of problem — RunnerTerminal.tsx:749 handles image paste by shipping bytes to Rust to restore the NSPasteboard flavor (#79). A non-image file falls through: inferPasteImageMime returns null, the loop continues, and the handler returns without preventDefault. The gap is one branch wide.

The web layer can't close it alone — DataTransfer withholds filesystem paths (File.name is only the basename, and WKWebView exposes no file.path), so the path must come from the native pasteboard.

Scope

  • ⌘V over a terminal pane with file references on the clipboard inserts the absolute path at the cursor, shell-quoted; multiple files insert space-separated.
  • Text and image pastes keep today's behavior exactly.
  • Out of scope: drag-and-drop of files onto a pane (different Tauri mechanism, its own spec), directory contents, cwd-relative rewriting.

Key decisions

  1. Read paths in Rust via NSPasteboard — commands/session.rs:144-165 already has the plumbing and objc2-app-kit is already a dependency.
  2. Branch inside the existing onPaste handler; empty native result falls through untouched.
  3. Prefer the native read over text/uri-list, whose presence is inconsistent across source apps.
  4. Quote unconditionally (''\\'') — spaces in project paths are common.
  5. Insert as text, never submit — a pasted path is mid-sentence, so no inject_paste/Enter.
  6. No cwd-relative rewriting; absolute paths always resolve.

Implementation phases

  1. Native pasteboard read — command returning Vec<String> of file-URL paths; quoting helper unit tests.
  2. Frontend branch — extend onPaste (RunnerTerminal.tsx:749-781), inject via injectStdin; component tests for image / file / text pastes.
  3. Validationcargo test --workspace, tsc --noEmit, lint, pnpm test, manual list.

Spec: docs/features/55-paste-file-paths.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Annoying — fix when convenientfeatureFeature work tracked in docs/features/

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions