Skip to content

feat: drag and drop - #4005

Merged
sxyazi merged 5 commits into
mainfrom
pr-021afa8c
May 28, 2026
Merged

feat: drag and drop#4005
sxyazi merged 5 commits into
mainfrom
pr-021afa8c

Conversation

@sxyazi

@sxyazi sxyazi commented May 28, 2026

Copy link
Copy Markdown
Owner

Follow-up for:

Resolves #3968


With this PR, Yazi will support DnD, which means you can drag a file from Yazi to other apps, or drop a file from other apps into Yazi. Download the nightly build to try it out!

Note

For the feature to work, your terminal needs to support The Drag and Drop protocol.

The protocol is pretty new, and currently only kitty (>= v0.47.0) supports it, but I'm looking forward to more terminals supporting the protocol in the future.

UPDATE: See https://yazi-rs.github.io/docs/dnd for the latest terminal support status.

Demo

eQEl7bve.mp4

Copilot AI left a comment

Copy link
Copy Markdown

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 adds end-to-end drag-and-drop (DnD) support to Yazi using kitty’s OSC 72 DnD protocol, wiring terminal DnD events into the Lua UI runtime and providing preset Lua logic for offering selected files and accepting text/uri-list drops.

Changes:

  • Introduces Lua-facing rt.tty queue/flush APIs plus DnD event bindings to drive OSC 72 sequences and receive decoded drop payloads.
  • Adds preset Lua plugin/component support (dnd.lua, Tip) and routes DnD events through the app actor into the Lua Root component.
  • Refactors terminal DnD sequences (generic MIME lists) and unifies base64 configuration via yazi-shim.

Reviewed changes

Copilot reviewed 49 out of 50 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
yazi-tty/src/writer.rs Adjusts writer traits/imports for terminal output.
yazi-term/src/sequence/traits.rs Adds internal trait to generalize MIME list inputs.
yazi-term/src/sequence/mod.rs Exposes new traits module in sequence namespace.
yazi-term/src/sequence/dnd.rs Refactors OSC 72 DnD sequences; uses shared base64 engine; generic MIME lists.
yazi-term/src/event/dnd.rs Expands DnD event model, adds error events, decodes drop payload data.
yazi-shim/src/mlua/traits.rs Adds Lua table extension for cloneable sequence iteration.
yazi-shim/src/mlua/string.rs Introduces ByteString wrapper for byte-preserving Lua strings.
yazi-shim/src/mlua/sequence.rs Adds cloneable SequenceIter over Lua tables using raw Lua FFI.
yazi-shim/src/mlua/mod.rs Exposes new sequence and string mlua helpers.
yazi-shim/src/lib.rs Exposes new base64 shim module.
yazi-shim/src/base64.rs Defines a shared base64 engine configuration used across crates.
yazi-shim/Cargo.toml Adds base64 dependency for shim base64 engine.
yazi-shared/Cargo.toml Bumps memchr patch version.
yazi-scheduler/src/scheduler.rs Changes file_cut API to accept FileInCut and return an Id.
yazi-scheduler/src/plugin/plugin.rs Updates plugin entry submission to use From conversion.
yazi-scheduler/src/plugin/in.rs Replaces into_job with From<PluginInEntry> for EntryJob.
yazi-scheduler/src/file/in.rs Makes FileInCut public, adds constructor, and adds FromLua conversion.
yazi-runner/src/loader/loader.rs Adds preset dnd plugin and tip component registration.
yazi-plugin/src/utils/utils.rs Adds percent_decode utility to Lua utils composer.
yazi-plugin/src/utils/text.rs Implements Lua percent_decode helper (byte-preserving).
yazi-plugin/src/utils/tasks.rs Adds cut as a supported ya.task() spawn kind.
yazi-plugin/src/standard.rs Loads new tip.lua component preset.
yazi-plugin/src/runtime/runtime.rs Exposes rt.tty binding to Lua runtime.
yazi-plugin/preset/plugins/dnd.lua Adds preset Lua DnD helper plugin for offering/cutting URI lists.
yazi-plugin/preset/components/tip.lua Adds a UI tip component for drop affordance.
yazi-plugin/preset/components/root.lua Adds drop routing and drop-target tracking at the root component level.
yazi-plugin/preset/components/rail.lua Ignores non-legacy drag events (prevents DnD events affecting rails).
yazi-plugin/preset/components/current.lua Adds DnD drag offering and drop acceptance logic + drop tip rendering.
yazi-plugin/Cargo.toml Adds percent-encoding dependency for new percent-decode helper.
yazi-parser/src/spark/spark.rs Adds app:dnd spark variant wiring.
yazi-parser/src/app/mod.rs Registers new app-level dnd form module.
yazi-parser/src/app/dnd.rs Adds DndForm to carry DndEvent through the actor system.
yazi-fm/src/dispatcher.rs Routes terminal DnD events into app:dnd actor instead of inline handling.
yazi-fm/Cargo.toml Bumps tikv-jemallocator on supported targets.
yazi-core/src/tasks/option.rs Adds TaskOpt::Cut and TaskIn plumbing for cut tasks.
yazi-core/src/tasks/file.rs Updates cut submission to use new FileInCut::new + scheduler API.
yazi-binding/src/tty.rs Adds Lua Tty userdata to queue/flush OSC sequences for DnD.
yazi-binding/src/mouse.rs Adds a constant type = "legacy" field to mouse events.
yazi-binding/src/lib.rs Exposes new dnd and tty binding modules.
yazi-binding/src/dnd.rs Adds Lua DndEvent userdata wrapper with cached fields (mimes/data).
yazi-binding/Cargo.toml Adds dependency on yazi-tty for rt.tty implementation.
yazi-adapter/src/drivers/iip.rs Cleans up trait imports (unnamed imports) for write traits.
yazi-actor/src/tasks/spawn.rs Dispatches new TaskOpt::Cut to scheduler.
yazi-actor/src/app/mouse.rs Refactors Lua root creation scope structure (indent/ownership changes).
yazi-actor/src/app/mod.rs Registers new dnd app actor module.
yazi-actor/src/app/dnd.rs Adds actor to forward DnD events into Lua Root:drag / Root:drop.
README.md Documents Drag and Drop as a supported feature.
cspell.json Adds new word entry for Mimelist.
CHANGELOG.md Adds changelog entry for drag and drop and PR reference.
Cargo.lock Updates dependency lockfile to match version bumps and new deps.

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

