ya env output
Yazi
Version: 26.5.6 (8e80798 2026-06-01)
Debug : false
Triple : x86_64-unknown-linux-gnu (linux-x86_64)
Rustc : 1.96.0 (ac68faa2 2026-05-25)
Backtrace: None
Ya
Version: 26.5.6 (8e80798 2026-06-01)
Debug : false
Triple : x86_64-unknown-linux-gnu (linux-x86_64)
Rustc : 1.96.0 (ac68faa2 2026-05-25)
Config
Init : /home/arti/.config/yazi/init.lua (195 chars)
Yazi : /home/arti/.config/yazi/yazi.toml (63 chars)
Keymap : /home/arti/.config/yazi/keymap.toml (1828 chars)
Theme : /home/arti/.config/yazi/theme.toml (No such file or directory (os error 2))
VFS : /home/arti/.config/yazi/vfs.toml (No such file or directory (os error 2))
Package : /home/arti/.config/yazi/package.toml (624 chars)
Dark/light flavor: ArcSwapAny("") / ArcSwapAny("")
Emulator
TERM : Some("xterm-kitty")
TERM_PROGRAM : None
TERM_PROGRAM_VERSION: None
Brand.from_env : Some(Kitty)
Emulator.detect : Emulator { kind: Left(Kitty), version: "kitty(0.47.1)", light: false, csi_16t: (9, 20), force_16t: false }
Adapter
Adapter.matches : Kgp
Dimension.available: Dimension { cols: 211, rows: 50, width: 1899, height: 1000 }
Desktop
XDG_SESSION_TYPE : Some("wayland")
WAYLAND_DISPLAY : Some("wayland-1")
DISPLAY : Some(":0")
NIRI_SOCKET : Some("/run/user/1000/niri.wayland-1.1548.sock")
SWAYSOCK : None
HYPRLAND_INSTANCE_SIGNATURE: None
WAYFIRE_SOCKET : None
SSH
shared.in_ssh_connection: false
WSL
WSL: false
Variables
SHELL : Some("/bin/zsh")
EDITOR : Some("helix")
VISUAL : Some("helix")
YAZI_FILE_ONE : None
YAZI_CONFIG_HOME : None
YAZI_ZOXIDE_OPTS : None
SSH_AUTH_SOCK : None
FZF_DEFAULT_OPTS : None
FZF_DEFAULT_COMMAND: None
Text Opener
default : Some(OpenerRule { id: Id(3), run: NonEmptyString("${EDITOR:-vi} %s"), block: true, orphan: false, desc: "$EDITOR", for: Unix, spread: true })
block-create: Some(OpenerRule { id: Id(3), run: NonEmptyString("${EDITOR:-vi} %s"), block: true, orphan: false, desc: "$EDITOR", for: Unix, spread: true })
block-rename: Some(OpenerRule { id: Id(3), run: NonEmptyString("${EDITOR:-vi} %s"), block: true, orphan: false, desc: "$EDITOR", for: Unix, spread: true })
Multiplexers
TMUX : false
tmux version : tmux 3.6b
tmux build flags : enable-sixel=Supported
ZELLIJ_SESSION_NAME: None
Zellij version : No such file or directory (os error 2)
Dependencies
file : 5.47
ueberzugpp : No such file or directory (os error 2)
ffmpeg/ffprobe: 8.1.1 / 8.1.1
pdftoppm : 26.05.0
magick : 7.1.2-24
fzf : 0.72.0
fd/fdfind : 10.4.2 / No such file or directory (os error 2)
rg : 15.1.0
chafa : No such file or directory (os error 2)
zoxide : 0.9.9
7zz/7z : No such file or directory (os error 2) / 26.01
resvg : No such file or directory (os error 2)
jq : 1.8.1
Clipboard
wl-copy/paste: 2.3.0 / 2.3.0
xclip : No such file or directory (os error 2)
xsel : No such file or directory (os error 2)
Routine
`file -bL --mime-type`: text/plain
Please describe the problem you're trying to solve
fs.unique("file", url) currently inserts the counter before the last extension only.
If I copy then paste this file in the same directory
I get
it is not a bug, but in my opinion this is a bad ux.
same kind of thing happens with:
backup.tar.zst
backup.tar.xz
package.pkg.tar.zst
I think this is a bad name. .tar.gz / .tar.zst is not just a random last extension. It is a compound suffix. backup.tar_1.gz looks like a gzip file that contains backup.tar_1, not like another backup.tar.gz archive.
Expected
backup.tar.gz
backup_1.tar.gz
backup.tar.zst
backup_1.tar.zst
It can also affect tools that look at filenames or suffixes: previewers, open rules, scripts, upload filters, archive tools, etc. For example 7z won't preview archive correctly if file suffix changed by yazi.
Would you be willing to contribute this feature?
Describe the solution you'd like
I don't think fs.unique() should try to guess every possible naming pattern.
But I think there are two cases here.
First for normal file operations like copy n paste, it would be good if Yazi handled common compound file suffixes a bit better.
For example
backup.tar.gz
backup.tar.zst
backup.tar.xz
package.pkg.tar.zst
When these files are copied into the same directory, I think the counter should be inserted before the full suffix:
backup.tar.gz -> backup_1.tar.gz
backup.tar.zst -> backup_1.tar.zst
package.pkg.tar.zst -> package_1.pkg.tar.zst
not
backup.tar.gz -> backup.tar_1.gz
backup.tar.zst -> backup.tar_1.zst
package.pkg.tar.zst -> package.pkg.tar_1.zst
This should probably only be done for well known compound suffixes. I don't think every project naming style should be hardcoded into Yazi.
Second for plugins, maybe fs.unique() could accept an optional suffix from the caller.
Something like:
fs.unique("file", url, { preserve_suffix = ".tar.zst" })
or:
fs.unique("file", url, { suffix = ".tar.zst" })
Then plugins that already know what kind of file they are creating can keep the suffix intact, but still use the unique file creation from Yazi.
So the current behavior can stay for normal files:
photo.jpg -> photo_1.jpg
report.pdf -> report_1.pdf
but plugins and common archive cases can avoid breaking the suffix in the middle.
Additional context
No response
Checklist
ya envoutputYazi Version: 26.5.6 (8e80798 2026-06-01) Debug : false Triple : x86_64-unknown-linux-gnu (linux-x86_64) Rustc : 1.96.0 (ac68faa2 2026-05-25) Backtrace: None Ya Version: 26.5.6 (8e80798 2026-06-01) Debug : false Triple : x86_64-unknown-linux-gnu (linux-x86_64) Rustc : 1.96.0 (ac68faa2 2026-05-25) Config Init : /home/arti/.config/yazi/init.lua (195 chars) Yazi : /home/arti/.config/yazi/yazi.toml (63 chars) Keymap : /home/arti/.config/yazi/keymap.toml (1828 chars) Theme : /home/arti/.config/yazi/theme.toml (No such file or directory (os error 2)) VFS : /home/arti/.config/yazi/vfs.toml (No such file or directory (os error 2)) Package : /home/arti/.config/yazi/package.toml (624 chars) Dark/light flavor: ArcSwapAny("") / ArcSwapAny("") Emulator TERM : Some("xterm-kitty") TERM_PROGRAM : None TERM_PROGRAM_VERSION: None Brand.from_env : Some(Kitty) Emulator.detect : Emulator { kind: Left(Kitty), version: "kitty(0.47.1)", light: false, csi_16t: (9, 20), force_16t: false } Adapter Adapter.matches : Kgp Dimension.available: Dimension { cols: 211, rows: 50, width: 1899, height: 1000 } Desktop XDG_SESSION_TYPE : Some("wayland") WAYLAND_DISPLAY : Some("wayland-1") DISPLAY : Some(":0") NIRI_SOCKET : Some("/run/user/1000/niri.wayland-1.1548.sock") SWAYSOCK : None HYPRLAND_INSTANCE_SIGNATURE: None WAYFIRE_SOCKET : None SSH shared.in_ssh_connection: false WSL WSL: false Variables SHELL : Some("/bin/zsh") EDITOR : Some("helix") VISUAL : Some("helix") YAZI_FILE_ONE : None YAZI_CONFIG_HOME : None YAZI_ZOXIDE_OPTS : None SSH_AUTH_SOCK : None FZF_DEFAULT_OPTS : None FZF_DEFAULT_COMMAND: None Text Opener default : Some(OpenerRule { id: Id(3), run: NonEmptyString("${EDITOR:-vi} %s"), block: true, orphan: false, desc: "$EDITOR", for: Unix, spread: true }) block-create: Some(OpenerRule { id: Id(3), run: NonEmptyString("${EDITOR:-vi} %s"), block: true, orphan: false, desc: "$EDITOR", for: Unix, spread: true }) block-rename: Some(OpenerRule { id: Id(3), run: NonEmptyString("${EDITOR:-vi} %s"), block: true, orphan: false, desc: "$EDITOR", for: Unix, spread: true }) Multiplexers TMUX : false tmux version : tmux 3.6b tmux build flags : enable-sixel=Supported ZELLIJ_SESSION_NAME: None Zellij version : No such file or directory (os error 2) Dependencies file : 5.47 ueberzugpp : No such file or directory (os error 2) ffmpeg/ffprobe: 8.1.1 / 8.1.1 pdftoppm : 26.05.0 magick : 7.1.2-24 fzf : 0.72.0 fd/fdfind : 10.4.2 / No such file or directory (os error 2) rg : 15.1.0 chafa : No such file or directory (os error 2) zoxide : 0.9.9 7zz/7z : No such file or directory (os error 2) / 26.01 resvg : No such file or directory (os error 2) jq : 1.8.1 Clipboard wl-copy/paste: 2.3.0 / 2.3.0 xclip : No such file or directory (os error 2) xsel : No such file or directory (os error 2) Routine `file -bL --mime-type`: text/plainPlease describe the problem you're trying to solve
fs.unique("file", url)currently inserts the counter before the last extension only.If I copy then paste this file in the same directory
I get
it is not a bug, but in my opinion this is a bad ux.
same kind of thing happens with:
I think this is a bad name.
.tar.gz/.tar.zstis not just a random last extension. It is a compound suffix.backup.tar_1.gzlooks like a gzip file that containsbackup.tar_1, not like anotherbackup.tar.gzarchive.Expected
It can also affect tools that look at filenames or suffixes: previewers, open rules, scripts, upload filters, archive tools, etc. For example 7z won't preview archive correctly if file suffix changed by yazi.
Would you be willing to contribute this feature?
Describe the solution you'd like
I don't think
fs.unique()should try to guess every possible naming pattern.But I think there are two cases here.
First for normal file operations like copy n paste, it would be good if Yazi handled common compound file suffixes a bit better.
For example
When these files are copied into the same directory, I think the counter should be inserted before the full suffix:
not
This should probably only be done for well known compound suffixes. I don't think every project naming style should be hardcoded into Yazi.
Second for plugins, maybe
fs.unique()could accept an optional suffix from the caller.Something like:
or:
Then plugins that already know what kind of file they are creating can keep the suffix intact, but still use the unique file creation from Yazi.
So the current behavior can stay for normal files:
but plugins and common archive cases can avoid breaking the suffix in the middle.
Additional context
No response
Checklist