Skip to content

feat: support pasting video files from clipboard via Ctrl-V#1369

Merged
RealKai42 merged 5 commits into
mainfrom
kaiyi/fix-ctrl-v-paste-crash
Mar 9, 2026
Merged

feat: support pasting video files from clipboard via Ctrl-V#1369
RealKai42 merged 5 commits into
mainfrom
kaiyi/fix-ctrl-v-paste-crash

Conversation

@RealKai42
Copy link
Copy Markdown
Collaborator

@RealKai42 RealKai42 commented Mar 9, 2026

Extends Ctrl-V clipboard paste to handle video files in addition to images.

  • grab_media_from_clipboard() replaces grab_image_from_clipboard(), returning a typed ClipboardImage | ClipboardVideo | None
  • Video files (mp4, mov, mkv, etc.) are detected first; their path is inserted as text (shell-quoted in shell mode)
  • Fixes a crash when clipboard_data is None after a non-media paste attempt
  • Updates toolbar tip from "paste image" → "paste media"
  • Adds unit tests for clipboard classification and prompt paste behavior

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked the related issue, if any.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have run make gen-changelog to update the changelog.
  • I have run make gen-docs to update the user documentation.

Open with Devin

Copilot AI review requested due to automatic review settings March 9, 2026 06:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the Ctrl-V clipboard paste handler to support video files in addition to images. grab_image_from_clipboard() is replaced with grab_media_from_clipboard(), which returns a typed ClipboardImage | ClipboardVideo | None. Video files are detected by extension, with video taking priority over images in multi-file clipboard payloads. On macOS, the native pasteboard API is tried first (avoiding misidentification via video thumbnails). The toolbar tip is updated from "paste image" to "paste media", and a crash when clipboard_data is None in the fallback paste path is fixed.

Changes:

  • clipboard.py: Introduces ClipboardImage/ClipboardVideo dataclasses, _VIDEO_SUFFIXES, renames and restructures the clipboard-reading function, and extracts _classify_file_paths().
  • prompt.py: Renames _try_paste_image_try_paste_media, adds video path insertion logic (with shell-quoting), fixes the None clipboard_data crash, and updates the toolbar tip.
  • Tests: Adds tests/test_clipboard.py for _classify_file_paths classification and tests/ui_and_conv/test_prompt_clipboard.py for the video-paste prompt behavior; updates the toolbar tip assertion.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/kimi_cli/utils/clipboard.py Core change: new typed result classes, video suffix set, updated grab_media_from_clipboard with macOS-priority path, and _classify_file_paths helper
src/kimi_cli/ui/shell/prompt.py Renames handler to _try_paste_media, adds video path insertion with shell-quoting, fixes None clipboard crash, updates toolbar tip
tests/test_clipboard.py New tests for _classify_file_paths covering all video suffixes, image files, priority ordering, and edge cases
tests/ui_and_conv/test_prompt_clipboard.py New tests for _try_paste_media covering video path shell-quoting and agent-mode behavior
tests/ui_and_conv/test_prompt_tips.py Updates toolbar tip assertion to match "paste media"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/kimi_cli/ui/shell/prompt.py Outdated
Comment on lines +859 to +866
if isinstance(media, ClipboardVideo):
logger.debug("Pasted video from clipboard: {path}", path=media.path)
video_text = str(media.path)
if self._mode == PromptMode.SHELL:
video_text = shlex.quote(video_text)
event.current_buffer.insert_text(video_text)
event.app.invalidate()
return True
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

When a video is detected from the clipboard in AGENT mode, the path is inserted into the buffer without checking whether video_in is in self._model_capabilities. By contrast, the image branch already checks image_in and shows a warning to the user when the model doesn't support image input (line 869–871). A user pasting a video with a model that lacks video_in capability will silently get a path inserted into their prompt with no feedback, which is inconsistent and likely to cause confusion.

The video branch should check "video_in" not in self._model_capabilities and print a similar warning (e.g., "Video input is not supported by the selected LLM model") before returning True, mirroring the image-capability guard.

Copilot uses AI. Check for mistakes.
Comment thread src/kimi_cli/utils/clipboard.py Outdated
Comment on lines +64 to +65
# Note: if a video file was copied, the native path above would have
# already caught it. Reaching here means no video file was found.
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

The inline comment "Note: if a video file was copied, the native path above would have already caught it. Reaching here means no video file was found." is inaccurate. The macOS native path lookup in step 1 returns None and falls through whenever any call to _classify_file_paths returns None — this includes the case where a non-video, non-image file (e.g. a .pdf or .dmg) was copied. In that scenario, the clipboard paths did exist but no video was in them; ImageGrab.grabclipboard() might then still return an image object (for example, the macOS-generated thumbnail of a copied document). The comment's reasoning is therefore only correct when there were no file paths at all in the native clipboard. Consider revising the comment to reflect this more precisely, for example: "If we reach here, the native path lookup did not identify a video or image file path (either no file paths were present, or none were media files)."

Suggested change
# Note: if a video file was copied, the native path above would have
# already caught it. Reaching here means no video file was found.
# Note: if we reach here, the macOS native path lookup did not identify
# a video or image file path (either no file paths were present, or none
# were recognized as media files).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

devin-ai-integration[bot]

This comment was marked as resolved.

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.

2 participants