Comment thread yazi-tty/src/writer.rs
Comment on lines +1 to 3
use std::{fmt::{self, Debug}, io::{self, BufWriter}, ops::Deref};

use parking_lot::Mutex;
Comment thread yazi-binding/src/tty.rs
Comment on lines +17 to +24
b"ConfirmDrag" => {
let it = t.raw_get::<Table>("mimes")?.sequence_iter::<ByteString>(lua).flatten();
write!(w, "{}", match &*t.raw_get::<BorrowedBytes>("type")? {
b"copy" => ConfirmDrag::Copy(it),
b"move" => ConfirmDrag::Move(it),
b"either" => ConfirmDrag::Either(it),
_ => return Err("invalid ConfirmDrag type".into_lua_err()),
})
Comment thread yazi-binding/src/tty.rs
Comment on lines +18 to +31
let it = t.raw_get::<Table>("mimes")?.sequence_iter::<ByteString>(lua).flatten();
write!(w, "{}", match &*t.raw_get::<BorrowedBytes>("type")? {
b"copy" => ConfirmDrag::Copy(it),
b"move" => ConfirmDrag::Move(it),
b"either" => ConfirmDrag::Either(it),
_ => return Err("invalid ConfirmDrag type".into_lua_err()),
})
}
b"ConfirmDrop" => {
let it = t.raw_get::<Table>("mimes")?.sequence_iter::<ByteString>(lua).flatten();
write!(w, "{}", match &*t.raw_get::<BorrowedBytes>("type")? {
b"reject" => ConfirmDrop::Reject,
b"copy" => ConfirmDrop::Copy(it),
b"move" => ConfirmDrop::Move(it),
Comment thread yazi-binding/src/tty.rs Outdated
Comment on lines +239 to +249
impl FromLua for FileInCut {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
let Value::Table(t) = value else {
return Err("constructing FileInCut from non-table value".into_lua_err());
};

Ok(Self::new(
t.raw_get::<yazi_binding::Url>("from")?.into(),
t.raw_get::<yazi_binding::Url>("to")?.into(),
t.raw_get("force")?,
))
Comment thread yazi-plugin/preset/plugins/dnd.lua Outdated
local from = Url(ya.percent_decode(line:sub(8)))
if from.name then
local to = cx.active.current.cwd:join(from.name)
ya.async(function() ya.task("cut", { from = from, to = to }):spawn() end)
@sxyazi
sxyazi merged commit 04f9f72 into main May 28, 2026
10 checks passed
@sxyazi
sxyazi deleted the pr-021afa8c branch May 28, 2026 01:25
sxyazi added a commit that referenced this pull request May 28, 2026
sxyazi added a commit that referenced this pull request May 28, 2026
sxyazi added a commit that referenced this pull request May 28, 2026
sxyazi added a commit that referenced this pull request May 28, 2026
sxyazi added a commit that referenced this pull request May 28, 2026
sxyazi added a commit that referenced this pull request May 28, 2026
sxyazi added a commit that referenced this pull request May 28, 2026
vishudhshah added a commit to vishudhshah/dotfiles that referenced this pull request May 29, 2026
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Jun 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drag and drop support with the new DnD protocol

2 participants