# paste-dialog.yazi A [yazi](https://github.com/sxyazi/yazi) plugin that shows an interactive conflict-resolution dialog when pasting files. Instead of silently appending `_1`, `_2` suffixes to conflicting names, you choose how to handle each conflict individually. | Option | Action | Description | |--------|--------|-------------| | **Merge** | merge / overwrite | Merge directory contents recursively; overwrite individual files. _(default — press Enter)_ | | **Merge all remaining** | merge / overwrite | Same as Merge, but applied to every remaining conflict without prompting again. | | **Replace** | replace | Delete the destination entirely, then copy fresh (removes files that exist only at the destination). | | **Rename** | rename | Prompt for a new name, pre-filled with `name-yymmdd`. If the new name also conflicts the dialog reappears with a different default (`name-2`, `name-3`, …). | | **Skip** | skip | Leave this item untouched. | | **Cancel** | abort | Paste any non-conflicting items already queued, then stop. _(Esc)_ | Non-conflicting items always paste silently — the dialog only appears when a conflict is detected. > ⚠️ **This plugin requires a modified version of yazi.** > See [Requirements](#requirements) below. --- ## Requirements This plugin depends on Rust-level changes to yazi that have **not** been merged into upstream: | Change | Why it's needed | |--------|----------------| | `paste_resolved` actor + parser | Per-item paste with explicit `from`/`to`/`overwrite`/`replace` — not possible with the existing `ya.emit("paste")`. | | `file_copy_one` / `file_cut_one` | Scheduler methods that accept individual source/destination URLs with a `replace` flag. | | `ya.pick({ title=, items= })` | Exposes the existing pick dialog to Lua plugins (was internal-only). | | `PickCfg::with_title()` | Lets `ya.pick()` override the dialog title. | Build yazi from the fork: ```sh git clone https://github.com/chodak166/yazi.git cd yazi cargo build --release # Install the modified binaries on your PATH cp target/release/yazi target/release/ya ~/.local/bin/ ``` --- ## Installation ### Option A — install via `ya pkg` (recommended) ```sh ya pkg add chodak166/paste-dialog.yazi ``` ### Option B — manual install ```sh # 1. Create the plugin directory mkdir -p ~/.config/yazi/plugins/paste-dialog.yazi # 2. Download main.lua into it curl -fsSL https://raw.githubusercontent.com/chodak166/paste-dialog.yazi/main/main.lua \ -o ~/.config/yazi/plugins/paste-dialog.yazi/main.lua ``` ### Add the keybinding Add the following to `~/.config/yazi/keymap.toml` (the `prepend_keymap` keeps all default bindings intact): ```toml [[mgr.prepend_keymap]] on = "p" run = "plugin paste-dialog" desc = "Paste with conflict dialog" ``` Restart yazi, then press p to paste with conflict resolution. --- ## Usage 1. Yank files (y) or cut them (x) as usual. 2. Navigate to the destination directory. 3. Press p to paste. 4. If there are conflicts a pick dialog appears for each one: - Navigate with j/k or arrow keys, confirm with Enter. - **Merge** — overwrites the destination file or merges directory contents. - **Merge all remaining** — merge this and all remaining conflicts without prompting. - **Replace** — deletes the destination entirely before copying (removes excess files). - **Rename** — shows an input prompt with `name-yymmdd` pre-filled. If the new name also conflicts, the dialog reappears; choosing Rename again cycles the default to `name-2`, `name-3`, etc. - **Skip** — leaves the destination untouched. - **Cancel** (or Esc) — pastes any queued clean items, then aborts. --- ## Notes - **Merge** uses the scheduler's existing `force=true` behavior: new files are added, existing files are overwritten, destination-only files are preserved. - **Replace** deletes the destination directory entirely before copying, removing any files that exist only in the destination. - Deep conflicts within merged directories are resolved silently by overwriting individual files. - **Cut + Skip** leaves the source file in place (it is not deleted). - Between the conflict pre-scan and the actual paste, `overwrite=false` items fall back to `unique_file()` if a new conflict appears. ## License MIT