new file: herdr/.config/herdr/sessions/home/session-history.json new file: herdr/.config/herdr/sessions/home/session.json new file: kanata/.config/systemd/user/default.target.wants/duplicati.service new file: pi/.pi/agent/extensions/atuin.ts new file: yazi/.config/yazi/bookmark modified: yazi/.config/yazi/init.lua modified: yazi/.config/yazi/keymap.toml modified: yazi/.config/yazi/package.toml renamed: yazi/.config/yazi/flavors/catppuccin-mocha.yazi/LICENSE -> yazi/.config/yazi/plugins/chmod.yazi/LICENSE new file: yazi/.config/yazi/plugins/chmod.yazi/README.md new file: yazi/.config/yazi/plugins/chmod.yazi/main.lua new file: yazi/.config/yazi/plugins/eza-preview.yazi/LICENSE new file: yazi/.config/yazi/plugins/eza-preview.yazi/README.md new file: yazi/.config/yazi/plugins/eza-preview.yazi/main.lua modified: yazi/.config/yazi/plugins/fchar.yazi/README.md modified: yazi/.config/yazi/plugins/fchar.yazi/main.lua deleted: yazi/.config/yazi/plugins/file-extra-metadata.yazi/main.lua modified: yazi/.config/yazi/plugins/mediainfo.yazi/LICENSE modified: yazi/.config/yazi/plugins/mediainfo.yazi/README.md new file: yazi/.config/yazi/plugins/mediainfo.yazi/adobe-old.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/adobe-stable.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/audio-old.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/audio-stable.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/const.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/image-old.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/image-stable.lua modified: yazi/.config/yazi/plugins/mediainfo.yazi/main.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/none-media-preview-old.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/none-media-preview-stable.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/utils.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/video-old.lua new file: yazi/.config/yazi/plugins/mediainfo.yazi/video-stable.lua modified: yazi/.config/yazi/plugins/mime-ext.yazi/README.md new file: yazi/.config/yazi/plugins/mime-ext.yazi/local.lua modified: yazi/.config/yazi/plugins/mime-ext.yazi/main.lua new file: yazi/.config/yazi/plugins/mime-ext.yazi/remote.lua modified: yazi/.config/yazi/plugins/rich-preview.yazi/main.lua modified: yazi/.config/yazi/plugins/smart-enter.yazi/README.md deleted: yazi/.config/yazi/plugins/whoosh.yazi/.luarc.json modified: yazi/.config/yazi/plugins/whoosh.yazi/LICENSE deleted: yazi/.config/yazi/plugins/whoosh.yazi/README-RU.md modified: yazi/.config/yazi/plugins/whoosh.yazi/README.md modified: yazi/.config/yazi/plugins/whoosh.yazi/bookmarks deleted: yazi/.config/yazi/plugins/whoosh.yazi/image/history.png deleted: yazi/.config/yazi/plugins/whoosh.yazi/image/plugin.png modified: yazi/.config/yazi/plugins/whoosh.yazi/main.lua modified: yazi/.config/yazi/yazi.toml renamed: yazi/.config/yazi/plugins/full-border.yazi/LICENSE -> yazi_1/.config/yazi/flavors/catppuccin-mocha.yazi/LICENSE renamed: yazi/.config/yazi/flavors/catppuccin-mocha.yazi/LICENSE-tmtheme -> yazi_1/.config/yazi/flavors/catppuccin-mocha.yazi/LICENSE-tmtheme renamed: yazi/.config/yazi/flavors/catppuccin-mocha.yazi/README.md -> yazi_1/.config/yazi/flavors/catppuccin-mocha.yazi/README.md renamed: yazi/.config/yazi/flavors/catppuccin-mocha.yazi/flavor.toml -> yazi_1/.config/yazi/flavors/catppuccin-mocha.yazi/flavor.toml renamed: yazi/.config/yazi/flavors/catppuccin-mocha.yazi/preview.png -> yazi_1/.config/yazi/flavors/catppuccin-mocha.yazi/preview.png renamed: yazi/.config/yazi/flavors/catppuccin-mocha.yazi/tmtheme.xml -> yazi_1/.config/yazi/flavors/catppuccin-mocha.yazi/tmtheme.xml renamed: yazi/.config/yazi/flavors/dracula.yazi -> yazi_1/.config/yazi/flavors/dracula.yazi renamed: yazi/.config/yazi/flavors/everforest-medium.yazi/LICENSE -> yazi_1/.config/yazi/flavors/everforest-medium.yazi/LICENSE renamed: yazi/.config/yazi/flavors/everforest-medium.yazi/LICENSE-tmtheme -> yazi_1/.config/yazi/flavors/everforest-medium.yazi/LICENSE-tmtheme renamed: yazi/.config/yazi/flavors/everforest-medium.yazi/README.md -> yazi_1/.config/yazi/flavors/everforest-medium.yazi/README.md renamed: yazi/.config/yazi/flavors/everforest-medium.yazi/flavor.toml -> yazi_1/.config/yazi/flavors/everforest-medium.yazi/flavor.toml renamed: yazi/.config/yazi/flavors/everforest-medium.yazi/preview.png -> yazi_1/.config/yazi/flavors/everforest-medium.yazi/preview.png renamed: yazi/.config/yazi/flavors/everforest-medium.yazi/tmtheme.xml -> yazi_1/.config/yazi/flavors/everforest-medium.yazi/tmtheme.xml new file: yazi_1/.config/yazi/flavors/gruvbox-dark.yazi/LICENSE new file: yazi_1/.config/yazi/flavors/gruvbox-dark.yazi/LICENSE-tmtheme new file: yazi_1/.config/yazi/flavors/gruvbox-dark.yazi/README.md new file: yazi_1/.config/yazi/flavors/gruvbox-dark.yazi/flavor.toml new file: yazi_1/.config/yazi/flavors/gruvbox-dark.yazi/preview.png new file: yazi_1/.config/yazi/flavors/gruvbox-dark.yazi/tmtheme.xml renamed: yazi/.config/yazi/flavors/gruvbox-material.yazi/LICENSE -> yazi_1/.config/yazi/flavors/gruvbox-material.yazi/LICENSE renamed: yazi/.config/yazi/flavors/gruvbox-material.yazi/LICENSE-tmtheme -> yazi_1/.config/yazi/flavors/gruvbox-material.yazi/LICENSE-tmtheme renamed: yazi/.config/yazi/flavors/gruvbox-material.yazi/README.md -> yazi_1/.config/yazi/flavors/gruvbox-material.yazi/README.md renamed: yazi/.config/yazi/flavors/gruvbox-material.yazi/flavor.toml -> yazi_1/.config/yazi/flavors/gruvbox-material.yazi/flavor.toml renamed: yazi/.config/yazi/flavors/gruvbox-material.yazi/preview.png -> yazi_1/.config/yazi/flavors/gruvbox-material.yazi/preview.png renamed: yazi/.config/yazi/flavors/gruvbox-material.yazi/tmtheme.xml -> yazi_1/.config/yazi/flavors/gruvbox-material.yazi/tmtheme.xml renamed: yazi/.config/yazi/flavors/kanagawa.yazi/LICENSE -> yazi_1/.config/yazi/flavors/kanagawa.yazi/LICENSE renamed: yazi/.config/yazi/flavors/kanagawa.yazi/LICENSE-tmtheme -> yazi_1/.config/yazi/flavors/kanagawa.yazi/LICENSE-tmtheme renamed: yazi/.config/yazi/flavors/kanagawa.yazi/README.md -> yazi_1/.config/yazi/flavors/kanagawa.yazi/README.md renamed: yazi/.config/yazi/flavors/kanagawa.yazi/flavor.toml -> yazi_1/.config/yazi/flavors/kanagawa.yazi/flavor.toml renamed: yazi/.config/yazi/flavors/kanagawa.yazi/preview.png -> yazi_1/.config/yazi/flavors/kanagawa.yazi/preview.png renamed: yazi/.config/yazi/flavors/kanagawa.yazi/tmtheme.xml -> yazi_1/.config/yazi/flavors/kanagawa.yazi/tmtheme.xml renamed: yazi/.config/yazi/flavors/monokai.yazi/LICENSE -> yazi_1/.config/yazi/flavors/monokai.yazi/LICENSE renamed: yazi/.config/yazi/flavors/monokai.yazi/LICENSE-tmtheme -> yazi_1/.config/yazi/flavors/monokai.yazi/LICENSE-tmtheme renamed: yazi/.config/yazi/flavors/monokai.yazi/README.md -> yazi_1/.config/yazi/flavors/monokai.yazi/README.md renamed: yazi/.config/yazi/flavors/monokai.yazi/flavor.toml -> yazi_1/.config/yazi/flavors/monokai.yazi/flavor.toml renamed: yazi/.config/yazi/flavors/monokai.yazi/preview.png -> yazi_1/.config/yazi/flavors/monokai.yazi/preview.png renamed: yazi/.config/yazi/flavors/monokai.yazi/tmtheme.xml -> yazi_1/.config/yazi/flavors/monokai.yazi/tmtheme.xml renamed: yazi/.config/yazi/flavors/rose-pine-moon.yazi/LICENSE -> yazi_1/.config/yazi/flavors/rose-pine-moon.yazi/LICENSE renamed: yazi/.config/yazi/flavors/rose-pine-moon.yazi/LICENSE-tmtheme -> yazi_1/.config/yazi/flavors/rose-pine-moon.yazi/LICENSE-tmtheme renamed: yazi/.config/yazi/flavors/rose-pine-moon.yazi/README.md -> yazi_1/.config/yazi/flavors/rose-pine-moon.yazi/README.md renamed: yazi/.config/yazi/flavors/rose-pine-moon.yazi/flavor.toml -> yazi_1/.config/yazi/flavors/rose-pine-moon.yazi/flavor.toml renamed: yazi/.config/yazi/flavors/rose-pine-moon.yazi/preview.png -> yazi_1/.config/yazi/flavors/rose-pine-moon.yazi/preview.png renamed: yazi/.config/yazi/flavors/rose-pine-moon.yazi/tmtheme.xml -> yazi_1/.config/yazi/flavors/rose-pine-moon.yazi/tmtheme.xml renamed: yazi/.config/yazi/flavors/tokyo-night.yazi/LICENSE -> yazi_1/.config/yazi/flavors/tokyo-night.yazi/LICENSE renamed: yazi/.config/yazi/flavors/tokyo-night.yazi/LICENSE-tmtheme -> yazi_1/.config/yazi/flavors/tokyo-night.yazi/LICENSE-tmtheme renamed: yazi/.config/yazi/flavors/tokyo-night.yazi/README.md -> yazi_1/.config/yazi/flavors/tokyo-night.yazi/README.md renamed: yazi/.config/yazi/flavors/tokyo-night.yazi/flavor.toml -> yazi_1/.config/yazi/flavors/tokyo-night.yazi/flavor.toml renamed: yazi/.config/yazi/flavors/tokyo-night.yazi/preview.png -> yazi_1/.config/yazi/flavors/tokyo-night.yazi/preview.png renamed: yazi/.config/yazi/flavors/tokyo-night.yazi/tmtheme.xml -> yazi_1/.config/yazi/flavors/tokyo-night.yazi/tmtheme.xml new file: yazi_1/.config/yazi/init.lua new file: yazi_1/.config/yazi/keymap.toml renamed: yazi/.config/yazi/omp/omp.json -> yazi_1/.config/yazi/omp/omp.json renamed: yazi/.config/yazi/omp/omp.toml -> yazi_1/.config/yazi/omp/omp.toml renamed: yazi/.config/yazi/omp/omp2.toml -> yazi_1/.config/yazi/omp/omp2.toml renamed: yazi/.config/yazi/omp/omp_rose-pine.toml -> yazi_1/.config/yazi/omp/omp_rose-pine.toml new file: yazi_1/.config/yazi/package.toml renamed: yazi/.config/yazi/plugins/bunny.yazi/LICENSE -> yazi_1/.config/yazi/plugins/bunny.yazi/LICENSE renamed: yazi/.config/yazi/plugins/bunny.yazi/README.md -> yazi_1/.config/yazi/plugins/bunny.yazi/README.md renamed: yazi/.config/yazi/plugins/bunny.yazi/main.lua -> yazi_1/.config/yazi/plugins/bunny.yazi/main.lua renamed: yazi/.config/yazi/plugins/bypass.yazi/LICENSE -> yazi_1/.config/yazi/plugins/bypass.yazi/LICENSE renamed: yazi/.config/yazi/plugins/bypass.yazi/README.md -> yazi_1/.config/yazi/plugins/bypass.yazi/README.md renamed: yazi/.config/yazi/plugins/bypass.yazi/main.lua -> yazi_1/.config/yazi/plugins/bypass.yazi/main.lua renamed: yazi/.config/yazi/plugins/dupes.yazi/LICENSE -> yazi_1/.config/yazi/plugins/dupes.yazi/LICENSE renamed: yazi/.config/yazi/plugins/dupes.yazi/README.md -> yazi_1/.config/yazi/plugins/dupes.yazi/README.md renamed: yazi/.config/yazi/plugins/dupes.yazi/main.lua -> yazi_1/.config/yazi/plugins/dupes.yazi/main.lua renamed: yazi/.config/yazi/plugins/fazif.yazi/LICENSE -> yazi_1/.config/yazi/plugins/fazif.yazi/LICENSE renamed: yazi/.config/yazi/plugins/fazif.yazi/README.md -> yazi_1/.config/yazi/plugins/fazif.yazi/README.md renamed: yazi/.config/yazi/plugins/fazif.yazi/faziffd -> yazi_1/.config/yazi/plugins/fazif.yazi/faziffd renamed: yazi/.config/yazi/plugins/fazif.yazi/faziffdr -> yazi_1/.config/yazi/plugins/fazif.yazi/faziffdr renamed: yazi/.config/yazi/plugins/fazif.yazi/fazifrg -> yazi_1/.config/yazi/plugins/fazif.yazi/fazifrg renamed: yazi/.config/yazi/plugins/fazif.yazi/fazifrga -> yazi_1/.config/yazi/plugins/fazif.yazi/fazifrga renamed: yazi/.config/yazi/plugins/fazif.yazi/main.lua -> yazi_1/.config/yazi/plugins/fazif.yazi/main.lua new file: yazi_1/.config/yazi/plugins/fchar.yazi/LICENSE new file: yazi_1/.config/yazi/plugins/fchar.yazi/README.md new file: yazi_1/.config/yazi/plugins/fchar.yazi/main.lua renamed: yazi/.config/yazi/plugins/file-extra-metadata.yazi/LICENSE -> yazi_1/.config/yazi/plugins/file-extra-metadata.yazi/LICENSE renamed: yazi/.config/yazi/plugins/file-extra-metadata.yazi/README.md -> yazi_1/.config/yazi/plugins/file-extra-metadata.yazi/README.md new file: yazi_1/.config/yazi/plugins/file-extra-metadata.yazi/main.lua renamed: yazi/.config/yazi/plugins/git.yazi/LICENSE -> yazi_1/.config/yazi/plugins/full-border.yazi/LICENSE renamed: yazi/.config/yazi/plugins/full-border.yazi/README.md -> yazi_1/.config/yazi/plugins/full-border.yazi/README.md renamed: yazi/.config/yazi/plugins/full-border.yazi/main.lua -> yazi_1/.config/yazi/plugins/full-border.yazi/main.lua renamed: yazi/.config/yazi/plugins/mount.yazi/LICENSE -> yazi_1/.config/yazi/plugins/git.yazi/LICENSE renamed: yazi/.config/yazi/plugins/git.yazi/README.md -> yazi_1/.config/yazi/plugins/git.yazi/README.md renamed: yazi/.config/yazi/plugins/git.yazi/main.lua -> yazi_1/.config/yazi/plugins/git.yazi/main.lua renamed: yazi/.config/yazi/plugins/git.yazi/types.lua -> yazi_1/.config/yazi/plugins/git.yazi/types.lua renamed: yazi/.config/yazi/plugins/lazygit.yazi/LICENSE -> yazi_1/.config/yazi/plugins/lazygit.yazi/LICENSE renamed: yazi/.config/yazi/plugins/lazygit.yazi/README.md -> yazi_1/.config/yazi/plugins/lazygit.yazi/README.md renamed: yazi/.config/yazi/plugins/lazygit.yazi/main.lua -> yazi_1/.config/yazi/plugins/lazygit.yazi/main.lua renamed: yazi/.config/yazi/plugins/open-with-cmd.yazi/LICENSE -> yazi_1/.config/yazi/plugins/mediainfo.yazi/LICENSE new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/README.md new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/adobe-old.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/adobe-stable.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/assets/2025-02-15-09-14-23.png new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/assets/2025-02-15-09-15-39.png new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/assets/2025-02-15-16-51-11.png new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/assets/2025-02-15-16-52-39.png new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/audio-old.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/audio-stable.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/const.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/image-old.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/image-stable.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/main.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/none-media-preview-old.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/none-media-preview-stable.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/utils.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/video-old.lua new file: yazi_1/.config/yazi/plugins/mediainfo.yazi/video-stable.lua renamed: yazi/.config/yazi/plugins/piper.yazi/LICENSE -> yazi_1/.config/yazi/plugins/mime-ext.yazi/LICENSE new file: yazi_1/.config/yazi/plugins/mime-ext.yazi/README.md new file: yazi_1/.config/yazi/plugins/mime-ext.yazi/local.lua new file: yazi_1/.config/yazi/plugins/mime-ext.yazi/main.lua new file: yazi_1/.config/yazi/plugins/mime-ext.yazi/remote.lua renamed: yazi/.config/yazi/plugins/rsync.yazi/LICENSE -> yazi_1/.config/yazi/plugins/mount.yazi/LICENSE renamed: yazi/.config/yazi/plugins/mount.yazi/README.md -> yazi_1/.config/yazi/plugins/mount.yazi/README.md new file: yazi_1/.config/yazi/plugins/mount.yazi/cross.lua renamed: yazi/.config/yazi/plugins/mount.yazi/main.lua -> yazi_1/.config/yazi/plugins/mount.yazi/main.lua new file: yazi_1/.config/yazi/plugins/mount.yazi/sudo.lua renamed: yazi/.config/yazi/plugins/omp.yazi -> yazi_1/.config/yazi/plugins/omp.yazi renamed: yazi/.config/yazi/plugins/open-git-remote.yazi/LICENSE -> yazi_1/.config/yazi/plugins/open-git-remote.yazi/LICENSE renamed: yazi/.config/yazi/plugins/open-git-remote.yazi/README.md -> yazi_1/.config/yazi/plugins/open-git-remote.yazi/README.md renamed: yazi/.config/yazi/plugins/open-git-remote.yazi/main.lua -> yazi_1/.config/yazi/plugins/open-git-remote.yazi/main.lua new file: yazi_1/.config/yazi/plugins/open-with-cmd.yazi/LICENSE renamed: yazi/.config/yazi/plugins/open-with-cmd.yazi/README.md -> yazi_1/.config/yazi/plugins/open-with-cmd.yazi/README.md renamed: yazi/.config/yazi/plugins/open-with-cmd.yazi/main.lua -> yazi_1/.config/yazi/plugins/open-with-cmd.yazi/main.lua renamed: yazi/.config/yazi/plugins/ouch.yazi/LICENSE -> yazi_1/.config/yazi/plugins/ouch.yazi/LICENSE renamed: yazi/.config/yazi/plugins/ouch.yazi/README.md -> yazi_1/.config/yazi/plugins/ouch.yazi/README.md renamed: yazi/.config/yazi/plugins/ouch.yazi/main.lua -> yazi_1/.config/yazi/plugins/ouch.yazi/main.lua renamed: yazi/.config/yazi/plugins/toggle-pane.yazi/LICENSE -> yazi_1/.config/yazi/plugins/piper.yazi/LICENSE renamed: yazi/.config/yazi/plugins/piper.yazi/README.md -> yazi_1/.config/yazi/plugins/piper.yazi/README.md renamed: yazi/.config/yazi/plugins/piper.yazi/main.lua -> yazi_1/.config/yazi/plugins/piper.yazi/main.lua renamed: yazi/.config/yazi/plugins/projects.yazi/LICENSE -> yazi_1/.config/yazi/plugins/projects.yazi/LICENSE renamed: yazi/.config/yazi/plugins/projects.yazi/README.md -> yazi_1/.config/yazi/plugins/projects.yazi/README.md renamed: yazi/.config/yazi/plugins/projects.yazi/json.lua -> yazi_1/.config/yazi/plugins/projects.yazi/json.lua renamed: yazi/.config/yazi/plugins/projects.yazi/main.lua -> yazi_1/.config/yazi/plugins/projects.yazi/main.lua renamed: yazi/.config/yazi/plugins/recycle-bin.yazi/LICENSE -> yazi_1/.config/yazi/plugins/recycle-bin.yazi/LICENSE renamed: yazi/.config/yazi/plugins/recycle-bin.yazi/README.md -> yazi_1/.config/yazi/plugins/recycle-bin.yazi/README.md renamed: yazi/.config/yazi/plugins/recycle-bin.yazi/main.lua -> yazi_1/.config/yazi/plugins/recycle-bin.yazi/main.lua new file: yazi_1/.config/yazi/plugins/rich-preview.yazi/LICENSE new file: yazi_1/.config/yazi/plugins/rich-preview.yazi/README.md new file: yazi_1/.config/yazi/plugins/rich-preview.yazi/main.lua renamed: yazi/.config/yazi/plugins/vcs-files.yazi/LICENSE -> yazi_1/.config/yazi/plugins/rsync.yazi/LICENSE renamed: yazi/.config/yazi/plugins/rsync.yazi/README.md -> yazi_1/.config/yazi/plugins/rsync.yazi/README.md renamed: yazi/.config/yazi/plugins/rsync.yazi/assets/demo.gif -> yazi_1/.config/yazi/plugins/rsync.yazi/assets/demo.gif renamed: yazi/.config/yazi/plugins/rsync.yazi/assets/demo.webm -> yazi_1/.config/yazi/plugins/rsync.yazi/assets/demo.webm renamed: yazi/.config/yazi/plugins/rsync.yazi/main.lua -> yazi_1/.config/yazi/plugins/rsync.yazi/main.lua renamed: yazi/.config/yazi/plugins/simple-tag.yazi/LICENSE -> yazi_1/.config/yazi/plugins/simple-tag.yazi/LICENSE renamed: yazi/.config/yazi/plugins/simple-tag.yazi/README.md -> yazi_1/.config/yazi/plugins/simple-tag.yazi/README.md renamed: yazi/.config/yazi/plugins/simple-tag.yazi/main.lua -> yazi_1/.config/yazi/plugins/simple-tag.yazi/main.lua new file: yazi_1/.config/yazi/plugins/smart-enter.yazi/LICENSE new file: yazi_1/.config/yazi/plugins/smart-enter.yazi/README.md new file: yazi_1/.config/yazi/plugins/smart-enter.yazi/main.lua renamed: yazi/.config/yazi/plugins/smart-paste.yazi/LICENSE -> yazi_1/.config/yazi/plugins/smart-paste.yazi/LICENSE renamed: yazi/.config/yazi/plugins/smart-paste.yazi/README.md -> yazi_1/.config/yazi/plugins/smart-paste.yazi/README.md renamed: yazi/.config/yazi/plugins/smart-paste.yazi/main.lua -> yazi_1/.config/yazi/plugins/smart-paste.yazi/main.lua new file: yazi_1/.config/yazi/plugins/toggle-pane.yazi/LICENSE renamed: yazi/.config/yazi/plugins/toggle-pane.yazi/README.md -> yazi_1/.config/yazi/plugins/toggle-pane.yazi/README.md renamed: yazi/.config/yazi/plugins/toggle-pane.yazi/main.lua -> yazi_1/.config/yazi/plugins/toggle-pane.yazi/main.lua new file: yazi_1/.config/yazi/plugins/vcs-files.yazi/LICENSE renamed: yazi/.config/yazi/plugins/vcs-files.yazi/README.md -> yazi_1/.config/yazi/plugins/vcs-files.yazi/README.md renamed: yazi/.config/yazi/plugins/vcs-files.yazi/main.lua -> yazi_1/.config/yazi/plugins/vcs-files.yazi/main.lua renamed: yazi/.config/yazi/plugins/what-size.yazi/LICENSE -> yazi_1/.config/yazi/plugins/what-size.yazi/LICENSE renamed: yazi/.config/yazi/plugins/what-size.yazi/README.md -> yazi_1/.config/yazi/plugins/what-size.yazi/README.md renamed: yazi/.config/yazi/plugins/what-size.yazi/main.lua -> yazi_1/.config/yazi/plugins/what-size.yazi/main.lua new file: yazi_1/.config/yazi/plugins/whoosh.yazi new file: yazi_1/.config/yazi/plugins/wise-enter.yazi/LICENSE new file: yazi_1/.config/yazi/plugins/wise-enter.yazi/README.md new file: yazi_1/.config/yazi/plugins/wise-enter.yazi/main.lua renamed: yazi/.config/yazi/plugins/yafg.yazi/LICENSE -> yazi_1/.config/yazi/plugins/yafg.yazi/LICENSE renamed: yazi/.config/yazi/plugins/yafg.yazi/README.md -> yazi_1/.config/yazi/plugins/yafg.yazi/README.md renamed: yazi/.config/yazi/plugins/yafg.yazi/main.lua -> yazi_1/.config/yazi/plugins/yafg.yazi/main.lua renamed: yazi/.config/yazi/plugins/yaziline.yazi/LICENSE -> yazi_1/.config/yazi/plugins/yaziline.yazi/LICENSE renamed: yazi/.config/yazi/plugins/yaziline.yazi/README.md -> yazi_1/.config/yazi/plugins/yaziline.yazi/README.md renamed: yazi/.config/yazi/plugins/yaziline.yazi/main.lua -> yazi_1/.config/yazi/plugins/yaziline.yazi/main.lua renamed: yazi/.config/yazi/tags/home/liph/.local/share/Trash/files/tags.json -> yazi_1/.config/yazi/tags/home/liph/.local/share/Trash/files/tags.json renamed: yazi/.config/yazi/tags/home/liph/Downloads/tags.json -> yazi_1/.config/yazi/tags/home/liph/Downloads/tags.json renamed: yazi/.config/yazi/tags/home/liph/programming/webdev/html/static/tags.json -> yazi_1/.config/yazi/tags/home/liph/programming/webdev/html/static/tags.json new file: yazi_1/.config/yazi/tags/home/liph/scripts/tags.json renamed: yazi/.config/yazi/tags/home/liph/tags.json -> yazi_1/.config/yazi/tags/home/liph/tags.json new file: yazi_1/.config/yazi/yazi.toml
386 lines
13 KiB
Lua
386 lines
13 KiB
Lua
--- @since 25.5.28
|
|
local function debug(...)
|
|
local function toReadableString(val)
|
|
if type(val) == "table" then
|
|
local str = "{ "
|
|
for k, v in pairs(val) do
|
|
str = str .. "[" .. tostring(k) .. "] = " .. toReadableString(v) .. ", "
|
|
end
|
|
return str .. "}"
|
|
elseif type(val) == "Url" then
|
|
return "Url:" .. tostring(val)
|
|
else
|
|
return tostring(val)
|
|
end
|
|
end
|
|
local args = { ... }
|
|
local processed_args = {}
|
|
for _, arg in pairs(args) do
|
|
table.insert(processed_args, toReadableString(arg))
|
|
end
|
|
ya.dbg("BUNNY.YAZI", table.unpack(processed_args))
|
|
end
|
|
local function fail(s, ...) ya.notify { title = "bunny.yazi", content = string.format(s, ...), timeout = 4, level = "error" } end
|
|
local function info(s, ...) ya.notify { title = "bunny.yazi", content = string.format(s, ...), timeout = 2, level = "info" } end
|
|
|
|
local get_state = ya.sync(function(state, attr)
|
|
return state[attr]
|
|
end)
|
|
|
|
local set_state = ya.sync(function(state, attr, value)
|
|
state[attr] = value
|
|
end)
|
|
|
|
local get_cwd = ya.sync(function(state)
|
|
return tostring(cx.active.current.cwd) -- Url objects are evil >.<"
|
|
end)
|
|
|
|
local get_current_tab_idx = ya.sync(function(state)
|
|
return cx.tabs.idx
|
|
end)
|
|
|
|
local get_tabs_as_paths = ya.sync(function(state)
|
|
local tabs = cx.tabs
|
|
local active_tab_idx = tabs.idx
|
|
local result = {}
|
|
for idx = 1, #tabs, 1 do
|
|
if idx ~= active_tab_idx and tabs[idx] then
|
|
result[idx] = tostring(tabs[idx].current.cwd)
|
|
end
|
|
end
|
|
return result
|
|
end)
|
|
|
|
local some = function(...)
|
|
for _, v in ipairs({ ... }) do
|
|
if v ~= nil then
|
|
return v
|
|
end
|
|
end
|
|
end
|
|
|
|
local function filename(pathstr)
|
|
if pathstr == "/" then return pathstr end
|
|
local url_name = Url(pathstr):name()
|
|
if url_name then
|
|
return tostring(url_name)
|
|
else
|
|
return pathstr
|
|
end
|
|
end
|
|
|
|
local function path_to_desc(path, strategy)
|
|
if strategy == "filename" then
|
|
return filename(path)
|
|
end
|
|
local home = os.getenv("HOME")
|
|
if home and home ~= "" then
|
|
local startPos, endPos = string.find(path, home)
|
|
-- Only substitute if the match is from the start of path, very important
|
|
if startPos == 1 then
|
|
return "~" .. path:sub(endPos + 1)
|
|
end
|
|
end
|
|
return tostring(path)
|
|
end
|
|
|
|
local function sort_hops(hops)
|
|
local function convert_key(key)
|
|
local t = type(key)
|
|
if t == "table" then
|
|
-- If table, sort by first key string
|
|
return key[1]
|
|
elseif t == "string" and string.lower(key) ~= key then
|
|
-- If uppercase letter (signifying an ephemeral hop), prepend "z"
|
|
-- so it gets sorted after lowercase persistent hops
|
|
return "z" .. key
|
|
end
|
|
return key
|
|
end
|
|
table.sort(hops, function(x, y)
|
|
return convert_key(x.key) < convert_key(y.key)
|
|
end)
|
|
return hops
|
|
end
|
|
|
|
local create_special_hops = function(config)
|
|
local hops = {}
|
|
local desc_strategy, tabs, ephemeral = config.desc_strategy, config.tabs, config.ephemeral
|
|
if ephemeral then
|
|
table.insert(hops, { key = "<Enter>", desc = "Create hop", path = "__MARK__" })
|
|
end
|
|
table.insert(hops, { key = "<Space>", desc = "Fuzzy search", path = "__FUZZY__" })
|
|
local tabhist = get_state("tabhist")
|
|
local tab = get_current_tab_idx()
|
|
if tabhist[tab] and tabhist[tab][2] then
|
|
local previous_dir = tabhist[tab][2]
|
|
table.insert(hops, {
|
|
key = "<Backspace>",
|
|
path = previous_dir,
|
|
desc = path_to_desc(previous_dir, desc_strategy)
|
|
})
|
|
end
|
|
if tabs then
|
|
for idx, tab_path in pairs(get_tabs_as_paths()) do
|
|
table.insert(hops, {
|
|
key = tostring(idx),
|
|
path = tab_path,
|
|
desc = path_to_desc(tab_path, desc_strategy)
|
|
})
|
|
end
|
|
end
|
|
return hops
|
|
end
|
|
|
|
local function validate_options(options)
|
|
local function validate_key(key)
|
|
local kt = type(key)
|
|
if not key then
|
|
return false, "key is missing"
|
|
elseif kt == "string" then
|
|
if utf8.len(key) ~= 1 then
|
|
return false, "key must be single character"
|
|
end
|
|
elseif kt == "table" then
|
|
if #key == 0 then
|
|
return false, "key cannot be empty table"
|
|
end
|
|
for _, char in pairs(key) do
|
|
if utf8.len(char) ~= 1 then
|
|
return false, "key list must contain single characters"
|
|
end
|
|
end
|
|
else
|
|
return false, "key must be string or table"
|
|
end
|
|
return true, ""
|
|
end
|
|
if type(options) ~= "table" then
|
|
return "Invalid config"
|
|
end
|
|
local hops, desc_strategy, tabs, ephemeral, fuzzy_cmd, notify =
|
|
options.hops, options.desc_strategy, options.tabs,
|
|
options.ephemeral, options.fuzzy_cmd, options.notify
|
|
-- Validate hops
|
|
if type(hops) == "table" then
|
|
local used_keys = {}
|
|
for idx, hop in pairs(hops) do
|
|
hop.desc = hop.desc or hop.tag or nil -- used to be tag, allow for backwards compat
|
|
local key_is_validated, key_err = validate_key(hop.key)
|
|
local err = 'Invalid "hops" config value: #' .. idx .. " "
|
|
if not key_is_validated then
|
|
return err .. key_err
|
|
elseif not hop.path then
|
|
return err .. 'path is missing'
|
|
elseif type(hop.path) ~= "string" or string.len(hop.path) == 0 then
|
|
return err .. 'path must be non-empty string'
|
|
elseif hop.desc and (type(hop.desc) ~= "string" or string.len(hop.path) == 0) then
|
|
return err .. 'desc must be non-empty string'
|
|
end
|
|
-- Check for duplicate keys
|
|
if used_keys[hop.key] then
|
|
return err .. 'needs unique key'
|
|
end
|
|
-- Insert hop keys as table keys to easily check for set membership
|
|
used_keys[hop.key] = true
|
|
end
|
|
else
|
|
return 'Invalid "hops" config value'
|
|
end
|
|
-- Validate other options
|
|
if desc_strategy ~= nil and desc_strategy ~= "path" and desc_strategy ~= "filename" then
|
|
return 'Invalid "desc_strategy" config value'
|
|
elseif tabs ~= nil and type(notify) ~= "boolean" then
|
|
return 'Invalid "tabs" config value'
|
|
elseif ephemeral ~= nil and type(notify) ~= "boolean" then
|
|
return 'Invalid "ephemeral" config value'
|
|
elseif fuzzy_cmd ~= nil and type(fuzzy_cmd) ~= "string" then
|
|
return 'Invalid "fuzzy_cmd" config value'
|
|
elseif notify ~= nil and type(notify) ~= "boolean" then
|
|
return 'Invalid "notify" config value'
|
|
end
|
|
end
|
|
|
|
-- https://github.com/sxyazi/yazi/blob/main/yazi-plugin/preset/plugins/fzf.lua
|
|
-- https://github.com/sxyazi/yazi/blob/main/yazi-plugin/src/process/child.rs
|
|
-- Returns nil if fzf command failed or user exited with escape key
|
|
local select_fuzzy = function(hops, config)
|
|
local permit = ui.hide()
|
|
local child, spawn_err =
|
|
Command(config.fuzzy_cmd):stdin(Command.PIPED):stdout(Command.PIPED):stderr(Command.INHERIT):spawn()
|
|
if not child then
|
|
fail("Command `%s` failed with code %s. Do you have it installed?", config.fuzzy_cmd, spawn_err.code)
|
|
return
|
|
end
|
|
local fuzzy_entries = {}
|
|
for _, hop in pairs(hops) do
|
|
local existing_desc = fuzzy_entries[hop.path]
|
|
if not existing_desc or existing_desc == "" then
|
|
local fuzzy_desc = hop.desc
|
|
-- Avoid repeating path in description
|
|
if fuzzy_desc == hop.path then
|
|
fuzzy_desc = ""
|
|
end
|
|
fuzzy_entries[hop.path] = fuzzy_desc
|
|
end
|
|
end
|
|
-- Build fzf input string
|
|
local input_lines = {}
|
|
for entry_path, entry_desc in pairs(fuzzy_entries) do
|
|
local line = entry_desc .. string.rep(" ", 23 - #entry_desc) .. "\t" .. entry_path
|
|
table.insert(input_lines, line)
|
|
end
|
|
child:write_all(table.concat(input_lines, "\n"))
|
|
child:flush()
|
|
local output, output_err = child:wait_with_output()
|
|
permit:drop()
|
|
if not output.status.success then
|
|
if output.status.code ~= 130 then -- user pressed escape to quit
|
|
fail("Command `%s` failed with code %s", config.fuzzy_cmd, output_err.code)
|
|
end
|
|
return
|
|
end
|
|
-- Parse fzf output, remove right padded spaces from desc
|
|
local desc, path = string.match(output.stdout, "^(.-) *\t(.-)\n$")
|
|
if not desc or not path or path == "" then
|
|
fail("Failed to parse fuzzy searcher result")
|
|
return
|
|
end
|
|
if desc == "" then
|
|
desc = path_to_desc(path, config.desc_strategy)
|
|
end
|
|
return { desc = desc, path = path }
|
|
end
|
|
|
|
local cd = function(selected_hop, config)
|
|
local _, dir_list_err = fs.read_dir(Url(selected_hop.path), { limit = 1, resolve = true })
|
|
if dir_list_err then
|
|
fail("Invalid directory " .. path_to_desc(selected_hop.path))
|
|
return
|
|
end
|
|
-- Assuming that if I can fs.read_dir, then this will also succeed
|
|
ya.emit("cd", { selected_hop.path })
|
|
if config.notify then
|
|
info('Hopped to ' .. selected_hop.desc)
|
|
end
|
|
end
|
|
|
|
local attempt_hop = function(hops, config)
|
|
local cands = {}
|
|
for _, hop in pairs(create_special_hops(config)) do
|
|
table.insert(cands, { desc = hop.desc, on = hop.key, path = hop.path })
|
|
end
|
|
for _, hop in pairs(hops) do
|
|
table.insert(cands, { desc = hop.desc, on = hop.key, path = hop.path })
|
|
end
|
|
local hops_idx = ya.which { cands = cands }
|
|
if not hops_idx then return end
|
|
local selected_hop = cands[hops_idx]
|
|
-- Handle special hops
|
|
if selected_hop.path == "__MARK__" then
|
|
local mark_cands = {};
|
|
-- Ideally any unicode character would be supported, but yazi.which
|
|
-- requies a concrete list of candidates
|
|
local candidate_chars = {
|
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
|
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
|
|
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
|
'W', 'X', 'Y', 'Z', '`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
|
|
'-', '_', '=', '+', '[', '{', ']', '}', '\\', '|', ';', ':', "'", '"', ',', '<',
|
|
'.', '>', '/', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
|
|
}
|
|
for _, char in pairs(candidate_chars) do
|
|
table.insert(mark_cands, { on = char })
|
|
end
|
|
info("Press a key to create new hop")
|
|
local char_idx = ya.which { cands = mark_cands, silent = true }
|
|
if char_idx ~= nil then
|
|
local selected_char = mark_cands[char_idx].on
|
|
local cwd = get_cwd()
|
|
table.insert(hops, { key = selected_char, path = cwd, desc = path_to_desc(cwd, config.desc_strategy) })
|
|
set_state("hops", sort_hops(hops))
|
|
end
|
|
return
|
|
elseif selected_hop.path == "__FUZZY__" then
|
|
local fuzzy_hop = select_fuzzy(hops, config)
|
|
if not fuzzy_hop then return end
|
|
selected_hop = fuzzy_hop
|
|
end
|
|
cd(selected_hop, config)
|
|
end
|
|
|
|
local function init()
|
|
local options = get_state("options")
|
|
local err = validate_options(options)
|
|
if err then
|
|
set_state("init_error", err)
|
|
fail(err)
|
|
return
|
|
end
|
|
-- Set default config values
|
|
local desc_strategy = options.desc_strategy or "path"
|
|
set_state("config", {
|
|
desc_strategy = desc_strategy,
|
|
fuzzy_cmd = some(options.fuzzy_cmd, "fzf"),
|
|
notify = some(options.notify, false),
|
|
ephemeral = some(options.ephemeral, true),
|
|
tabs = some(options.tabs, true),
|
|
})
|
|
-- Set hops after ensuring they all have a description
|
|
local hops = {}
|
|
for _, hop in pairs(options.hops) do
|
|
hop.desc = hop.desc or path_to_desc(hop.path, desc_strategy)
|
|
-- Manually replace ~ from users so we can make a valid Url later to check if dir exists
|
|
if string.sub(hop.path, 1, 1) == "~" then
|
|
hop.path = os.getenv("HOME") .. hop.path:sub(2)
|
|
end
|
|
table.insert(hops, hop)
|
|
end
|
|
set_state("hops", sort_hops(hops))
|
|
set_state("init", true)
|
|
end
|
|
|
|
return {
|
|
setup = function(state, options)
|
|
state.options = options
|
|
ps.sub("cd", function(body)
|
|
-- Note: This callback is sync and triggered at startup!
|
|
local tab = body.tab -- type number
|
|
-- Very important to turn this into a string because Url has ownership issues
|
|
-- when passed to standard utility functions >.<'
|
|
-- https://github.com/sxyazi/yazi/issues/2159
|
|
local cwd = tostring(cx.active.current.cwd)
|
|
-- Upon startup this will be nil so initialize if necessary
|
|
local tabhist = state.tabhist or {}
|
|
-- tabhist structure:{ <tab_index> = { <current_dir>, <previous_dir?> }, ... }
|
|
if not tabhist[tab] then
|
|
-- If fresh tab, initialize tab history table
|
|
tabhist[tab] = { cwd }
|
|
else
|
|
-- Otherwise, shift history table to the right and add cwd to the front
|
|
tabhist[tab] = { cwd, tabhist[tab][1] }
|
|
end
|
|
state.tabhist = tabhist
|
|
end)
|
|
end,
|
|
entry = function(self, job)
|
|
if not get_state("init") then
|
|
init()
|
|
end
|
|
local init_error = get_state("init_error")
|
|
if init_error then
|
|
fail(init_error)
|
|
return
|
|
end
|
|
local hops, config = get_state("hops"), get_state("config")
|
|
if job.args[1] == "fuzzy" then
|
|
local fuzzy_hop = select_fuzzy(hops, config)
|
|
if fuzzy_hop then
|
|
cd(fuzzy_hop, config)
|
|
end
|
|
else
|
|
attempt_hop(hops, config)
|
|
end
|
|
end,
|
|
}
|