feat(tui): improve clipboard paste and drag-and-drop file handling on Linux#14552
Open
RobertWsp wants to merge 7 commits intoanomalyco:devfrom
Open
feat(tui): improve clipboard paste and drag-and-drop file handling on Linux#14552RobertWsp wants to merge 7 commits intoanomalyco:devfrom
RobertWsp wants to merge 7 commits intoanomalyco:devfrom
Conversation
event.preventDefault() must be called synchronously before yielding to the event loop. The previous code called it after awaiting Filesystem.exists(), allowing the browser default paste to insert raw file paths into the textarea alongside the virtual extmarks. Fix: add a synchronous heuristic check (paths start with /, ~/, or file://) to call preventDefault() immediately, then validate existence asynchronously. If async validation fails, manually insert text as fallback since the default paste was already prevented.
Single file paths for PDFs, code files, and directories were falling through to the text handler because only image MIME types were checked. Uses existsSync for synchronous preventDefault before any await.
WezTerm sends dropped files as space-separated paths with backslash- escaped spaces (quote_dropped_files=SpacesOnly), not newline-separated. Add shellTokens() parser to handle all WezTerm quoting modes and integrate it into onPaste so multi-file DnD routes to pasteImage/ pasteFile correctly. Also removes debug logging from prior session.
Move event.preventDefault() before await in the WezTerm space-separated DnD branch to prevent raw path text from being inserted during the async gap. Add text fallback when file existence check fails.
Contributor
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
1 task
Contributor
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes #14555
Also addresses #4668, #6331, #10154
Type of change
What does this PR do?
Fixes TUI paste and drag-and-drop to properly handle multiple file formats and terminal emulators on Linux.
clipboard.ts— Dynamic MIME discovery: The previous implementation hardcodedimage/pngas the only clipboard format. This replaces it with a priority-ordered probe (PNG → JPEG → WebP → GIF → BMP) that reads the first available format from the system clipboard viaxclip/xsel. Falls back gracefully when no image is available.prompt/index.tsx— RewrittenonPastehandler: The core change. When text is pasted, the handler now checks if the pasted content looks like file paths before treating it as plain text:Multi-line paths (newline-separated, from Nautilus/Thunar file managers): splits by newline, validates each line is an existing path via
Filesystem.exists(), then routes images topasteImage()and other files to the newpasteFile().Single-line space-separated paths (WezTerm
DroppedFileformat): WezTerm joins multiple dropped file paths with spaces and backslash-escapes spaces within filenames (quote_dropped_files = "SpacesOnly"is the Linux default). A newshellTokens()function parses this format by splitting on unescaped spaces and unescaping\→.Single file path: detected with synchronous
existsSync()check for fast-path routing.pasteFile(): new function that handles non-image attachments (PDFs, SVGs, code files) by creating[File: name.ext]virtual tokens, and directories as[Dir: dirname/].Critical fix — synchronous
event.preventDefault():onPasteis async, butevent.preventDefault()must be called before anyawaitto prevent the browser's default paste behavior (inserting raw text) from executing during the async gap. This is called immediately after the synchronous heuristic check (all tokens look like paths), before any filesystem I/O.The all-or-nothing validation ensures regular text paste is unaffected: if ANY token doesn't look like a path or doesn't exist on disk, the entire paste falls through to normal text insertion.
How did you verify your code works?
Tested on Zorin OS 18 (Ubuntu Noble, X11) with WezTerm nightly
20260117-154428-05343b38:Projeto (12).png) parsed correctlyScreenshots / recordings
N/A — TUI terminal behavior, not a visual UI change.
Checklist