Compare commits

...

791 commits
v0.3.0 ... main

Author SHA1 Message Date
三咲雅 misaki masa
9accf929f4
feat: trash bin (#4144)
Some checks are pending
Cachix / Publish Flake (push) Waiting to run
Check / clippy (push) Waiting to run
Check / rustfmt (push) Waiting to run
Check / stylua (push) Waiting to run
Draft / build-unix (gcc-aarch64-linux-gnu, ubuntu-latest, aarch64-unknown-linux-gnu) (push) Waiting to run
Draft / build-unix (gcc-i686-linux-gnu, ubuntu-latest, i686-unknown-linux-gnu) (push) Waiting to run
Draft / build-unix (gcc-riscv64-linux-gnu, ubuntu-latest, riscv64gc-unknown-linux-gnu) (push) Waiting to run
Draft / build-unix (gcc-sparc64-linux-gnu, ubuntu-latest, sparc64-unknown-linux-gnu) (push) Waiting to run
Draft / build-unix (macos-latest, aarch64-apple-darwin) (push) Waiting to run
Draft / build-unix (macos-latest, x86_64-apple-darwin) (push) Waiting to run
Draft / build-unix (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Waiting to run
Draft / build-windows (windows-latest, aarch64-pc-windows-msvc) (push) Waiting to run
Draft / build-windows (windows-latest, x86_64-pc-windows-msvc) (push) Waiting to run
Draft / build-musl (aarch64-unknown-linux-musl) (push) Waiting to run
Draft / build-musl (x86_64-unknown-linux-musl) (push) Waiting to run
Draft / build-snap (amd64, ubuntu-latest) (push) Waiting to run
Draft / build-snap (arm64, ubuntu-24.04-arm) (push) Waiting to run
Draft / snap (push) Blocked by required conditions
Draft / draft (push) Blocked by required conditions
Draft / nightly (push) Blocked by required conditions
Test / test (macos-latest) (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
Test / test (windows-latest) (push) Waiting to run
2026-07-22 03:13:58 +08:00
nabsei
6aa75594db
docs: add a note about following the contribution guidelines in the PR template (#4140)
Co-authored-by: 三咲雅 misaki masa <sxyazi@gmail.com>
2026-07-21 08:59:20 +08:00
Omenabaka
60d94608cb
fix: magick preview of multiframe files (#4024)
Co-authored-by: 三咲雅 misaki masa <sxyazi@gmail.com>
2026-07-19 23:58:16 +08:00
三咲雅 misaki masa
52640fcece
feat: new hub VFS kind (#4131) 2026-07-17 03:04:19 +08:00
三咲雅 misaki masa
b25ae9f82d
fix: fail when package source is missing (#4124) 2026-07-14 01:11:34 +08:00
三咲雅 misaki masa
4dab480347
fix: preserve search results on refresh (#4123) 2026-07-13 22:51:42 +08:00
三咲雅 misaki masa
d39637f40c
feat!: support VFS services with same name but different schemes (#4120) 2026-07-13 20:01:47 +08:00
三咲雅 misaki masa
ddc6632505
fix: flush last input before submitting the completion (#4119) 2026-07-13 09:01:59 +08:00
三咲雅 misaki masa
6d84921e70
feat!: custom VFS provider (#4118) 2026-07-13 02:01:37 +08:00
三咲雅 misaki masa
dbb0cc0d55
feat: experimental %y, %Y, %t, %T, %yN, %YN, %tN, %TN shell formatting parameters (#4108) 2026-07-08 17:04:12 +08:00
三咲雅 misaki masa
aa850f9a3b
feat: input history (#4104) 2026-07-06 18:43:08 +08:00
三咲雅 misaki masa
c92c4aba88
feat: make visual mode support wraparound scrolling (#4101) 2026-07-05 18:06:25 +08:00
ebugusey
6e0aaee822
feat: add ya CLI completions to Windows package (#4099) 2026-07-03 22:09:57 +08:00
三咲雅 misaki masa
b8ceaea940
feat!: show file icons in trash/delete/overwrite confirmations (#4096) 2026-07-02 04:09:12 +08:00
三咲雅 misaki masa
21550a7eb5
feat: new target parameter for create action (#4088) 2026-06-28 02:10:23 +08:00
三咲雅 misaki masa
39527f488f
perf: switch memory allocator back to jemalloc (#4084) 2026-06-26 22:38:48 +08:00
三咲雅 misaki masa
de611b0e6b
perf: switch memory allocator to mimalloc (#4083) 2026-06-26 14:34:28 +08:00
三咲雅 misaki masa
ef654f4420
feat: context-aware icons for inputs (#4080) 2026-06-24 23:14:16 +08:00
Alastair
2a106aa231
fix: filter keybindings by chord in command palette (#4078)
Co-authored-by: Alastair Scheuermann <alastairsounds@users.noreply.github.com>
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-06-24 21:50:51 +08:00
SpiritCroc
b1ee2e72ff
feat: H/M/L Vim-like motion for moving cursor relative to viewport (#3970)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-06-24 17:42:20 +08:00
三咲雅 misaki masa
581886a355
feat!: make help menu a command palette (#4074) 2026-06-22 23:57:29 +08:00
三咲雅 misaki masa
4f45ddb514
fix: ignore NumLock state when comparing keybindings (#4071) 2026-06-20 23:57:12 +08:00
三咲雅 misaki masa
0ba1811af3
fix: use cleaned and normalized $PWD as startup CWD to avoid MSYS2/git-bash path quirks (#4068) 2026-06-20 12:47:00 +08:00
三咲雅 misaki masa
feeea673f1
fix: normalize \\?\-prefixed Verbatim paths when creating relative symlinks on Windows (#4067) 2026-06-20 12:07:33 +08:00
三咲雅 misaki masa
ef5db6e257
fix: sort interactive cd candidates case-insensitively so short exact matches match first (#4066) 2026-06-20 11:15:40 +08:00
三咲雅 misaki masa
0daa5df644
fix: use WebP as magick preset preloader cache format to keep image transparency (#4065) 2026-06-20 10:37:24 +08:00
三咲雅 misaki masa
6144d2748e
fix: keep package hashes indifferent to line endings when ya pkg pulls packages (#4064) 2026-06-20 09:34:41 +08:00
三咲雅 misaki masa
84a5be0b6a
feat: Lua API for printing escape sequences to the terminal (#4059) 2026-06-19 23:14:13 +08:00
Alastair
ab8d634f8e
fix: split graceful vs passive stop in terminal stream (#4055)
Co-authored-by: Alastair Scheuermann <alastairsounds@users.noreply.github.com>
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-06-19 09:30:52 +08:00
三咲雅 misaki masa
85132ff343
fix: quit once event stream closes in case terminal won't send a SIGHUP signal (#4052) 2026-06-18 21:21:38 +08:00
三咲雅 misaki masa
53d36b5186
refactor: switch to ratatui-core (#4050) 2026-06-18 16:23:26 +08:00
三咲雅 misaki masa
446a5721bf
refactor: move Lua bindings down into each subcrates (#4049) 2026-06-18 15:06:31 +08:00
三咲雅 misaki masa
f1e93d7f52
feat: new input DDS event watching changes in input content (#4043) 2026-06-14 19:58:23 +08:00
三咲雅 misaki masa
b37be0529a
feat: new ui.Input element (#4040) 2026-06-13 19:37:29 +08:00
三咲雅 misaki masa
9b920ed2e3
refactor: unify rendering behavior with a new renderer (#4038) 2026-06-11 20:44:22 +08:00
三咲雅 misaki masa
07a5deb109
feat: dynamic keymap Lua API (#4031) 2026-06-10 15:09:49 +08:00
Biswapriyo Nath
4086fbb166
feat(nix): shell completions for ya CLI (#4030) 2026-06-10 13:22:31 +08:00
sxyazi
9cfeb67db7
refactor: make Lua bindings Send (#4027) 2026-06-09 22:52:43 +08:00
三咲雅 misaki masa
f6113d3865
feat: advanced app overall style (#4023) 2026-06-07 21:46:07 +08:00
三咲雅 misaki masa
ea7fa2127c
perf: eliminate hacks in image and UI conflict resolution (#4022) 2026-06-06 14:35:12 +08:00
cyanyux
8a4b0b208e
fix(snap): make bundled magick find libgomp at runtime (#4016) 2026-06-06 13:53:59 +08:00
三咲雅 misaki masa
9bdd6777e4
feat: keymap Lua bindings (#4021) 2026-06-06 13:45:52 +08:00
三咲雅 misaki masa
8e80798984
feat: new gait for input backward and forward actions (#4012) 2026-06-01 13:16:01 +08:00
三咲雅 misaki masa
e892bf7d90
fix: decouple yazi_boot crate init from yazi_term init (#4011) 2026-05-31 13:07:11 +08:00
三咲雅 misaki masa
601cb10b32
feat: Unix domain socket on Windows as the underlying transport layer for DDS (#4009) 2026-05-29 15:33:03 +08:00
三咲雅 misaki masa
6c30430666
fix: a TOCTOU race condition while creating temporary directories (#4008) 2026-05-28 18:07:31 +08:00
三咲雅 misaki masa
7a51626505
feat: drag and drop (#4005) 2026-05-28 12:05:06 +08:00
三咲雅 misaki masa
cf8b54179e
feat: terminal drag and drop protocol (#3999) 2026-05-25 10:30:04 +08:00
三咲雅 misaki masa
f7fea2b19a
docs: update contributing guidelines 2026-05-25 09:31:04 +08:00
Dongda Li
d9cd1907d9
feat: image preview with Überzug++ on Niri (#3990)
Co-authored-by: 三咲雅 misaki masa <sxyazi@gmail.com>
2026-05-23 11:02:40 +08:00
JinHyuk Sung
5d643ee01a
fix: restrict preview cache directory permissions (#3984)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-05-22 18:56:19 +08:00
三咲雅 misaki masa
c037855c4f
feat!: new virtual terminal backend (#3989) 2026-05-22 17:00:06 +08:00
三咲雅 misaki masa
3f5cc47a48
fix: normalize main entry IDs for consistent internal sharing (#3966) 2026-05-15 07:30:38 +08:00
Daniel Vincent
fde563380b
feat: bulk create (#3793)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-05-12 02:12:08 +08:00
三咲雅 misaki masa
247f925e53
fix: get rid of the Cargo curse (#3952) 2026-05-10 00:57:57 +08:00
Immanuel Tikhonov
22fb9e0d09
fix: keep repeated ! negations in a condition right-associative (#3946)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-05-09 22:32:18 +08:00
三咲雅 misaki masa
92b9ea3794
fix: make the input component sync and reactive (#3949) 2026-05-09 09:26:07 +08:00
三咲雅 misaki masa
3968c4799c
docs: rename id of the fetcher rule to group (#3943) 2026-05-08 08:57:50 +08:00
三咲雅 misaki masa
aa526434f0
chore: bump to v26.5.6 (#3935) 2026-05-06 02:02:39 +08:00
三咲雅 misaki masa
10fc76db07
feat: custom styles for plugins (#3934) 2026-05-05 06:03:25 +08:00
三咲雅 misaki masa
5ad1e003f2
chore: use Tombi for TOML schema validation (#3932) 2026-05-05 01:37:17 +08:00
三咲雅 misaki masa
62dd22b8da
fix: put package cache in cache dir instead of state dir (#3930) 2026-05-02 22:15:25 +08:00
三咲雅 misaki masa
740d891989
feat: new key-close DDS event (#3925) 2026-05-01 23:09:13 +08:00
三咲雅 misaki masa
1caa5807c6
fix: mock OS-level reaping on Windows to avoid child processes potentially detached (#3922) 2026-04-30 18:50:51 +08:00
三咲雅 misaki masa
c4c533e3ef
feat: connect to SFTP servers with no authentication (#3916)
Co-authored-by: yadokani389 <155296849+yadokani389@users.noreply.github.com>
2026-04-26 16:07:11 +08:00
yadokani389
88848932fc
fix: use cspell package in devShell (#3912) 2026-04-26 15:27:21 +08:00
WINLAIC
a2996908de
feat: drag-resize panes with mouse (#3890)
Co-authored-by: Lingxuan Ye <yelingxuan@xiaomi.com>
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-04-22 19:35:19 +08:00
sxyazi
4a2e5addcd
feat: new app:theme action that hot-reload user themes/flavors (#3906) 2026-04-21 23:34:56 +08:00
三咲雅 misaki masa
369c47539c
feat: dynamic open/opener Lua API (#3901) 2026-04-19 16:58:57 +08:00
三咲雅 misaki masa
d1a27bca1f
feat: warn ya.mgr_emit() of its deprecation (#3902) 2026-04-19 16:51:56 +08:00
三咲雅 misaki masa
ae4c138f49
fix: paste --force doesn't work on existing read-only files with the same name (#3894) 2026-04-17 00:16:29 +08:00
sxyazi
463150848d
feat: dynamic previewer Lua API (#3891) 2026-04-16 17:05:46 +08:00
sxyazi
80a54c3dd5
fix: use u64 for parsing Linux partition blocks (#3873) 2026-04-11 09:25:17 +08:00
三咲雅 misaki masa
9abbc12212
docs: update readme 2026-04-11 08:12:19 +08:00
三咲雅 misaki masa
74d903a49a
feat: expose stash action and give it a new search source (#3872) 2026-04-11 07:59:38 +08:00
三咲雅 misaki masa
f6408656b4
fix!: make ui.Style immutable (#3862) 2026-04-07 11:06:31 +08:00
sxyazi
354cdef907
feat: hover cursor over the new file after extracting (#3854) 2026-04-06 15:32:18 +08:00
sxyazi
ec178fdb52
refactor: unify progress representation and add cleanup state (#3853) 2026-04-05 14:05:42 +08:00
三咲雅 misaki masa
4bb4f37555
refactor: simplify the remote progressive file copier (#3852) 2026-04-04 21:28:57 +08:00
三咲雅 misaki masa
0cedbd9c7b
feat: hover cursor over the new file after copying/cutting/linking/hardlinking (#3846) 2026-04-03 20:45:34 +08:00
sxyazi
ad655eda52
refactor: simplify FromStr implementations with strum 2026-04-03 09:13:52 +08:00
三咲雅 misaki masa
4857d46918
feat: make Action a deserializer (#3841) 2026-04-02 19:15:36 +08:00
三咲雅 misaki masa
6b143c1f4d
fix: enable sysfs files in the preset empty previewer (#3833) 2026-03-31 22:13:14 +08:00
三咲雅 misaki masa
4225c34fea
refactor: pull the process API out into yazi-binding crate (#3830) 2026-03-31 22:04:12 +08:00
三咲雅 misaki masa
607bc0dd2b
refactor: prepare for custom VFS provider (#3821) 2026-03-31 19:18:18 +08:00
Daniel Ramos Rodríguez
2514725e56
fix: handle file URIs in the desktop entry (#3827) 2026-03-31 10:50:12 +08:00
Omenabaka
935eb6b298
feat: allow active tab's inner separator to blend with its background (#3817) 2026-03-27 07:22:20 +08:00
sxyazi
b67798ea19
feat: Vim-like lua action that runs an inline Lua snippet (#3813) 2026-03-25 19:57:31 +08:00
三咲雅 misaki masa
5b2dd41e64
fix: ensure the status bar always has the directory length available (#3810) 2026-03-24 22:12:23 +08:00
三咲雅 misaki masa
e2fae151a5
refactor: simplify the text wrapper (#3808) 2026-03-24 20:14:04 +08:00
sxyazi
5c05350d52
perf: avoid unnecessary allocations in code highlighting (#3804) 2026-03-23 18:06:04 +08:00
三咲雅 misaki masa
d4924ebcad
fix: treat nfs4 mounts as soundless for directory refresh (#3800) 2026-03-22 06:36:34 +08:00
三咲雅 misaki masa
c703332b4b
feat: new bulk_exit action that customizes the prompt for bulk operations (#3792) 2026-03-21 17:26:44 +08:00
Mario Stief
7b61eb1595
feat: new --discard for ya pkg that discard local changes made to packages (#3781)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-03-20 15:47:06 +08:00
三咲雅 misaki masa
a246e9c7c0
feat: make cmp component follow input cursor (#3784) 2026-03-19 21:19:10 +08:00
三咲雅 misaki masa
cc2414728c
feat: new ya.exec() API and ya exec subcommand to execute an action and await its result (#3780) 2026-03-18 19:18:36 +08:00
三咲雅 misaki masa
6a1ddb71e0
feat: deserialize from Data (#3778) 2026-03-18 14:13:23 +08:00
sxyazi
da96795303
refactor: make Clippy happy 2026-03-17 09:41:46 +08:00
三咲雅 misaki masa
de01a56ac5
fix: use edit opener for files with MIME application/wine-extension-ini (#3771) 2026-03-16 13:29:03 +08:00
三咲雅 misaki masa
d22c96b69c
perf: reuse previewed and spotted widgets when possible (#3765) 2026-03-15 15:18:58 +08:00
三咲雅 misaki masa
fa1ee46edc
refactor: implement FromLua instead of TryFrom<Value> (#3760) 2026-03-13 20:28:44 +08:00
三咲雅 misaki masa
3534ba0705
feat: new experimental ya.co() API that creates a coroutine (#3757) 2026-03-12 16:18:30 +08:00
三咲雅 misaki masa
e4829372db
feat: link to the quick-start in yazi --help where lists all common keybinds (#3754) 2026-03-11 13:34:11 +08:00
三咲雅 misaki masa
1be991ec72
docs: update image 2026-03-11 13:06:06 +08:00
IcEarthlight
dee27a2377
feat: new ind-hidden and key-hidden DDS events to change hidden status in Lua (#3748)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-03-10 12:56:07 +08:00
三咲雅 misaki masa
8932ddd66d
perf: preset multi spotter only updates sizes for folders to cut memory usage (#3751) 2026-03-10 12:39:19 +08:00
itsvyle
741f84e22b
feat: certificate authentication for SFTP VFS provider (#3716)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-03-07 15:45:27 +08:00
三咲雅 misaki masa
f10b8910ad
fix: be a little defensive while parsing the output of 7zz -ba (#3744) 2026-03-06 23:09:40 +08:00
Daniel Vincent
dbf81deeab
feat: multi-file spotter (#3733)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-03-06 09:27:32 +08:00
三咲雅 misaki masa
be91b4111c
fix: shift of auto-wrap points in both code and JSON previewers (#3739) 2026-03-05 20:16:03 +08:00
三咲雅 misaki masa
9648d8a43b
fix: wrong intersection check in preview and spot rendering (#3736) 2026-03-04 15:36:13 +08:00
Yashank
b92b576ce1
feat: new hovered condition specifying different icons for hovered files (#3728)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-03-03 20:18:55 +08:00
bitbloxhub
0efeaf5f64
chore: update flake inputs (#3731) 2026-03-03 09:41:15 +08:00
三咲雅 misaki masa
0a83f0bd27
feat: keep span info when config parsing fails (#3727) 2026-03-02 16:47:28 +08:00
三咲雅 misaki masa
3cdc3ecb70
feat: new hey DDS event fires when static messages are restored from persistence (#3725) 2026-02-28 13:01:03 +08:00
三咲雅 misaki masa
884c265de1
fix: avoid blocking on read-half of the watch channel (#3721) 2026-02-26 20:36:22 +08:00
三咲雅 misaki masa
05aeae3b09
fix: ensure cargo-deb picks up the right build artifacts (#3720) 2026-02-26 14:18:00 +08:00
三咲雅 misaki masa
9eb4d03a44
feat: dual watcher for local files (#3713) 2026-02-26 08:16:58 +08:00
三咲雅 misaki masa
0bb6379a2a
docs: update readme 2026-02-26 08:08:36 +08:00
三咲雅 misaki masa
8b773a62a5
fix: make group order of files from flat view stable on select (#3712) 2026-02-23 19:01:04 +08:00
三咲雅 misaki masa
16aa3cd0fc
fix: escape backslashes in ImageMagick font path parameter (#3708) 2026-02-22 19:59:47 +08:00
三咲雅 misaki masa
d84f0b1265
refactor: async Command over emitting shell actions (#3706) 2026-02-22 10:31:15 +08:00
三咲雅 misaki masa
e49cdfe220
fix: fallback in Windows casefold for MS-DOS devices (#3700) 2026-02-19 13:22:14 +08:00
三咲雅 misaki masa
9af792ef69
feat: new --in for search action to set search directory (#3696) 2026-02-18 17:16:05 +08:00
三咲雅 misaki masa
578016e00f
refactor: use the term "action" instead of "command" (#3694) 2026-02-18 17:08:48 +08:00
三咲雅 misaki masa
7f339381f1
feat: new marker_symbol option to specify the symbol used for marking files (#3689) 2026-02-16 21:42:36 +08:00
三咲雅 misaki masa
31cfc58188
feat: new download DDS event fires when remote files are downloaded (#3687) 2026-02-16 12:52:58 +08:00
SuniRein
c0f96f553b
feat: new sort_fallback option to control fallback sorting behavior (#3077)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-02-15 14:00:58 +08:00
三咲雅 misaki masa
13bdb164a4
feat!: new ind-app-title DDS event to customize the app title (#3684) 2026-02-13 13:03:44 +08:00
三咲雅 misaki masa
c3bc4fecad
fix: Chafa v1.18.1 causes random ghost keypresses when previewing images (#3678) 2026-02-12 00:12:42 +08:00
三咲雅 misaki masa
98b1614016
feat: new fs.unique() creates a unique file or directory (#3677) 2026-02-11 12:51:49 +08:00
三咲雅 misaki masa
a8a4b684a1
feat: deduplicate empty directories in preset archive previewer (#3676) 2026-02-11 11:07:23 +08:00
三咲雅 misaki masa
30ec603441
refactor: async fs.access() instead of sync io.open() (#3670) 2026-02-10 11:29:46 +08:00
三咲雅 misaki masa
1a121bbfb0
feat: new fs.access() API to access the filesystem (#3668) 2026-02-09 08:50:01 +08:00
三咲雅 misaki masa
0aeeb3b0f7
feat!: custom tab name (#3666) 2026-02-08 10:46:38 +08:00
sxyazi
dc66f79cef
feat!: finer control over concurrent workers (#3661) 2026-02-06 22:27:08 +08:00
三咲雅 misaki masa
6757fed5aa
feat: new which:dismiss command to dismiss the which component (#3654) 2026-02-02 02:53:02 +08:00
sxyazi
339002ee48
fix: make ya pkg ignore default remote name in user Git config (#3648) 2026-01-31 18:43:25 +08:00
sxyazi
a015d4a7ef
feat: new relay-notify-push DDS event to allow custom notification handlers (#3642) 2026-01-31 09:25:17 +08:00
三咲雅 misaki masa
dfdb235d74
feat: allow using ps.sub() in init.lua directly without a plugin (#3638) 2026-01-30 10:12:21 +08:00
三咲雅 misaki masa
1ea0ea072c
refactor: move Lua bindings into their own yazi-binding crate (#3636) 2026-01-29 23:12:29 +08:00
三咲雅 misaki masa
eaeda8b4fa
perf: reduce memory allocations by using Lua 5.5 external strings (#3634) 2026-01-29 07:58:15 +08:00
三咲雅 misaki masa
cfd9a22125
feat!: upgrade Lua to 5.5 (#3633) 2026-01-29 01:08:22 +08:00
三咲雅 misaki masa
6d942ea011
feat: subscribe to and intercept app-level events through DDS (#3632) 2026-01-29 00:34:28 +08:00
三咲雅 misaki masa
583345296f
refactor: move Term to its own yazi-term crate (#3629) 2026-01-28 22:26:47 +08:00
三咲雅 misaki masa
24c60419bb
refactor: new yazi-emulator crate (#3624) 2026-01-27 22:37:34 +08:00
三咲雅 misaki masa
e0911f2507
refactor: new yazi-tty crate (#3623) 2026-01-27 22:03:48 +08:00
三咲雅 misaki masa
6150571738
fix: ignore target-dir to avoid deadlocks during cargo install (#3620) 2026-01-27 08:49:39 +08:00
三咲雅 misaki masa
592e70a1c9
feat: new cx.which API to access the which component state (#3617) 2026-01-27 01:29:14 +08:00
三咲雅 misaki masa
06c665a086
fix: account for border when calculating message widths (#3615) 2026-01-26 17:23:57 +08:00
三咲雅 misaki masa
92880b844b
refactor: make command data cloneable (#3613) 2026-01-26 07:36:35 +08:00
三咲雅 misaki masa
face6aed40
feat: new ind-which-show DDS event to change the which component behavior (#3608) 2026-01-25 03:06:50 +08:00
Ciarán O'Brien
afc694c122
fix: archive extraction fails for target paths with non-ASCII characters on Windows (#3607)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-24 18:03:51 +08:00
Jared Cervantes
49b8324bbf
fix: remove duplicate categories in the .desktop file (#3602)
Signed-off-by: Jared Cervantes <jared@jaredcervantes.com>
2026-01-23 21:14:41 +08:00
sxyazi
4e0acf8cbf
chore: bump version to 26.1.22 2026-01-22 23:31:21 +08:00
三咲雅 misaki masa
d17e7e14cd
feat: experimental module-level async support (#3594) 2026-01-21 19:19:39 +08:00
三咲雅 misaki masa
e6d995710f
fix: properly drop the permit for terminal resources (#3592) 2026-01-20 18:25:02 +08:00
sxyazi
ca4cc59413
fix: make environment detection work on WSL 2 (#3587) 2026-01-19 01:08:15 +08:00
AminurAlam
97d0c6bb23
fix: sort extension excludes directories since only files have extensions (#3582) 2026-01-18 01:09:47 +08:00
三咲雅 misaki masa
a38a5e6377
fix: set orphan=true for xdg-open to work around its odd behavior with programs that are both CLI/GUI (#3581) 2026-01-17 23:03:08 +08:00
三咲雅 misaki masa
756964b10a
fix: build error on NetBSD (#3506) 2026-01-17 13:11:25 +08:00
WindFade
8a909697f8
feat: disable ANSI escape sequences in ya pkg when stdout is not a TTY (#3566)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-16 14:03:27 +08:00
Marcus Geiger
798d38e494
feat: re-enable the TIFF feature (#3573)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-16 13:53:26 +08:00
sxyazi
0fc343b95a
fix: merge duplicate top directories in archive previews 2026-01-15 14:38:32 +08:00
三咲雅 misaki masa
0c8c973e6c
feat: check and refresh the file list when the terminal gains focus (#3561) 2026-01-13 16:53:00 +08:00
sxyazi
41e5717930
chore: update icons 2026-01-11 19:00:50 +08:00
三咲雅 misaki masa
babc80d842
feat: exclude Apple Resource Forks (__MACOSX) from archive preview (#3548) 2026-01-11 18:16:05 +08:00
itsvyle
233d721e7c
feat: tree view for the preset archive previewer (#3525)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-11 13:20:43 +08:00
三咲雅 misaki masa
16d20e2171
feat: new Path.os() API creates an OS-native Path (#3541) 2026-01-09 19:51:37 +08:00
三咲雅 misaki masa
b1dd185692
fix: smart-case in interactive cd broken due to a typo (#3540) 2026-01-09 08:00:55 +08:00
三咲雅 misaki masa
ebedab3e29
fix: shell formatting for non-spread opener rules (#3532) 2026-01-08 17:04:53 +08:00
itsvyle
83674f19b4
feat: support compressed tarballs (.tar.gz, .tar.bz2, etc.) in the preset archive previewer (#3518)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-08 15:35:29 +08:00
Gabriel Wicke
c6e1702c61
fix: trust directory stats outside of Linux and macOS (#3528)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-08 15:34:36 +08:00
Gabriel Wicke
30ac041d9e
refactor: make partition heuristic predicate a positive match (#3526) 2026-01-08 02:25:50 +08:00
三咲雅 misaki masa
c9327ca851
fix: account for URL covariance in Url:join() (#3514) 2026-01-06 11:55:48 +08:00
sxyazi
3c39a326ab
chore: bump version to 26.1.4 (#3498) 2026-01-04 12:35:06 +08:00
三咲雅 misaki masa
e611de5284
fix: make the SFTP VFS provider's create_dir() and create_new() correctly report "file exists" errors (#3495) 2026-01-03 19:01:38 +08:00
三咲雅 misaki masa
81c66a645f
fix: a race condition generating unique filenames for concurrent file operations (#3494) 2026-01-03 16:40:49 +08:00
leiserfg
a6fcbb04df
Support 8-bit images in RGB, CIELAB, and GRAY color spaces (#3358)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-02 22:57:06 +08:00
Integral
0000141700
fix: ya pkg fails to write package.toml when the config directory does not exist (#3482)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2026-01-01 09:25:23 +08:00
三咲雅 misaki masa
456b88d660
feat: support VFS for preset previewers that rely on external commands (#3477) 2026-01-01 09:13:56 +08:00
三咲雅 misaki masa
f31147d246
chore: bump version to 25.12.29 (#3471) 2025-12-29 08:21:43 +08:00
三咲雅 misaki masa
faf33e1b03
fix: stricter casefold matching (#3470) 2025-12-28 16:05:06 +08:00
三咲雅 misaki masa
77d36ff5a5
feat: new fs.copy() and fs.rename() APIs (#3467) 2025-12-27 17:52:15 +08:00
Francesco Marchisotti
c5a3e42986
feat: ISO 8601 date format for spotter (#3465)
Co-authored-by: 三咲雅 misaki masa <sxyazi@gmail.com>
2025-12-27 08:00:22 +08:00
三咲雅 misaki masa
366fca6b10
perf: raise the max allowed concurrent connections per SFTP service (#3466) 2025-12-27 07:40:30 +08:00
三咲雅 misaki masa
2f66561a82
fix: Command:output() should set stderr to piped instead of stdin (#3458) 2025-12-24 16:18:11 +08:00
三咲雅 misaki masa
8c81172a19
feat: new duplicate DDS event for copying files (#3456) 2025-12-24 13:28:38 +08:00
sxyazi
6e3c96289e
feat: make task post-hooks stateful (#3454) 2025-12-24 01:15:18 +08:00
三咲雅 misaki masa
329c5d28f0
fix: a race condition when terminal resumes while signal system is restarting (#3448) 2025-12-19 18:46:38 +08:00
三咲雅 misaki masa
e7cd66370f
fix: avoid UI-dependent async APIs from being called during app initialization to avoid deadlocks (#3445) 2025-12-19 00:21:13 +08:00
三咲雅 misaki masa
e9eb8b9155
fix: unify path expansion and absolutization behavior (#3438) 2025-12-17 23:00:05 +08:00
三咲雅 misaki masa
80b3b8465d
perf: immediate task cancellation (#3429) 2025-12-14 21:02:22 +08:00
三咲雅 misaki masa
5fe58ba2b1
feat: include context in error logs when a task fails (#3427) 2025-12-13 19:43:29 +08:00
三咲雅 misaki masa
ac7718c226
feat: new experimental ya.async() API (#3422) 2025-12-11 01:10:28 +08:00
Matthieu Coudron
85a99937a1
feat: install manpages from flake (#3417) 2025-12-09 22:55:24 +08:00
三咲雅 misaki masa
55ef88b726
feat!: rounded corners for indicator bar (#3419) 2025-12-09 22:25:01 +08:00
三咲雅 misaki masa
396f634bb8
fix: add preset VFS config file to avoid TOML parsing errors (#3414) 2025-12-08 16:24:19 +08:00
三咲雅 misaki masa
9ae8b90d23
feat: prioritize symbolic links when cutting remote files (#3412) 2025-12-07 18:00:49 +08:00
三咲雅 misaki masa
d2e9e72684
refactor: pull directory traversal out into a function (#3411) 2025-12-07 01:28:45 +08:00
三咲雅 misaki masa
c569263a50
fix: always follow symlinks when pasting remote files (#3406) 2025-12-05 23:46:23 +08:00
sxyazi
205b7fe11f
refactor: rename the "provider" term in VFS config to "service" (#3403) 2025-12-05 15:04:39 +08:00
三咲雅 misaki masa
dccc9b2c2a
fix: escape control characters in filenames (#3400) 2025-12-04 16:13:39 +08:00
三咲雅 misaki masa
c6e03e91d2
feat: remote filesystem support for interactive cd (#3398) 2025-12-03 17:06:42 +08:00
三咲雅 misaki masa
c7739c5941
feat: remote file management (#3396) 2025-12-02 19:33:27 +08:00
rezky_nightky
878b74acb7
docs: little typo in CHANGELOG (#3394) 2025-12-02 18:38:09 +08:00
三咲雅 misaki masa
44e244b9d6
perf: concurrent chunked upload and download of a single file over SFTP (#3393) 2025-12-01 22:39:36 +08:00
三咲雅 misaki masa
d910104c00
fix: errors out if the target package directory doesn't exist previously (#3392) 2025-12-01 11:11:00 +08:00
三咲雅 misaki masa
d0adb9c015
feat: new ind-sort and key-sort DDS events to change sorting in Lua (#3391) 2025-12-01 10:51:27 +08:00
三咲雅 misaki masa
0fb652d2ec
feat: new null plugin as a general-purpose error handler (#3387) 2025-11-30 14:44:17 +08:00
三咲雅 misaki masa
76196aab70
refactor!: return Path instead of Url from File.link_to (#3385) 2025-11-30 12:08:59 +08:00
三咲雅 misaki masa
ade1025a74
feat: timeouts for SFTP operations (#3384) 2025-11-29 15:02:25 +08:00
三咲雅 misaki masa
81ccdd8b64
feat: include stderr along with existing error code when video preview fails (#3383) 2025-11-29 10:06:05 +08:00
sxyazi
0b8aaba29b
refactor: make Clippy happy 2025-11-29 07:39:04 +08:00
三咲雅 misaki masa
8c2a6dba90
feat: check if already in visual mode before entering visual mode (#3381) 2025-11-29 05:27:35 +08:00
三咲雅 misaki masa
a8f2498471
feat: new stash command to let users customize back and forward command behavior (#3380) 2025-11-29 05:27:17 +08:00
三咲雅 misaki masa
3561867b99
feat: WTF-8 validator (#3374) 2025-11-27 16:01:06 +08:00
三咲雅 misaki masa
329c80cbee
feat: support Unix path backend for the SFTP provider (#3371) 2025-11-26 17:27:52 +08:00
三咲雅 misaki masa
a1fb206a59
feat: ya.quote() support escaping strings containing invalid UTF-8 (#3369) 2025-11-26 08:57:35 +08:00
三咲雅 misaki masa
2d55c9427d
fix: prevent quotes in file(1) arguments from being stripped under MSYS2 (#3364) 2025-11-25 09:10:11 +08:00
XYenon
c725c91df1
fix(nix): shell env (#3363) 2025-11-24 19:55:41 +08:00
sxyazi
449450d0db
feat!: introduce Path as a subset of Url to enforce type safety (#3361) 2025-11-24 15:23:06 +08:00
sxyazi
76fe6d7244
fix: user-prepended open rules do not override presets (#3360) 2025-11-24 12:30:52 +08:00
三咲雅 misaki masa
e5ee31cb7e
feat: new Unix path backend (#3359) 2025-11-24 11:35:10 +08:00
三咲雅 misaki masa
a08b345a02
docs: document the applicability of all yazi-* crates (#3345) 2025-11-20 09:00:01 +08:00
三咲雅 misaki masa
d3ad1c0920
refactor: refine PathLike and StrandLike traits (#3340) 2025-11-19 18:07:04 +08:00
walldmtd
9cd742811a
fix: -flatten flag should come after the input file in preset ImageMagick previewer (#3339)
Co-authored-by: 三咲雅 misaki masa <sxyazi@gmail.com>
2025-11-19 13:26:35 +08:00
三咲雅 misaki masa
f9abe886cc
feat: multi-path architecture (#3334) 2025-11-18 13:56:20 +08:00
Zane Weissman
577065cbd0
feat: new overall option to set the overall background color (#3317) 2025-11-12 12:41:13 +08:00
三咲雅 misaki masa
4b56e73235
feat: dynamic paths (#3316) 2025-11-06 18:01:02 +08:00
Ruowen
cc8f9a7177
fix(nix): bump flake.lock to fix build failure due to rust-overlay (#3314)
Signed-off-by: Ruowen Qin <chinqrw@gmail.com>
2025-11-06 17:15:27 +08:00
三咲雅 misaki masa
587950bb5b
fix: u16 instead of u32 as the type of max_width and max_height options (#3313) 2025-11-05 08:53:30 +08:00
三咲雅 misaki masa
97c63e2708
fix: make file counter more distinguishable in dark mode (#3311) 2025-11-05 01:20:56 +08:00
三咲雅 misaki masa
604b86612a
refactor: simplify paths (#3297) 2025-10-31 20:26:26 +08:00
Pui Yong Qing
b766cff69f
fix: follow upstream renaming of poppler_utils to poppler-utils in Nix flake (#3296) 2025-10-31 20:11:59 +08:00
三咲雅 misaki masa
a3e9ea0d16
refactor: generalize Loc, LocBuf, Uri, and Urn (#3295) 2025-10-30 19:37:46 +08:00
三咲雅 misaki masa
564b885196
feat: ya emit and ya emit-to support invalid UTF-8 as command argument values (#3290) 2025-10-28 20:37:26 +08:00
三咲雅 misaki masa
440e67164a
feat: respect the user's image_filter setting for the preset magick previewer (#3286) 2025-10-28 00:30:09 +08:00
三咲雅 misaki masa
ff5f656a31
feat: add CHANGELOG.md (#3285) 2025-10-27 20:06:26 +08:00
三咲雅 misaki masa
c11ed02760
fix: fallback to PollWatcher instead of panicking when RecommendedWatcher initialization fails (#3281) 2025-10-27 13:11:30 +08:00
Carlos Eduardo
641bc6ff47
fix: make nix-shell use the nightly Rust toolchain (#3267) 2025-10-26 12:38:19 +08:00
三咲雅 misaki masa
157156b5b8
fix: a race condition in concurrent directory loading on a slow device (#3271) 2025-10-22 12:16:41 +08:00
sxyazi
b16c4894dc
docs: remove dead Hyper from the list of terminals supporting image preview
Fixes #3269
2025-10-22 12:12:59 +08:00
三咲雅 misaki masa
4b08e8d899
feat: new mimetype fetcher dedicated to remote files (#3268) 2025-10-21 15:14:08 +08:00
Kryštof Gärtner
4e32044450
feat: new casefy command for case conversion (#3235)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-10-20 14:42:47 +08:00
三咲雅 misaki masa
782ecb16b2
feat!: live editing of remote files (#3264) 2025-10-20 13:48:57 +08:00
三咲雅 misaki masa
46569a1f48
fix: disable kitty keyboard protocol on Windows due to crossterm inability to handle it (#3250) 2025-10-16 21:45:49 +08:00
三咲雅 misaki masa
e067a705ac
feat: new download/upload commands to cache/sync remote or local files to the peer (#3243) 2025-10-16 01:22:55 +08:00
三咲雅 misaki masa
c68e2df8c0
feat: encode SFTP paths on Windows in a revised WTF-8 (#3238) 2025-10-13 19:50:46 +08:00
三咲雅 misaki masa
554cb52cc5
feat: shell formatting (#3232) 2025-10-06 23:44:32 +08:00
三咲雅 misaki masa
cd6881c9fe
feat: support task initialization failure status (#3227) 2025-10-03 22:35:48 +08:00
三咲雅 misaki masa
149a5feffb
fix!: open command doesn't work under empty directories (#3226) 2025-10-03 18:18:27 +08:00
三咲雅 misaki masa
d8b0425a10
fix: incorrect $0 and $@ parameters in shell command under empty directories (#3225) 2025-10-03 17:18:39 +08:00
三咲雅 misaki masa
4d39194cd8
feat!: folder mime-type support (#3222) 2025-10-01 20:03:41 +08:00
三咲雅 misaki masa
879ed49996
feat: filesystem-level error (#3217) 2025-09-28 23:08:48 +08:00
三咲雅 misaki masa
7b36b7fe14
refactor: invert the dependency relationship between yazi-fs and yazi-vfs (#3215) 2025-09-28 15:50:25 +08:00
三咲雅 misaki masa
25d5554a9a
fix: wrong architecture label in aarch64 .deb packages (#3209) 2025-09-26 19:05:48 +08:00
三咲雅 misaki masa
51635996e0
fix: only create mapped local working directories for virtual file systems (#3207) 2025-09-26 17:48:41 +08:00
三咲雅 misaki masa
d905cbf2d7
feat: dedicated mime fetcher, previewer, and spotter for VFS (#3203) 2025-09-25 21:52:27 +08:00
三咲雅 misaki masa
6b09f2b665
feat: casefold support for the SFTP provider (#3201) 2025-09-24 23:33:45 +08:00
三咲雅 misaki masa
9f39363dd4
fix: renew package rev only when it's empty (#3200) 2025-09-24 20:17:16 +08:00
三咲雅 misaki masa
f3e029ec25
feat: include $FZF_DEFAULT_COMMAND in debug output (#3199) 2025-09-24 19:53:13 +08:00
三咲雅 misaki masa
86f0885737
feat: SFTP connection pool (#3198) 2025-09-24 19:49:37 +08:00
sxyazi
9a804bac9c
fix: do not passthrough DECRQM query to tmux 2025-09-23 19:05:30 +08:00
三咲雅 misaki masa
c0c0877d42
fix: record the follow state of symlink correctly (#3195) 2025-09-23 15:12:18 +08:00
三咲雅 misaki masa
e9742cb809
fix: check compatibility when reusing previewer bytecode cache (#3190) 2025-09-21 23:33:30 +08:00
三咲雅 misaki masa
8f9cce126c
feat: new --bg specifying image background color for the preset svg and magick previewers (#3189) 2025-09-21 22:18:00 +08:00
WhoSowSee
ba99ce4f8f
feat: unify the password input visually when extracting archives (#3179) 2025-09-21 11:48:17 +08:00
三咲雅 misaki masa
4e3ac54c8e
feat: new yazi-vfs crate (#3187) 2025-09-21 11:44:52 +08:00
三咲雅 misaki masa
30c0279570
feat: introduce ChaType for better cross-filesystem consistency (#3175) 2025-09-18 07:20:19 +08:00
三咲雅 misaki masa
ece59974fe
refactor: use Cha for better cross-platform consistency (#3174) 2025-09-17 23:18:54 +08:00
三咲雅 misaki masa
6cfa92f112
feat: SFTP virtual filesystem provider (#3172) 2025-09-17 08:34:35 +08:00
三咲雅 misaki masa
7deeaa4356
feat: size calculator for remote file systems (#3170) 2025-09-15 22:41:17 +08:00
三咲雅 misaki masa
a3fc9a0ec7
fix: force Git checkout for plugin cache repositories (#3169) 2025-09-14 19:42:30 +08:00
三咲雅 misaki masa
4a3710b1c4
feat: new yazi-sftp crate (#3166) 2025-09-14 02:50:28 +08:00
Phil Clifford
f0502a46b7
fix: add fd as a dependency to the .deb packaging workflow (#3128) 2025-09-13 11:30:49 +08:00
三咲雅 misaki masa
01fd967fa3
fix: DECSCUSR over DECSET 12 (#3165) 2025-09-13 11:03:08 +08:00
三咲雅 misaki masa
3713478753
feat: multi-entry support for plugin system (#3154) 2025-09-08 23:38:10 +08:00
三咲雅 misaki masa
fa0e7e62c1
feat: cosmetic work for the "URL" and "repository" spelling (#3152) 2025-09-08 22:09:49 +08:00
sxyazi
81a0cf4a1e
ci: enable Dependabot 2025-09-06 23:40:06 +08:00
adamnemecek
021d86f0d1
refactor: use Self where possible (#3138) 2025-09-06 00:48:30 +08:00
三咲雅 misaki masa
e795d6cf42
feat: offload mimetype fetching on opening files to the task scheduler (#3141) 2025-09-06 00:18:31 +08:00
yuvals1
3c42195bac
fix: generate unique image IDs for Kgp to tolerate tmux (#3038)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-09-04 22:53:57 +08:00
Cattyman
49910fcfe7
feat: progress of each task (#3121)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-09-04 18:55:28 +08:00
三咲雅 misaki masa
b997e56a60
fix: Windows path length may exceed MAX_PATH (#3137) 2025-09-04 17:02:18 +08:00
三咲雅 misaki masa
cfc7238638
feat: port task manager to Lua (#3134) 2025-09-03 22:25:16 +08:00
三咲雅 misaki masa
d670da80d3
fix: make casefold work when ancestor directories are symbolic links (#3132) 2025-09-03 00:15:57 +08:00
三咲雅 misaki masa
d7df581b67
feat: tasks without progress (#3131) 2025-09-02 16:58:34 +08:00
Copilot
eb537733a2
fix: Darwin framework deprecation in Nix build (#3119)
Co-authored-by: sxyazi <17523360+sxyazi@users.noreply.github.com>
2025-08-28 23:26:01 +08:00
三咲雅 misaki masa
8a0265ad64
perf: zero-copy UrlBuf to Url conversion (#3117) 2025-08-28 23:06:04 +08:00
三咲雅 misaki masa
dd7afaa64a
refactor: Url::pair() without allocation (#3116) 2025-08-27 23:52:09 +08:00
三咲雅 misaki masa
c2a94daad6
feat: casefold (#3114) 2025-08-27 15:55:35 +08:00
三咲雅 misaki masa
12172b7301
feat: support VFS for the file watcher (#3108) 2025-08-25 21:40:38 +08:00
三咲雅 misaki masa
c27ef58116
feat: support VFS for join(), starts_with(), and ends_with() of Url (#3094) 2025-08-23 23:06:11 +08:00
三咲雅 misaki masa
0054cf0b87
perf: lock-free hashing for string interns (#3091) 2025-08-21 09:40:52 +08:00
三咲雅 misaki masa
84907297a0
perf: string interning to reduce memory usage of mimetype and URL domain (#3084) 2025-08-19 21:58:57 +08:00
三咲雅 misaki masa
7a9bfff95d
perf: switch to a higher-performance hash algorithm (#3083) 2025-08-19 15:58:39 +08:00
三咲雅 misaki masa
ae75fc0f7b
feat: make mimetype matching more robust (#3082) 2025-08-19 15:17:32 +08:00
三咲雅 misaki masa
fe9ce240b5
fix: respect URL covariance when updating mimetypes (#3079) 2025-08-18 23:20:03 +08:00
boydaihungst
a41931275c
fix: erase overlapping image portions when previewing errors (#3067)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-08-18 19:55:28 +08:00
三咲雅 misaki masa
3ca33c1f84
refactor: introduce UrlBuf (#3072) 2025-08-18 02:25:59 +08:00
三咲雅 misaki masa
9810196565
refactor: introduce LocBuf (#3062) 2025-08-17 16:25:04 +08:00
三咲雅 misaki masa
2ec3a6c645
fix: avoid appending a newline when reading clipboard contents (#3059) 2025-08-14 11:26:46 +08:00
三咲雅 misaki masa
1bfcbc1664
feat: introduce the concept of Uri (#3049) 2025-08-13 01:38:43 +08:00
Raphael Amorim
a9bfeeeaad
docs: update Rio image support status (#3052)
Co-authored-by: 三咲雅 misaki masa <sxyazi@gmail.com>
2025-08-13 00:53:00 +08:00
三咲雅 misaki masa
a109aa92e7
refactor: refine URN for archives (#3043) 2025-08-11 01:02:53 +08:00
三咲雅 misaki masa
292d37ccde
refactor: simplify cursor repositioning (#3040) 2025-08-08 02:41:41 +08:00
三咲雅 misaki masa
41b00c8d4e
feat: allow DDS events to change command arguments (#3037) 2025-08-06 22:23:22 +08:00
三咲雅 misaki masa
0b45ed868f
feat: VFS support for the enter and leave commands (#3035) 2025-08-05 20:45:23 +08:00
三咲雅 misaki masa
d5f225bc4a
feat: virtual file system (#3034) 2025-08-05 02:23:57 +08:00
三咲雅 misaki masa
da97e5a8b4
feat: URL covariance for the mimetype agency (#3030) 2025-07-31 00:48:54 +08:00
三咲雅 misaki masa
9adc00c3a9
fix: keep original scheme when expanding URLs (#3028) 2025-07-30 02:08:17 +08:00
三咲雅 misaki masa
9c1f303f2c
feat: URL covariance for selected and yanked files (#3025) 2025-07-29 15:03:22 +08:00
三咲雅 misaki masa
9535caad5b
fix: make URLs with invalid UTF-8 serializable (#3023) 2025-07-28 17:21:47 +08:00
三咲雅 misaki masa
0e3cd8545c
feat: URL schemas (#3019) 2025-07-27 18:06:13 +08:00
三咲雅 misaki masa
c2883f1e05
refactor: pull filesystem calls out into a designated yazi_fs crate (#3013) 2025-07-23 22:43:11 +08:00
Andrew Rabert
1f596a01fc
feat: new bulk_rename command always renames files with the editor (#2984)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-07-23 15:02:01 +08:00
三咲雅 misaki masa
bfe12c8052
fix: suspend only when there is a parent process (#3008) 2025-07-21 14:42:10 +08:00
三咲雅 misaki masa
74bd98031e
feat: key-* DDS events to allow canceling user key commands (#3005) 2025-07-20 14:11:57 +08:00
三咲雅 misaki masa
c28d2e8180
refactor: eliminate the tab conceptual hierarchy (#2999) 2025-07-18 14:31:16 +08:00
三咲雅 misaki masa
0fd74ae44c
perf!: cacheable iterator (#2997) 2025-07-18 07:48:00 +08:00
三咲雅 misaki masa
5f8a1496fe
refactor: invert the dependency relationship between yazi-parser and yazi-proxy (#2992) 2025-07-16 22:46:10 +08:00
三咲雅 misaki masa
548bb0d063
refactor: upgrade to mlua v0.11.0 (#2989) 2025-07-16 11:02:34 +08:00
三咲雅 misaki masa
60a2382087
refactor: switch to actor model (#2986) 2025-07-14 23:08:11 +08:00
三咲雅 misaki masa
6366e46c23
refactor: use term "core" instead of "context" (#2978) 2025-07-11 09:00:22 +08:00
三咲雅 misaki masa
c9c85130e1
refactor: pull DDS events out into a macro (#2977) 2025-07-11 08:55:56 +08:00
三咲雅 misaki masa
18795320bb
fix: stringify!(r#move) is "r#move" instead of "move" (#2973) 2025-07-10 10:33:43 +08:00
Euclid Ye
bc9dbd35e3
feat: new "Show media info" for play opener on Windows (#2962) 2025-07-10 00:38:59 +08:00
simonborje
559a46e399
feat: make ticket optional for cmp:trigger (#2968)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-07-10 00:12:51 +08:00
三咲雅 misaki masa
452b435b71
feat: allow dynamic adjustment of layout ratio via rt.mgr.ratio (#2964) 2025-07-08 23:59:50 +08:00
Euclid Ye
5f7c0e813f
fix: respect user's system media opener instead of hardcoding mpv (#2959)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-07-07 21:44:55 +08:00
三咲雅 misaki masa
917e1f54a1
perf: do not listen for file changes in inactive tabs (#2958) 2025-07-06 22:27:56 +08:00
三咲雅 misaki masa
52ecb31f5a
refactor: introduce the SStr type for static strings (#2957) 2025-07-06 22:16:29 +08:00
三咲雅 misaki masa
a426d449f4
refactor: new yazi-parser crate (#2956) 2025-07-06 19:17:00 +08:00
三咲雅 misaki masa
ec7eb3e416
fix: fallback to PollWatcher on NetBSD (#2941) 2025-07-03 21:41:49 +08:00
Sebastian Hjelm
39f50c898b
fix: expose ya CLI in the Snap build (#2904) 2025-07-03 17:10:03 +08:00
三咲雅 misaki masa
ffdd74b6ab
refactor: move several UI-related APIs from the ya namespace to ui (#2939) 2025-07-03 15:58:51 +08:00
三咲雅 misaki masa
4ff7dae721
fix: Cargo doesn't respect .cargo/config.toml for the crates (#2936) 2025-06-30 23:18:30 +08:00
三咲雅 misaki masa
5a66559d1c
feat: improve the UX of the input component (#2935) 2025-06-30 16:27:25 +08:00
三咲雅 misaki masa
8657e6b6f5
feat: display newlines in input as spaces to improve readability (#2932) 2025-06-28 23:59:29 +08:00
TKperson
a8a1b5625b
fix: preserve open order for files with post-resolved mime-types (#2931)
Co-authored-by: TKperson <TKperson@users.noreply.github.com>
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-06-28 18:07:59 +08:00
三咲雅 misaki masa
8ef28ec678
refactor: deprecate ui.Rect.default (#2927) 2025-06-27 23:03:16 +08:00
三咲雅 misaki masa
e16c0da547
feat: allow custom mouse click behavior for individual files (#2925) 2025-06-27 20:50:19 +08:00
Yuriy Poltorak
2768fd22b1
feat: support .deb packages (#2807)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-06-27 17:43:59 +08:00
三咲雅 misaki masa
2d1cf621db
fix: incomplete cache calculation algorithm (#2922) 2025-06-26 20:12:54 +08:00
三咲雅 misaki masa
9d05946f4b
feat!: make ya.confirm() and ui.Pos() public API (#2921) 2025-06-26 18:12:09 +08:00
三咲雅 misaki masa
590d336716
feat: fill in error messages if preview fails (#2917) 2025-06-24 16:47:39 +08:00
三咲雅 misaki masa
e218f1d8bb
feat: filter by full path (prefix + filename) in search view instead of just filename (#2915) 2025-06-24 13:29:34 +08:00
三咲雅 misaki masa
1ed244a0a5
perf: store only Urn instead of full Url in find results (#2914) 2025-06-24 13:13:51 +08:00
三咲雅 misaki masa
ab0fe93150
feat: improve the UX of the pick component (#2906) 2025-06-22 21:23:46 +08:00
三咲雅 misaki masa
3a9591a3d9
feat: improve error handling in config file reading (#2901) 2025-06-21 22:23:59 +08:00
三咲雅 misaki masa
f5d0f47b51
fix: Cargo doesn't respect the workspace profile settings (#2899) 2025-06-21 14:58:58 +08:00
三咲雅 misaki masa
1a6abae974
feat: invalid UTF-8 support to Command:arg() and Command:env() APIs (#2895) 2025-06-18 22:01:36 +08:00
三咲雅 misaki masa
750ca0c0d4
fix: throw catchable errors instead of crashing when publishing a message containing invalid UTF-8 over DDS (#2893) 2025-06-18 19:30:31 +08:00
三咲雅 misaki masa
a0ce7c0ae7
refactor: reuse ordered-float as it's already in the dependency tree (#2891) 2025-06-18 13:29:39 +08:00
三咲雅 misaki masa
002b742cd9
feat: support tables with invalid UTF-8 keys in sendable data (#2890) 2025-06-18 10:46:31 +08:00
三咲雅 misaki masa
ec90f26ac3
feat: allow Url to accept invalid UTF-8 characters (#2889) 2025-06-17 18:24:43 +08:00
Mika Vilpas
c8148d2d75
fix: out-of-bounds error with empty backstack (#2887) 2025-06-17 08:29:46 +08:00
三咲雅 misaki masa
a0ab614108
fix: proper invalid UTF-8 path support (#2884) 2025-06-16 21:25:39 +08:00
三咲雅 misaki masa
56a4e87d7e
fix: interoperability between number, integer, and id (#2883) 2025-06-16 13:18:07 +08:00
三咲雅 misaki masa
a076ff8c82
refactor: satisfy mismatched-lifetime-syntaxes lint (#2881) 2025-06-16 11:52:35 +08:00
三咲雅 misaki masa
52d37fa25d
perf: app data instead of Lua registry to reduce stack pushes (#2880) 2025-06-16 11:25:02 +08:00
三咲雅 misaki masa
51560c30b7
perf: do not pre-allocate memory for Lua tables (#2879) 2025-06-16 11:19:18 +08:00
三咲雅 misaki masa
917fee939f
perf: make preload tasks discardable (#2875) 2025-06-14 16:13:48 +08:00
三咲雅 misaki masa
aae3f9ea4a
refactor: promote Id to the task scheduler (#2873) 2025-06-14 12:07:22 +08:00
三咲雅 misaki masa
0eec8fc80e
feat: zoom in or out of the preview image (#2864) 2025-06-11 15:24:11 +08:00
三咲雅 misaki masa
414d46fd16
perf: copy-on-write on command data & avoid converting primitive types to strings thereby allocating memory (#2862) 2025-06-11 10:13:51 +08:00
三咲雅 misaki masa
0752b53298
perf: sequence-based rendering merge strategy (#2861) 2025-06-11 08:49:05 +08:00
三咲雅 misaki masa
693dff25e3
feat: search view shares file selection and yank state (#2855) 2025-06-09 16:55:50 +08:00
Axlefublr
c0615e5f45
feat: port several widespread GUI keys to the input component (#2849)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-06-09 08:22:13 +08:00
三咲雅 misaki masa
b637c32ef7
feat: increase terminal response timeout to better tolerate slow SSH network environments (#2843) 2025-06-05 23:03:46 +08:00
三咲雅 misaki masa
d55e002d5a
fix: cd on the initial creation of a tab should not be added to the backstack (#2842) 2025-06-05 20:11:37 +08:00
三咲雅 misaki masa
145349b0e6
feat: allow upgrading only specific packages (#2841) 2025-06-05 19:46:49 +08:00
Ruowen
20446544ef
fix(nix): missing ffmpeg and resvg dependencies (#2825)
Signed-off-by: Ruowen Qin <chinqrw@gmail.com>
2025-06-04 00:08:18 +08:00
三咲雅 misaki masa
f866d75ef0
fix: incomplete hidden state check on Windows for Cha (#2835) 2025-06-03 23:54:50 +08:00
三咲雅 misaki masa
2d95221f59
perf: use AnyUserData::type_id() to reduce stack pushes (#2834) 2025-06-03 23:40:23 +08:00
三咲雅 misaki masa
d5038eeed5
perf: reduce file change event frequency (#2820) 2025-06-01 09:20:17 +08:00
三咲雅 misaki masa
b65a88075a
chore: bump version to 25.5.31 (#2815) 2025-05-31 00:39:47 +08:00
三咲雅 misaki masa
4fdc0f120f
fix: make every effort to carry hidden states for dummy files (#2814) 2025-05-31 00:08:50 +08:00
三咲雅 misaki masa
4076e35a2f
fix: forward --end-of-word of the input should consider the mode's delta (#2811) 2025-05-30 18:50:00 +08:00
三咲雅 misaki masa
e6471b7fe0
fix: expose ui.Wrap (#2810) 2025-05-30 18:14:57 +08:00
三咲雅 misaki masa
5cb6e1f224
chore: bump version to 25.5.28 (#2804) 2025-05-28 20:48:57 +08:00
三咲雅 misaki masa
8a4d495132
refactor!: deprecate [manager] in favor of [mgr] (#2803) 2025-05-28 20:41:56 +08:00
三咲雅 misaki masa
d7716cab44
feat: new ui.Align, ui.Wrap, and ui.Edge (#2802) 2025-05-28 16:49:47 +08:00
三咲雅 misaki masa
74a8ea9bc0
fix: update rust-onig to v6.5.1 for GCC 15 compatibility (#2794) 2025-05-26 16:46:23 +08:00
三咲雅 misaki masa
622ba09a80
refactor: use raw identifiers (#2783) 2025-05-21 17:32:41 +08:00
三咲雅 misaki masa
c6fcb4f799
feat: make custom tab bar easier (#2782) 2025-05-21 13:56:52 +08:00
Eugene Diachkin
546920e049
feat: add a / to the interactive cd auto-completion candidates (#2777)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-05-19 23:32:36 +08:00
三咲雅 misaki masa
b6ae5d3ca9
feat: truncate long paths in archive preview file list (#2778) 2025-05-19 23:23:40 +08:00
三咲雅 misaki masa
70e459a011
feat: new ya pkg subcommand (#2770) 2025-05-17 18:25:05 +08:00
三咲雅 misaki masa
358524347f
fix: always try to create state directory before draining DDS data (#2769) 2025-05-17 14:25:08 +08:00
三咲雅 · Misaki Masa
746c7f5ce9
chore: bump Rust version to 1.86.0 (#2766) 2025-05-16 16:55:03 +08:00
三咲雅 · Misaki Masa
ffc635e434
feat: improve path auto-completion results (#2765) 2025-05-16 16:37:04 +08:00
三咲雅 · Misaki Masa
e257581fe7
perf: remove intermediate variables in natural sorting algorithm to avoid unnecessary allocation (#2764) 2025-05-16 16:26:22 +08:00
三咲雅 · Misaki Masa
464acfe47b
feat: show file extension for truncated file list items (#2759) 2025-05-15 14:34:10 +08:00
三咲雅 · Misaki Masa
9a0ef6bb20
fix: icon rules mixing (#2755) 2025-05-14 16:31:21 +08:00
三咲雅 · Misaki Masa
5a4e6e4068
feat: truncate long items in the file list (#2754) 2025-05-14 02:03:54 +08:00
三咲雅 · Misaki Masa
cea2628a19
perf: avoid unnecessary memory allocation in ya.truncate() (#2753) 2025-05-14 01:34:16 +08:00
三咲雅 · Misaki Masa
55f69fbfee
refactor: deprecate the Command:args() method (#2752) 2025-05-14 01:29:03 +08:00
三咲雅 · Misaki Masa
ea90b0477e
feat!: redesign tabs (#2745) 2025-05-11 12:11:29 +08:00
三咲雅 · Misaki Masa
41cba40072
feat: make ui.Line renderable (#2743) 2025-05-10 11:50:06 +08:00
Kreijstal
3ae7673274
fix: windows-sys missing a Win32_Security feature (#2728)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-05-07 09:57:35 +08:00
三咲雅 · Misaki Masa
4e2a8bdf51
fix: avoid tmux interfering with kitty graphical sequences (#2734) 2025-05-07 09:54:20 +08:00
三咲雅 · Misaki Masa
db60951783
fix: detach background and orphan processes from the controlling terminal with setsid() (#2723) 2025-05-05 16:11:25 +08:00
三咲雅 · Misaki Masa
ca96c5bd98
feat: increase the granularity of back/forward history navigation to make its behavior more sensible (#2720) 2025-05-05 02:21:28 +08:00
三咲雅 · Misaki Masa
c53865788a
fix: missing a hover event after cd (#2719) 2025-05-05 01:18:09 +08:00
sxyazi
a201c93419
docs: add icon contribution guide 2025-05-03 02:17:11 +08:00
hankertrix
5da39722e4
feat: add --hovered to the copy command (#2709)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-05-02 20:02:40 +08:00
Mika Vilpas
37e8747c01
fix: ya pub-to 0 checks if any peer is able to receive the message (#2697)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-05-02 19:12:40 +08:00
三咲雅 · Misaki Masa
01a13fd664
fix: reset the cursor position with arrow() after deleting files (#2708) 2025-05-02 02:35:19 +08:00
三咲雅 · Misaki Masa
9037f8b8c0
feat!: 9x faster Sixel image preview (#2707) 2025-05-02 00:47:27 +08:00
三咲雅 · Misaki Masa
d6a01a63ef
feat: show error when image preview fails (#2706) 2025-05-01 22:58:24 +08:00
三咲雅 · Misaki Masa
8ed569b729
refactor: move tty to the new yazi-term crate (#2701) 2025-04-30 23:22:52 +08:00
三咲雅 · Misaki Masa
13a515c0ed
fix: no title is set when starts the first time (#2700) 2025-04-30 22:26:27 +08:00
hankertrix
9d92cdbf79
feat: add s and S keybinds in the input component (#2678)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-04-30 02:04:38 +08:00
三咲雅 · Misaki Masa
fbf8345d90
feat: checks in ya pub and ya emit subcommands to verify receiver exists and has necessary abilities (#2696) 2025-04-30 00:24:29 +08:00
三咲雅 · Misaki Masa
eba9f1e4f0
feat: calculate real-time directory size in spotter (#2695) 2025-04-29 22:17:06 +08:00
三咲雅 · Misaki Masa
54687181b3
feat: promote Id to a first-class type (#2692) 2025-04-28 23:52:23 +08:00
三咲雅 · Misaki Masa
2c99075ffa
feat: new fs.calc_size() API (#2691) 2025-04-28 21:56:08 +08:00
三咲雅 · Misaki Masa
6a9e7da8a3
perf: double directory size calculation speed (#2683) 2025-04-28 19:51:12 +08:00
三咲雅 · Misaki Masa
5ffe74109c
feat: increase the maximum allowed value of sixel_fraction to 30 (#2682) 2025-04-27 18:42:57 +08:00
三咲雅 · Misaki Masa
9e9ebf0745
feat: obscure input component for inputting passwords (#2675) 2025-04-25 07:15:51 +08:00
三咲雅 · Misaki Masa
bfad57d86f
feat: new --no-dummy option for reveal command (#2664) 2025-04-22 22:22:33 +08:00
三咲雅 · Misaki Masa
a29dbb9f06
feat: make the hover state for reveal, sort, and hidden commands stable (#2657) 2025-04-22 02:46:01 +08:00
三咲雅 · Misaki Masa
7169e19ff0
feat: fine-grained peek and watch (#2655) 2025-04-21 21:04:31 +08:00
三咲雅 · Misaki Masa
8327826217
feat: new ya.emit() API (#2653) 2025-04-21 19:28:52 +08:00
三咲雅 · Misaki Masa
6bd7a8039a
refactor: switch to Rust 2024 edition (#2645) 2025-04-20 23:41:05 +08:00
三咲雅 · Misaki Masa
0b90a7268a
fix: lazily update files to avoid triggering issues dependent on sort order (#2643) 2025-04-20 14:26:30 +08:00
三咲雅 · Misaki Masa
88bbbac7dd
feat: support embedded cover for video preview (#2640) 2025-04-19 23:13:11 +08:00
sxyazi
ce23dcd81b
ci: musl build should include commit hash 2025-04-19 01:31:40 +08:00
三咲雅 · Misaki Masa
c38be35250
feat: fall back to CSI 16 t when PowerShell OpenSSH returns a fake terminal size (#2636) 2025-04-18 03:00:53 +08:00
三咲雅 · Misaki Masa
510cb14ab6
feat: copy-on-write support for field caching (#2629) 2025-04-16 20:08:12 +08:00
三咲雅 · Misaki Masa
56d6e4a71e
fix: do not change revision when package deployment fails (#2627) 2025-04-16 17:14:39 +08:00
三咲雅 · Misaki Masa
d2cc73c927
fix: ensure state synchronization even when the package update fails midway (#2613) 2025-04-13 14:46:16 +08:00
Nicholas42
af92b92da8
feat: allow custom exit code with quit --code (#2609)
Co-authored-by: Nicholas Schwab <git@nicholas-schwab.de>
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-04-12 17:59:23 +08:00
ze0987
bef481057a
fix: respect the user's max_width setting for the built-in video previewer (#2560)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-04-11 13:23:01 +08:00
ze0987
ca4fe2ced7
feat: limit memory usage for previewing large images (#2602)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-04-11 13:03:45 +08:00
三咲雅 · Misaki Masa
7cc250180f
fix: reverse the mixing order of theme and flavor configuration (#2594) 2025-04-10 00:25:54 +08:00
ze0987
99ea3b74c4
fix: don't fail on videos with embedded images (#2590) 2025-04-08 19:47:09 +08:00
sxyazi
2e5f5ae5a6
chore: bump version to 25.4.8 2025-04-08 18:23:00 +08:00
三咲雅 · Misaki Masa
86f465902e
feat: new ui.Text:scroll() API for setting text to scroll horizontally or vertically (#2589) 2025-04-08 17:06:38 +08:00
三咲雅 · Misaki Masa
2e1156f267
fix: ignore XQuartz $DISPLAY variable (#2586) 2025-04-08 13:29:46 +08:00
三咲雅 · Misaki Masa
0082d1181a
feat!: switch to resvg as the SVG renderer (#2581) 2025-04-07 23:50:55 +08:00
三咲雅 · Misaki Masa
be00881403
feat: allow initializing input when opening it with commands like rename, create, find, filter, etc. (#2578) 2025-04-06 16:59:48 +08:00
三咲雅 · Misaki Masa
fd007ab023
refactor: deprecate ui.Padding and ui.Rect:padding() (#2574) 2025-04-05 21:52:48 +08:00
三咲雅 · Misaki Masa
9565c1b6fd
perf!: cache UserData fields (#2572) 2025-04-05 07:42:27 +08:00
三咲雅 · Misaki Masa
3c9f619b84
feat: support Warp terminal image preview (#2571) 2025-04-04 08:02:51 +08:00
三咲雅 · Misaki Masa
b725b86be1
fix: remove -density option from magick command in SVG previewer (#2564) 2025-04-03 16:39:45 +08:00
三咲雅 · Misaki Masa
1765aba684
feat!: enhance fzf integration (#2553) 2025-03-30 22:17:07 +08:00
三咲雅 · Misaki Masa
8488ae8394
fix: always check whether the cursor exceeds the upper bound to guard against unexpected values (#2551) 2025-03-30 03:33:09 +08:00
三咲雅 · Misaki Masa
0ada74efbe
feat: new follow command to follow files pointed to by symlinks (#2543) 2025-03-28 20:14:53 +08:00
Integral
a25bbe2e9d
feat: clear terminal before displaying EXIF data (#2541) 2025-03-28 00:02:09 +08:00
XOR-op
0d9e3dc17e
feat!: support arrow prev and arrow next for more components (#2540)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-03-27 23:59:59 +08:00
ze0987
ad09fb89d9
perf!: faster image preview with optimized magick arguments (#2533)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-03-26 21:10:14 +08:00
三咲雅 · Misaki Masa
aedfe766c5
refactor!: remove unnecessary tasks_show and close_input commands (#2530) 2025-03-25 17:37:16 +08:00
MikuGeek
31fccd4052
feat: allow bulk renaming to include trailing content in addition to the required new names (#2494)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-03-24 23:52:26 +08:00
三咲雅 · Misaki Masa
4bef557b7f
feat: show error message when directory fails to load (#2527) 2025-03-24 23:05:42 +08:00
三咲雅 · Misaki Masa
e138364102
feat: platform-specific key binding (#2526) 2025-03-24 19:09:37 +08:00
三咲雅 · Misaki Masa
83f4deecfe
feat: new symlink_target to style the target of symbolic links (#2522) 2025-03-24 16:39:20 +08:00
三咲雅 · Misaki Masa
913a92d610
feat: allow repositioning the cursor in the rename DDS event (#2521) 2025-03-24 16:06:35 +08:00
三咲雅 · Misaki Masa
1a2a18e333
perf: rewrite config parser to double the startup speed (#2508) 2025-03-22 01:57:36 +08:00
三咲雅 · Misaki Masa
db0300c902
feat: new ya.id("app") to get YAZI_ID in plugins (#2503) 2025-03-20 20:26:45 +08:00
三咲雅 · Misaki Masa
570c6d308b
refactor: new yazi-widgets crate (#2498) 2025-03-20 02:21:53 +08:00
三咲雅 · Misaki Masa
7632163678
feat: new base field for the Url userdata (#2492) 2025-03-18 17:06:20 +08:00
三咲雅 · Misaki Masa
c5808a0db4
perf: lazy compile and cache lua plugins as binary bytecode (#2490) 2025-03-17 16:12:43 +08:00
三咲雅 · Misaki Masa
8b3ce1838a
feat!: new @sync peek annotation for sync previewers (#2487) 2025-03-16 17:41:27 +08:00
三咲雅 · Misaki Masa
324a439c73
feat: file navigation wraparound with new arrow prev and arrow next commands (#2485) 2025-03-15 17:44:42 +08:00
三咲雅 · Misaki Masa
abfbd1cd9f
feat: new fs.expand_url API (#2476) 2025-03-12 14:17:07 +08:00
三咲雅 · Misaki Masa
faee35fc44
fix: force ANSI for keyboard progressive enhancement on Windows (#2474) 2025-03-11 15:19:30 +08:00
三咲雅 · Misaki Masa
a0c6842626
fix: respect hidden status of directory junctions and symlinks themselves on Windows (#2471) 2025-03-11 13:02:58 +08:00
三咲雅 · Misaki Masa
76adb97e22
ci: add label only if not removed manually (#2470) 2025-03-11 12:37:31 +08:00
三咲雅 · Misaki Masa
c8bf2c507a
refactor: prefer WriteConsoleW for Windows console output (#2464) 2025-03-10 14:41:02 +08:00
sxyazi
22980cf000
fix: set terminal code page to UTF-8 on Windows 2025-03-09 19:08:01 +08:00
三咲雅 · Misaki Masa
119cc9c2a1
feat: support using Yazi in Helix directly without Zellij or tmux (#2461) 2025-03-09 14:53:55 +08:00
三咲雅 · Misaki Masa
31177fd1fd
fix: remove the temporary extraction directory forcefully (#2458) 2025-03-08 15:16:06 +08:00
三咲雅 · Misaki Masa
ece635d6b8
feat: allow tab_swap to cycle tabs (#2456) 2025-03-08 09:50:38 +08:00
三咲雅 · Misaki Masa
a2bbd29289
feat: custom search engine Lua API (#2452) 2025-03-07 17:48:44 +08:00
三咲雅 · Misaki Masa
dc46e90b0a
fix: always show the size in the status bar even in empty directories (#2449) 2025-03-06 18:54:13 +08:00
三咲雅 · Misaki Masa
3dc6d82b98
feat: log tmux call execution time to logs (#2444) 2025-03-06 07:24:41 +08:00
三咲雅 · Misaki Masa
68cd02816d
feat: new rt.term exports terminal emulator information (#2442) 2025-03-05 11:50:47 +08:00
三咲雅 · Misaki Masa
3606bc7a1f
fix: reserve a hack for Zellij to force an image adapter (#2441) 2025-03-04 23:57:11 +08:00
三咲雅 · Misaki Masa
51de941f79
feat: new <C-A> and <C-E> keybindings to select entire line for the input component (#2439) 2025-03-04 22:21:04 +08:00
Jon Seager
2d210ae557
ci: add snap publishing workflow (#2435)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-03-04 21:29:22 +08:00
三咲雅 · Misaki Masa
3082cad16c
fix: windows-sys features for Win32_Security and Win32_System_IO (#2434) 2025-03-03 22:20:07 +08:00
三咲雅 · Misaki Masa
38d5b2fc87
fix: align the behavior of the end-of-options marker (--) with that of the shell (#2431) 2025-03-03 10:56:38 +08:00
三咲雅 · Misaki Masa
46125eda6e
chore: bump version to 25.3.2 (#2428) 2025-03-02 21:33:13 +08:00
hankertrix
4e32cd91ca
feat: expose almost the entirety of the user's configuration in Lua (#2413)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2025-03-02 20:44:36 +08:00
三咲雅 · Misaki Masa
94ff413e23
fix: STDIN_FILENO poll always returns 0 under SSH (#2427) 2025-03-02 11:02:26 +08:00
三咲雅 · Misaki Masa
541d849157
fix: ignore stdin redirection to ensure always accessing the real tty (#2425) 2025-03-02 06:09:28 +08:00
sxyazi
66f015de95
ci: support 8-character short hash in validate-form workflow 2025-03-02 03:14:48 +08:00
hankertrix
57ef8f9ebd
fix: incorrect deprecation warning when the plugin doesn't exist (#2418)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-03-01 23:11:38 +08:00
三咲雅 · Misaki Masa
84d71bfa39
fix: windows-sys features for Win32_Storage_FileSystem and Win32_System_Threading (#2417) 2025-02-28 19:03:40 +08:00
三咲雅 · Misaki Masa
2a6cad455f
refactor: use MaybeUninit in RoCell (#2412) 2025-02-28 08:49:36 +08:00
hankertrix
20c99c6a06
feat: expose all theme fields in Lua (#2405) 2025-02-27 02:28:15 +08:00
三咲雅 · Misaki Masa
6b0a5306c2
chore: bump version to 25.2.26 (#2404) 2025-02-26 22:21:27 +08:00
三咲雅 · Misaki Masa
950750f66e
fix: respect the user's image_alloc setting for the built-in ImageMagick previewer (#2403) 2025-02-26 21:00:05 +08:00
三咲雅 · Misaki Masa
953d567c63
feat: allow to specify layer for keymap commands (#2399) 2025-02-26 03:01:17 +08:00
三咲雅 · Misaki Masa
235f6888d4
refactor: rename rt.manager to rt.mgr, and th.manager to th.mgr (#2397) 2025-02-25 23:12:54 +08:00
三咲雅 · Misaki Masa
68e892694d
feat: expose mode field in Cha (#2394) 2025-02-24 21:51:46 +08:00
三咲雅 · Misaki Masa
133c6ebc9d
refactor: rename cf to rt (#2393) 2025-02-24 21:26:19 +08:00
三咲雅 · Misaki Masa
f11f77d7b9
feat: new cf.args to access startup arguments (#2392) 2025-02-24 00:39:15 +08:00
paperbenni
6ca27597f9
feat: add ripgrep-all support for search (#2383)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2025-02-23 23:59:43 +08:00
三咲雅 · Misaki Masa
36ed32d2c3
feat: new tbl_col and tbl_cell in theme system for spotter table styling (#2391) 2025-02-23 23:37:35 +08:00
三咲雅 · Misaki Masa
7b4c4eae40
feat: new cf and th allow to access user configuration and theme scheme in sync/async plugins consistently (#2389) 2025-02-23 20:37:35 +08:00
三咲雅 · Misaki Masa
2410bb9671
feat: bump trash and libc versions to support NetBSD (#2388) 2025-02-23 18:36:17 +08:00
三咲雅 · Misaki Masa
52a5ab59e9
feat: make incompatible version message more clear (#2377) 2025-02-21 23:08:42 +08:00
sxyazi
7f17ecd547
ci: validate form 2025-02-21 20:07:34 +08:00
三咲雅 · Misaki Masa
f75194b7cf
fix: didn't reset previous Cha when loading directories in chunks (#2366) 2025-02-20 01:17:14 +08:00
三咲雅 · Misaki Masa
4465101089
feat: add a link to the debugging instructions in yazi --debug (#2365) 2025-02-19 18:21:21 +08:00
三咲雅 · Misaki Masa
1ddbbfea71
fix: add maximum preview limit under /proc virtual file system (#2355) 2025-02-17 15:20:50 +08:00
hankertrix
3ec832b9d8
fix: incorrect kebab-case for the notify level enum (#2349)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-02-17 14:34:50 +08:00
三咲雅 · Misaki Masa
f25ef0f07b
feat: terminal response detection under async stdin (#2347) 2025-02-16 23:05:39 +08:00
三咲雅 · Misaki Masa
22c8f370dc
feat: new external and removable fields in the fs.partitions() API (#2343) 2025-02-15 23:15:31 +08:00
三咲雅 · Misaki Masa
38e45c647b
refactor: consistent naming for enum variants (#2339) 2025-02-14 23:17:06 +08:00
boydaihungst
b9416d8a04
feat: respect the user's wrap setting for the built-in JSON previewer (#2337) 2025-02-14 23:08:40 +08:00
三咲雅 · Misaki Masa
077faacc9a
feat: respect the user's max_width setting for the built-in PDF preloader (#2331) 2025-02-13 19:02:17 +08:00
三咲雅 · Misaki Masa
f506849fb5
feat: CSI-based Vim and Neovim built-in terminal detection for better accuracy (#2327) 2025-02-12 20:13:27 +08:00
三咲雅 · Misaki Masa
e2c841cca4
fix: load mount points with the best effort even if the /dev/disk/by-label directory does not exist (#2326) 2025-02-12 17:10:07 +08:00
PFiS
a4dde6a848
feat!: allow different separators to be applied individually to the left and right sides of the status bar (#2313) 2025-02-11 20:05:18 +08:00
三咲雅 · Misaki Masa
ce9092e73e
chore: bump version to 25.2.11 (#2323) 2025-02-11 19:07:47 +08:00
三咲雅 · Misaki Masa
89d4ceb5bb
feat: new overall option under [status] to allow specifying the overall style of the status bar (#2321) 2025-02-11 16:56:46 +08:00
三咲雅 · Misaki Masa
498623191a
fix: unable to delete sealed files on Windows due to platform differences (#2319) 2025-02-11 01:50:32 +08:00
三咲雅 · Misaki Masa
d75a5d6628
feat: reduce terminal response wait timeout (#2314) 2025-02-10 18:46:38 +08:00
三咲雅 · Misaki Masa
793c90f021
fix: reverse the order of CSI-based and environment-based terminal detection (#2310) 2025-02-09 14:50:19 +08:00
三咲雅 · Misaki Masa
17ff1e8812
chore: bump version to 25.2.7 (#2301) 2025-02-07 16:42:49 +08:00
三咲雅 · Misaki Masa
a8477059fd
feat: use positional argument instead of --args for the plugin command (#2299) 2025-02-07 02:51:13 +08:00
三咲雅 · Misaki Masa
633e68e73e
feat: support end of options (--) marker for all commands (#2298) 2025-02-07 02:01:23 +08:00
Ryan
b1d2be067f
docs: update Windows Terminal image preview support to Stable (#2296) 2025-02-06 14:54:53 +08:00
三咲雅 · Misaki Masa
e9fcab3b37
feat: new arrow top and arrow bot commands to jump to the top and bottom (#2294) 2025-02-05 21:35:15 +08:00
三咲雅 · Misaki Masa
0c100ae5a6
feat: switch to Calendar Versioning (#2291) 2025-02-05 17:00:33 +08:00
三咲雅 · Misaki Masa
b236f34d31
feat: new @since plugin annotation to specify the minimum supported Yazi version (#2290) 2025-02-05 15:55:56 +08:00
三咲雅 · Misaki Masa
4e96341f51
fix: enable unwinding on Windows release builds (#2286) 2025-02-04 16:28:51 +08:00
Eric Chen
7f1e9b83fd
docs: Warp sponsorship (#2282)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2025-02-04 11:12:05 +08:00
三咲雅 · Misaki Masa
1cc9b2475c
fix: correct shell quotes for Unicode on Windows (#2285) 2025-02-04 10:02:51 +08:00
三咲雅 · Misaki Masa
c41f2e21e0
fix: squeeze the parent directory offset after terminal size change (#2275) 2025-01-31 17:02:02 +08:00
sxyazi
74ce17ebbe
docs: add Bobcat to the list of VTEs with images preview support (#2269)
Co-authored-by: ismail-yilmaz <ismail-yilmaz@users.noreply.github.com>
2025-01-31 16:28:17 +08:00
evpeople
77624ba6dc
feat: ya pack supports adding and deleting multiple packages at the same time (#2257) 2025-01-31 16:16:49 +08:00
三咲雅 · Misaki Masa
c061397a09
feat: allow preloaders to return an optional Error to describe the failure (#2253) 2025-01-28 04:35:51 +08:00
三咲雅 · Misaki Masa
da36cd6ab8
feat: new cx.layer API to determine the current UI layer (#2247) 2025-01-26 01:54:18 +08:00
三咲雅 · Misaki Masa
af9a875512
feat: support package.toml as a symlink (#2245) 2025-01-25 21:10:05 +08:00
三咲雅 · Misaki Masa
29284613a0
fix: ensure the selected file list is always ordered (#2244) 2025-01-25 20:39:24 +08:00
Viktor
a4f8e86471
feat: wrap long task descriptions (#2243) 2025-01-25 00:24:39 +08:00
三咲雅 · Misaki Masa
cc568ee1fe
fix: JSON value null should be deserialized as Lua nil, not lightweight userdata null (#2242) 2025-01-24 23:19:29 +08:00
三咲雅 · Misaki Masa
abb43251fa
feat: apply natural sort to partitions on both Linux and macOS (#2235) 2025-01-22 22:51:17 +08:00
Filipe Paniguel
456935658a
fix: use u32 for parsing Linux partition blocks (#2234) 2025-01-22 20:37:18 +08:00
三咲雅 · Misaki Masa
1f4d0eafb5
fix: unmangle the hexadecimal space strings ("\x20") in Linux partition labels (#2233) 2025-01-22 20:34:14 +08:00
三咲雅 · Misaki Masa
245fb030df
feat: support local tmux image preview over SSH (#2229) 2025-01-20 18:59:00 +08:00
Eduardo Roberto
b4ca02f703
fix: ignore completions artifacts (#2226) 2025-01-20 15:42:06 +08:00
三咲雅 · Misaki Masa
5058cf2294
fix: sync block execution failed due to Runtime mutably borrowed more than once (#2225) 2025-01-19 22:54:34 +08:00
三咲雅 · Misaki Masa
ed3c9c4f3c
perf: detach the watch registration from the main thread (#2224) 2025-01-19 19:48:34 +08:00
Jon Seager
7bd79521da
ci(snap): correct arm64 runner OS (#2217) 2025-01-19 19:07:03 +08:00
三咲雅 · Misaki Masa
cd338d0d1b
feat: more complete hovered file cursor tracking (#2218) 2025-01-19 16:09:24 +08:00
Fedi Jamoussi
e37d8d6bc1
fix(nix): rust overlay infinite recursion (#2216) 2025-01-18 18:10:51 +08:00
Jon Seager
ebaf2c29c1
ci: use GitHub Linux arm64 runners for the snap build (#2214) 2025-01-18 16:44:45 +08:00
三咲雅 · Misaki Masa
3e1c8950f2
feat: mount manager (#2199) 2025-01-17 21:32:55 +08:00
三咲雅 · Misaki Masa
6c94227d40
feat: channel and multi-concurrent task join support for the plugin system (#2210) 2025-01-17 01:17:22 +08:00
三咲雅 · Misaki Masa
63eb82aa72
feat: custom modal component API (#2205) 2025-01-15 21:46:39 +08:00
Jon Seager
6a5fa714ae
feat: arm64 Snap package (#2188) 2025-01-15 13:34:59 +08:00
marcoleder
098f7396d8
fix: wrong description of the swipe command (#2197) 2025-01-14 13:47:21 +08:00
Valter Santos
5c88f26896
feat: new ya pack -d subcommand to delete packages (#2181)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-01-11 12:08:13 +08:00
gx
856f37b5b3
feat: new --no-cwd-file option for the close command (#2185)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-01-11 09:59:53 +08:00
Filipe Paniguel
b495f78dfe
fix: incorrect monorepo sub-plugin path resolution (#2186)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-01-10 16:25:13 +08:00
三咲雅 · Misaki Masa
1e0c5ff61c
feat: allow YAZI_LOG to control the log level of Überzug++ (#2183) 2025-01-09 15:58:38 +08:00
Valter Santos
6bc4a0295d
docs: correct the cargo test command in the contribution guide (#2182)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2025-01-09 15:52:13 +08:00
darcy
ba62b407bd
feat: replace mode and Vim motions (W, E, B, ^, _) for inputs (#2143)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2025-01-08 18:38:21 +08:00
三咲雅 · Misaki Masa
2eed881f12
feat: more decent package locking mechanism (#2168) 2025-01-08 16:03:40 +08:00
三咲雅 · Misaki Masa
7dd4454bf1
feat: support application/mbox mimetype (#2173) 2025-01-08 14:58:46 +08:00
三咲雅 · Misaki Masa
21f6a92ea3
feat: sort search results by full URN (#2164) 2025-01-06 13:52:58 +08:00
hankertrix
05ecbca994
fix: typo in the argument documentation for the CLI (#2158) 2025-01-05 22:30:18 +08:00
三咲雅 · Misaki Masa
7d993c1517
feat: support and hide Windows system files by default (#2149) 2025-01-03 08:18:34 +08:00
qumn
40fea8521e
fix: correct Vec capacity allocation caused by variable name shadowing (#2139) 2025-01-01 22:45:32 +08:00
三咲雅 · Misaki Masa
ef599a160a
fix: before_ext should exclude directories since only files have extensions (#2132) 2025-01-01 00:11:17 +08:00
Wenxuan
00e8adc3de
fix: handle broken pipe errors gracefully (#2110)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-12-30 23:52:52 +08:00
hankertrix
fd21452aa4
feat: prompt users without fzf for the zoxide plugin (#2122)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-12-30 22:33:13 +08:00
三咲雅 · Misaki Masa
2770e0259c
fix: don't check if has a hovered file in advance, only do so when --hovered is explicitly specified (#2105) 2024-12-28 00:58:54 +08:00
Anirudh Gupta
94128b45fc
docs: update the links in the README (#2103)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2024-12-27 23:19:57 +08:00
三咲雅 · Misaki Masa
9117fe262f
fix: add Alacritty to the database as a terminal that doesn't support any image protocol (#2107) 2024-12-27 23:09:45 +08:00
sxyazi
d754ac5dac
fix: reversed style shouldn't be applied to the entire text block 2024-12-25 23:48:22 +08:00
Integral
2a4a398342
ci: add new linux targets (#2099) 2024-12-25 18:33:32 +08:00
三咲雅 · Misaki Masa
7d3e58951c
feat: new ya.confirm() API (#2095) 2024-12-25 00:35:46 +08:00
三咲雅 · Misaki Masa
50a81bea31
fix: element style of ui.Text was not applied to the entire area (#2093) 2024-12-24 16:43:19 +08:00
AminurAlam
d746ae8338
feat: add cbr and cbz as valid archive extensions (#2077)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-12-23 15:04:46 +08:00
greg
5bd71bf225
feat: theme support for the spotter border and title (#2002) 2024-12-21 00:17:28 +08:00
sxyazi
783e95b1f2
chore: bump version to 0.4.3 2024-12-20 22:46:24 +08:00
三咲雅 · Misaki Masa
5cfcab305e
fix: missing a hover after reordering from an external plugin (#2072) 2024-12-20 19:49:42 +08:00
hankertrix
f0176992f5
feat: new fs.create() Lua API (#2068) 2024-12-20 19:07:05 +08:00
Integral
87bfd8e2aa
feat: add more supported archive formats to the preset config (#1926) 2024-12-20 17:55:33 +08:00
三咲雅 · Misaki Masa
9e6a801073
fix: missing a render after resuming from an external blocking process (#2071) 2024-12-20 16:57:24 +08:00
Integral
8800bae0aa
ci: add riscv64gc-unknown-linux-gnu target (#2067) 2024-12-19 16:54:38 +08:00
三咲雅 · Misaki Masa
635bb4be55
feat: allow noop for single-key chords by removing the mixing length limit (#2064) 2024-12-18 10:51:36 +08:00
三咲雅 · Misaki Masa
54918b506f
feat: new --cwd parameter for the shell command and fs.cwd() API (#2060) 2024-12-17 18:31:17 +08:00
三咲雅 · Misaki Masa
63ad28930f
fix: use a less intrusive DSR instead of DA1 workaround to forward terminal responses twice in tmux (#2058) 2024-12-16 21:59:28 +08:00
三咲雅 · Misaki Masa
c96b1d3aa1
fix: pass through show_hidden when building default Files (#2057) 2024-12-16 20:57:20 +08:00
三咲雅 · Misaki Masa
f4eef99f7e
fix: allow-passthrough must be set to on to prevent tmux from forwarding the real terminal's response to the inactive pane (#2052) 2024-12-16 09:07:56 +08:00
三咲雅 · Misaki Masa
6e1948e7e1
fix: set the current working directory in a thread-safe way (#2043) 2024-12-14 13:26:37 +08:00
三咲雅 · Misaki Masa
c1048debc5
feat: support for Android platform in the for qualifier of opener (#2041) 2024-12-14 08:50:36 +08:00
三咲雅 · Misaki Masa
196a46cc5e
fix: choose a more conservative macro_workers value to ensure concurrency safety with certain USB flash drives (#2040) 2024-12-14 08:02:24 +08:00
三咲雅 · Misaki Masa
c78f39b50f
chore: bump version to 0.4.2 (#2031) 2024-12-11 21:54:32 +08:00
三咲雅 · Misaki Masa
a64e8a8b59
fix: offset cursor shift when deleting multiple files in bulk (#2030) 2024-12-11 21:21:41 +08:00
三咲雅 · Misaki Masa
ccf466d881
feat: new option to suppress 0.4 deprecation warnings (#2027) 2024-12-11 17:38:43 +08:00
三咲雅 · Misaki Masa
61cab0f30a
fix: interactive cd autocomplete doesn't follow the latest CWD changes (#2025) 2024-12-11 14:25:29 +08:00
三咲雅 · Misaki Masa
22757199f9
chore: bump version to 0.4.1 (#2022) 2024-12-10 20:19:15 +08:00
三咲雅 · Misaki Masa
0b340b67d5
fix: failed to parse certain image dimensions for Überzug++ backend (#2020) 2024-12-10 07:45:18 +08:00
三咲雅 · Misaki Masa
7498b97251
fix: correctly handle CRLF on Windows in preset archive and json plugins (#2017) 2024-12-10 01:03:01 +08:00
Integral
a743488476
refactor: replace format! with concat! for string literals (#2012)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-12-09 21:19:02 +08:00
三咲雅 · Misaki Masa
62ac224cff
fix: disable passthrough when the user launches Yazi in Neovim inside tmux (#2014) 2024-12-09 10:27:58 +08:00
三咲雅 · Misaki Masa
b8b3ab9be3
chore: bump version to 0.4.0 (#2011) 2024-12-08 21:00:32 +08:00
gaesa
de93e6208d
fix: avoid upscaling for the video previewer (#2007)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-12-08 00:25:06 +08:00
三咲雅 · Misaki Masa
6308873f0b
fix: backspace --under didn't map UTF-8 character code points to byte indices (#2010) 2024-12-07 22:53:22 +08:00
三咲雅 · Misaki Masa
8ec944dbd3
fix: introduce own CWD instead of chdir to avoid potential race conditions (#2008) 2024-12-07 22:07:18 +08:00
gaesa
adb1426539
fix: respect PREVIEW.image_quality for the default PDF previewer (#2006)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-12-07 20:08:16 +08:00
三咲雅 · Misaki Masa
3bd625a8af
docs: add README for default configuration files (#2005) 2024-12-07 02:24:47 +08:00
三咲雅 · Misaki Masa
9d3c0c72fe
feat: fallback to CSI 16 t for certain terminals that do not support TIOCGWINSZ (#2004) 2024-12-07 00:46:10 +08:00
三咲雅 · Misaki Masa
11cf555b47
fix: revise revision if the new file list is empty but the previous one was not (#2003) 2024-12-06 22:11:45 +08:00
三咲雅 · Misaki Masa
fbf9b3d1ed
fix!: remove the vnd. prefix from mimetype to solve differences introduced in the newest version of file(1) 5.46 (#1995) 2024-12-05 22:37:05 +08:00
三咲雅 · Misaki Masa
c7d9265d25
fix: missing a repeek on unyanking files in the hovered folder (#1988) 2024-12-05 08:45:18 +08:00
三咲雅 · Misaki Masa
2771aef677
fix: propagate and update the directory node till its first parent when the files of a directory change (#1987) 2024-12-04 22:44:35 +08:00
三咲雅 · Misaki Masa
b4d1174f46
feat: move notification from top-right to bottom-right corner to avoid covering content as much as possible (#1984) 2024-12-03 23:59:18 +08:00
三咲雅 · Misaki Masa
d3f572a8c7
feat!: remove the meaningless --confirm option to simplify the shell command (#1982) 2024-12-03 22:15:43 +08:00
三咲雅 · Misaki Masa
4bd8b0b446
feat: new load DDS event (#1980) 2024-12-03 09:13:23 +08:00
三咲雅 · Misaki Masa
20dc0550bc
feat: new ya emit and ya emit-to subcommands to emit commands to a specified instance for execution (#1979) 2024-12-01 23:12:49 +08:00
zooeywm
91665b7713
feat: support assets installation for the ya pack subcommand (#1973)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-12-01 18:49:07 +08:00
三咲雅 · Misaki Masa
4194befb88
feat: true custom mime fetcher support - using user rules even during open or in watcher (#1976) 2024-12-01 00:15:43 +08:00
三咲雅 · Misaki Masa
d72f90356b
feat!: support passing arguments to previewer/preloader/spotter/fetcher (#1966) 2024-11-30 21:25:57 +08:00
三咲雅 · Misaki Masa
37292adfde
perf: introduce copy-on-write for event system to eliminate all memory reallocations (#1962) 2024-11-28 01:56:53 +08:00
三咲雅 · Misaki Masa
5e48df5126
feat!: extend the available styles for mode by separating mode from the separator styles (#1953) 2024-11-26 17:11:36 +08:00
sxyazi
ab04ce5d77
fix: make cd expand variables regardless 2024-11-25 23:29:31 +08:00
三咲雅 · Misaki Masa
4026cebd88
feat!: auto switch between dark and light icons/flavors based on terminal backgrounds (#1946) 2024-11-25 16:43:07 +08:00
三咲雅 · Misaki Masa
1277b01758
feat: new log system (#1945) 2024-11-24 17:47:32 +08:00
三咲雅 · Misaki Masa
805597268a
feat!: use an Error userdata instead of a plain error code for I/O errors (#1939) 2024-11-23 18:30:17 +08:00
三咲雅 · Misaki Masa
99d6c81fbb
refactor: remove unnecessary UI element construction (#1938) 2024-11-23 14:42:26 +08:00
sxyazi
870b0504e9
fix: ignore cancellation in C functions 2024-11-23 13:16:11 +08:00
Integral
87f7fb6b3b
refactor: make error messages more user-friendly (#1935)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-11-23 13:09:56 +08:00
三咲雅 · Misaki Masa
0f9a3195b7
feat!: video spotter & using ffmpeg instead of ffmpegthumbnailer as previewer backend (#1928) 2024-11-22 18:21:29 +08:00
三咲雅 · Misaki Masa
22e7d579d2
fix!: eliminate the x- prefix in mime-types (#1927) 2024-11-21 15:06:07 +08:00
Integral
202751b46a
fix: show "0/0" instead of "1/0" in empty directories (#1925) 2024-11-21 13:37:49 +08:00
boydaihungst
e965b865b9
feat: noop for spotters (#1924) 2024-11-20 23:45:40 +08:00
三咲雅 · Misaki Masa
1f32601dc4
feat: spotter (#1802) 2024-11-20 16:43:38 +08:00
Perfectio07
af565fbc40
chore: add CODE_OF_CONDUCT.md (#1911) 2024-11-16 09:25:23 +08:00
sxyazi
c65bdb3b09
fix: implement FromLua for Cha instead of AnyUserData 2024-11-14 13:08:11 +08:00
三咲雅 · Misaki Masa
00486521b8
perf: lazy load ui, ya, fs, and ps (#1903) 2024-11-13 11:38:11 +08:00
sxyazi
4ff4038b41
fix: register and ignore the SIGINT signal explicitly 2024-11-12 08:24:28 +08:00
Ion
fd8871d878
feat: add additional environment and dependency info in yazi --debug (#1896)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-11-10 22:58:47 +08:00
三咲雅 · Misaki Masa
a9a8a190a4
refactor: upgrade to mlua v0.10.0 (#1842) 2024-11-08 22:37:32 +08:00
三咲雅 · Misaki Masa
baf062f3b1
feat!: deprecate --sync option for the plugin command (#1891) 2024-11-07 23:08:39 +08:00
Integral
6001f3c619
feat: support searching with the alias fdfind if fd cannot be found (#1889)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-11-06 20:28:12 +08:00
sxyazi
81ce040443
feat: disable the rayon feature for image since Yazi already uses multithreading 2024-11-05 23:38:18 +08:00
三咲雅 · Misaki Masa
362fbebcc5
feat: add a new tab parameter for all tab-specific commands to specify which one (#1885) 2024-11-03 23:58:14 +08:00
yama
6086134d41
feat: include package revision hash in ya pack --list (#1884)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-11-03 20:56:06 +08:00
Li-Lun Lin
565f9cc898
feat: new copy --separator option to allow specifying the path separator (#1877)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-11-03 17:40:29 +08:00
三咲雅 · Misaki Masa
5531874a9a
feat: allow disabling certain preset keybinds with the new noop virtual command (#1882) 2024-11-03 16:48:17 +08:00
Integral
441ebcb764
refactor: destructure tuples to enhance readability (#1874) 2024-11-03 15:47:24 +08:00
三咲雅 · Misaki Masa
0baccdc9aa
fix: use complete rendering instead of partial rendering for no task progress report (#1876) 2024-11-01 19:52:19 +08:00
Integral
a510673123
refactor: use for loop to generate completions file (#1869) 2024-10-31 22:15:28 +08:00
aidancz
e3c91115a2
fix: wrong file list offset squeeze when scrolloff = 0 (#1866) 2024-10-31 14:15:20 +08:00
三咲雅 · Misaki Masa
c6687237e1
perf: introduce reflow for the rendering engine (#1863) 2024-10-30 19:06:06 +08:00
yw1ee
81b8c89ec1
feat: prioritize paths that need to be processed first during bulk renaming (#1801)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-10-30 13:28:19 +08:00
三咲雅 · Misaki Masa
5eabd7d897
fix: copy the CWD path regardless even if the directory is empty (#1849) 2024-10-28 21:28:33 +08:00
三咲雅 · Misaki Masa
e3507205fb
feat: suggest keywords in the header if a finder is active (#1847) 2024-10-28 17:14:41 +08:00
三咲雅 · Misaki Masa
4dd24f779c
perf: eliminate all memory reallocations during sorting (#1846) 2024-10-28 15:36:27 +08:00
三咲雅 · Misaki Masa
ef1a31a274
perf: using usize instead of *const OsStr reduces memory usage (#1839) 2024-10-26 17:09:27 +08:00
三咲雅 · Misaki Masa
96bcd820b8
refactor: add tests for Pattern::match_path (#1837) 2024-10-26 08:53:01 +08:00
三咲雅 · Misaki Masa
56f9a6a1eb
fix: reset image rendering and skip peeking if the TUI in the background (#1833) 2024-10-25 16:52:57 +08:00
三咲雅 · Misaki Masa
60cfa7dba9
feat: launch from preset settings if the user's config cannot be parsed (#1832) 2024-10-25 16:27:26 +08:00
sxyazi
81fd949016
chore: add discussion template 2024-10-25 08:48:52 +08:00
三咲雅 · Misaki Masa
e8c1d625ac
fix: use a unique Id for each tab (#1826) 2024-10-24 08:57:08 +08:00
三咲雅 · Misaki Masa
35d781e240
feat: allow customizing Zoxide's FZF options with YAZI_ZOXIDE_OPTS (#1822) 2024-10-23 10:45:41 +08:00
三咲雅 · Misaki Masa
0e118b5b3a
fix: use std copy function in a blocking thread (#1817) 2024-10-21 09:16:54 +08:00
三咲雅 · Misaki Masa
16881aab2f
feat: support reading non-UTF8 data with Child:read_line() API (#1816) 2024-10-21 02:59:38 +08:00
三咲雅 · Misaki Masa
24a77d8a5f
feat: add ICC profile to images for better color accuracy (#1808) 2024-10-19 21:07:41 +08:00
三咲雅 · Misaki Masa
11c5f3fed4
perf: apply rotate in place to images with orientation (#1807) 2024-10-19 10:29:36 +08:00
三咲雅 · Misaki Masa
df78827af5
fix: implement the file copy process for Linux and Android separately (#1805) 2024-10-19 08:58:06 +08:00
greg
53043313ba
feat: custom styles for the confirm component (#1789)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-10-17 18:39:51 +08:00
三咲雅 · Misaki Masa
a6c9c93d58
refactor: remove migration code as it's no longer needed and causes errors (#1795) 2024-10-16 20:26:39 +08:00
三咲雅 · Misaki Masa
e58cf555da
feat: add a compatibility layer for ui.Paragraph to help users transition more smoothly to the new ui.Text (#1794) 2024-10-16 20:17:56 +08:00
三咲雅 · Misaki Masa
0824e11cd2
fix: images were not cleared when closing a tab in front of the current tab (#1792) 2024-10-16 19:11:48 +08:00
Sarveshwaar SS
17a1169ea2
feat: append the suffix to the end when generating unique filenames for directories, i.e., after not before the extension (#1784)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-10-16 00:44:27 +08:00
三咲雅 · Misaki Masa
097e5abb82
refactor: replace Metadata with Cha in the file scheduler to improve interoperability with yazi-fs (#1785) 2024-10-15 20:38:34 +08:00
gaesa
3e8ac856cf
feat: prevent paths from being treated as options in file command (#1783) 2024-10-15 00:44:31 +08:00
三咲雅 · Misaki Masa
1acd7ca80f
feat!: decouple ui.List, ui.Bar, ui.Border, and ui.Gauge from coordinates (#1782) 2024-10-14 19:39:59 +08:00
三咲雅 · Misaki Masa
43b5ae0e6c
feat!: add ui.Text, ui.Table, remove ui.Paragraph and ui.ListItem (#1776) 2024-10-14 01:54:03 +08:00
三咲雅 · Misaki Masa
35c3c9e0f7
refactor!: rename the term select to toggle to reserve select for future use (#1773) 2024-10-13 18:47:12 +08:00
三咲雅 · Misaki Masa
13e307eab2
refactor: simplify module exports (#1770) 2024-10-12 21:05:12 +08:00
sxyazi
da1b2365b9
feat: add the plugin name to the deprecated API warning to make it more clear 2024-10-11 22:01:38 +08:00
三咲雅 · Misaki Masa
c84917c5e8
feat: yazi --debug supports detecting whether tmux is built with --enable-sixel (#1762) 2024-10-11 19:39:47 +08:00
三咲雅 · Misaki Masa
2014aee646
fix!: introduce a new btime term to align ctime with Unix (#1761) 2024-10-11 18:05:08 +08:00
三咲雅 · Misaki Masa
558d97d084
perf: merge multiple file operations into one to greatly speed up updates in large directories (#1745) 2024-10-08 19:33:38 +08:00
三咲雅 · Misaki Masa
064517665d
refactor: derive the Into<Opt> trait with procedural macros to avoid bloat (#1742) 2024-10-07 22:04:38 +08:00
三咲雅 · Misaki Masa
dcbe7873cd
fix: upserting operation should handle deleting in edge cases where the source and target URNs are different (#1737) 2024-10-06 13:04:52 +08:00
三咲雅 · Misaki Masa
87b159fb9d
fix: clamp when seeking a non-zero unit between -1 and 1 (#1736) 2024-10-05 22:32:18 +08:00
三咲雅 · Misaki Masa
491f8b8fb1
fix: compositors not supported by Überzug Wayland layer, or WSL not with WezTerm should fallback to Chafa (#1735) 2024-10-05 22:16:20 +08:00
三咲雅 · Misaki Masa
3321f47d46
refactor: use Kgp instead of Kitty since "Kitty" is a terminal emulator not a protocol name (#1732) 2024-10-04 23:43:36 +08:00
三咲雅 · Misaki Masa
3150fb10f7
refactor: turn RectRef, PaddingRef, PositionRef into Rect, Padding, Position (#1730) 2024-10-04 20:23:36 +08:00
三咲雅 · Misaki Masa
8c5d8aa589
fix: temporarily disable TIFF decoding (#1723) 2024-10-03 16:03:17 +08:00
三咲雅 · Misaki Masa
034c28bacb
feat: reuse the code previewer seeking behavior for json, archive, and empty (#1721) 2024-10-03 08:21:17 +08:00
XYenon
a96c60ce6a
feat!: make backspace command not close the input even when value is empty (#1680) 2024-10-03 07:41:28 +08:00
三咲雅 · Misaki Masa
e1773b11f1
feat: async micro task initialization error handling (#1710) 2024-10-01 18:38:37 +08:00
三咲雅 · Misaki Masa
40211df219
fix: replace control characters to printable characters in plain text preview (#1704) 2024-09-30 00:37:33 +08:00
sxyazi
a7b9275c06
feat: switch snap confinement to strict 2024-09-29 19:32:13 +08:00
三咲雅 · Misaki Masa
e6912da7d1
feat: add more context to error messages (#1701) 2024-09-29 15:56:28 +08:00
三咲雅 · Misaki Masa
3e4973dbbf
feat: allow overriding and rewriting the sync methods of builtin plugins (#1695) 2024-09-28 00:41:34 +08:00
三咲雅 · Misaki Masa
70fbe41cc2
fix: increase the revision when there is a change in Urn on updating (#1691) 2024-09-27 09:32:53 +08:00
Raphael Amorim
9f8109e02e
feat: adapt for image preview in the Rio terminal (#1690)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-09-27 00:35:01 +08:00
dm9pZCAq
e2816716a0
feat: improve jemalloc memory efficiency (#1689) 2024-09-26 20:31:28 +08:00
venatio
ae53ef4443
fix: magick previewer for multi-layered image files with -flatten argument (#1684) 2024-09-26 09:14:13 +08:00
三咲雅 · Misaki Masa
c4ffdc08bb
fix: enter and leave commands should treat the search results as regular entities (#1687) 2024-09-26 08:50:07 +08:00
三咲雅 · Misaki Masa
5b66192332
fix: one file's mime-type changed multiple times without triggering a preview again (#1682) 2024-09-26 00:22:55 +08:00
三咲雅 · Misaki Masa
631afd09ee
fix: warnings should be output to stderr instead of stdout (#1669) 2024-09-21 20:12:35 +08:00
三咲雅 · Misaki Masa
1a1820cf77
feat: add the area() API for renderable elements (#1667) 2024-09-21 01:47:34 +08:00
三咲雅 · Misaki Masa
ac196f211e
feat: support calling methods in builtin plugins with arbitrary types of arguments (self can now be omitted) (#1666) 2024-09-21 00:23:46 +08:00
三咲雅 · Misaki Masa
e858d11ce0
refactor: ensure that each Url contains the full location information (#1659) 2024-09-20 22:21:32 +08:00
三咲雅 · Misaki Masa
7222e178a3
perf: introduce URN to speed up large directory file updates (#1652) 2024-09-19 20:43:03 +08:00
Tyarel
dfe2884110
feat: support setting different input titles for create --dir (#1650)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-09-17 00:03:17 +08:00
三咲雅 · Misaki Masa
28083d805e
perf: introduce URN to speed up large directory locating (#1648) 2024-09-16 18:55:03 +08:00
三咲雅 · Misaki Masa
49639aa34c
perf: avoid unnecessary allocations in base64 encoding of IIP (#1639) 2024-09-15 00:39:38 +08:00
Diego Dorado
0acf5c288e
feat: support transparent image preview (#1556)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-09-15 00:00:43 +08:00
Dirk Wang
276f69128d
feat: make the builtin extract plugin support compressed tarballs (*.tar.gz, *.tar.bz2, etc.) (#1583)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-09-14 21:19:17 +08:00
三咲雅 · Misaki Masa
2453539fb5
feat: add list_meta() method to archive plugin (#1638) 2024-09-14 19:00:03 +08:00
三咲雅 · Misaki Masa
bc68d1eb01
feat: complete and consistent support for the ui.Style() API (#1637) 2024-09-12 18:45:10 +08:00
三咲雅 · Misaki Masa
61c0db8630
fix: set a dedicated Mimetype agency to reconcile regular files and search results (#1627) 2024-09-10 13:39:44 +08:00
三咲雅 · Misaki Masa
b87361023f
fix: set allow-passthrough always to all instead of on to prevent overriding a user setting with a higher priority all (#1626) 2024-09-10 12:28:48 +08:00
三咲雅 · Misaki Masa
3ee1209d3c
perf: introduce URN to speed up large directory file sorting (#1622) 2024-09-10 00:41:33 +08:00
三咲雅 · Misaki Masa
d20b3d8408
refactor: privatize url of the File (#1619) 2024-09-10 00:31:21 +08:00
sxyazi
9483798459
fix: update rustix to fix the enable_raw_mode() error on WSL/Android
https://github.com/crossterm-rs/crossterm/pull/926#issuecomment-2334770989
2024-09-07 13:52:45 +08:00
三咲雅 · Misaki Masa
0cdaff98d0
fix: match icon by extension case-insensitive (#1614) 2024-09-05 23:14:38 +08:00
sxyazi
7c445cef1f
chore: bump version to 0.3.3 2024-09-04 23:16:18 +08:00
三咲雅 · Misaki Masa
e3c653154f
feat: add dict_merge() function (#1609) 2024-09-04 21:45:51 +08:00
三咲雅 · Misaki Masa
322f5fc230
feat: add is_absolute, has_root, starts_with, ends_with, strip_prefix to Url Userdata (#1605) 2024-09-04 19:17:48 +08:00
三咲雅 · Misaki Masa
ff04e2d21f
chore: upgrade ratatui to 0.28.1 (#1601) 2024-09-04 01:48:18 +08:00
e82eric
e940d81d2a
feat: support image preview in Windows Terminal (#1588)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-09-02 11:47:30 +08:00
三咲雅 · Misaki Masa
f2dca99e43
feat: size linemode supports showing the file count for directories (#1591) 2024-09-02 09:11:30 +08:00
三咲雅 · Misaki Masa
5f4779cc90
perf: truncate long lists in confirm dialogs (#1590) 2024-09-02 07:19:22 +08:00
三咲雅 · Misaki Masa
3a2dd30166
fix: Rail component should have a higher rendering priority (#1585) 2024-09-01 16:51:05 +08:00
Solitude
fdd574997b
feat: ensure that Entity and Linemode have consistent space padding (#1580)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-09-01 15:58:38 +08:00
三咲雅 · Misaki Masa
907ac09e34
fix: continuous fetcher was not scheduled consecutively (#1575) 2024-08-31 11:57:39 +08:00
三咲雅 · Misaki Masa
a0a2331b3b
fix: fallback to PollWatcher on WSL (#1574) 2024-08-31 01:33:28 +08:00
P_Lee
69e7c8ff0d
fix: squeeze offset of the file list after resizing window (#1500)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-30 10:11:41 +08:00
taoky
598104492b
fix: check compositor support status before using ueberzug wayland output (#1566)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-30 02:00:59 +08:00
三咲雅 · Misaki Masa
b280d79f76
fix: keybindings disappear when mixing presets with a wrong filter condition (#1568) 2024-08-29 12:43:03 +08:00
sxyazi
ddb8ce530f
chore: bump version to 0.3.2 2024-08-28 12:37:54 +08:00
三咲雅 · Misaki Masa
90b1e525b8
fix: DECSET and DECRQM tmux passthrough (#1564) 2024-08-28 03:08:52 +08:00
三咲雅 · Misaki Masa
caacd15110
fix: filter out the which candidates that overlap with longer key chords (#1562) 2024-08-28 00:08:51 +08:00
Artyom Artamonov
cd7209c040
feat: word wrapping in code previewer (#1159)
Co-authored-by: Lex Moskovski <alex@moskovski.com>
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-26 09:00:09 +08:00
三咲雅 · Misaki Masa
58ba459b63
perf: only scan the first 1024 bytes to detect if it's binary, apply \r fixes only to content within the visible range, avoid unnecessary allocations during natural sorting (#1551) 2024-08-25 10:52:30 +08:00
三咲雅 · Misaki Masa
9cf85c09d2
feat: make the builtin code previewer handle invalid carriage return chars and binary streams better (#1550) 2024-08-25 02:56:38 +08:00
Zhang ShengYan
69c20d4dd3
fix: wrong debug_assert in OrderedFloat for NaN (#1547) 2024-08-24 11:33:39 +08:00
Yuri Astrakhan
c9d74360bf
docs: add links to all terminal emulators (#1538)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-23 19:14:12 +08:00
三咲雅 · Misaki Masa
0601079023
fix: wait till mimetype is resolved to avoid flickering (#1542) 2024-08-23 18:53:43 +08:00
三咲雅 · Misaki Masa
91da9d19cf
fix: use a different cache directory for each user to avoid permission issues (#1541) 2024-08-23 18:28:47 +08:00
Zhao
4fa37cb3cd
chore: set MACOSX_DEPLOYMENT_TARGE to 10.11 to make the binary compatible with old macOS (#1532)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-22 23:41:02 +08:00
thelamb
92112de1c0
feat: new confirm component (#1167)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-22 22:20:31 +08:00
三咲雅 · Misaki Masa
573ca5287f
feat: add ext() method to Url userdata (#1528) 2024-08-21 00:45:50 +08:00
Rolf K / rkaid
46f42b2f0c
feat: add --dir option to create command (#1505)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-21 00:36:30 +08:00
三咲雅 · Misaki Masa
0f106b591c
perf: new image_delay option debounces image previews to avoid lag caused by terminal image decoding during fast scrolling (#1512) 2024-08-18 23:51:17 +08:00
三咲雅 · Misaki Masa
99a3b3a043
fix: upgrade ansi-to-tui to 5.0.0-rc.1 to resolve ratatui version conflict (#1499) 2024-08-16 18:21:13 +08:00
三咲雅 · Misaki Masa
374c6a8891
fix: overlong single-line text containing escape sequences was not being properly escaped (#1497) 2024-08-16 15:40:11 +08:00
三咲雅 · Misaki Masa
4112bf451f
chore: bump version to 0.3.1 (#1492) 2024-08-15 22:39:36 +08:00
Aidan Hannigan
c43db9cf56
feat: add keybinding for the hardlink command (#1461)
Co-authored-by: ahanniga <ahanniga@ibm.com>
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-15 21:45:46 +08:00
Mika Vilpas
77d1817771
feat: new tab DDS event on tab switch (#1474)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-15 21:34:12 +08:00
三咲雅 · Misaki Masa
fc304ca043
fix: replace # with : to resolve the problem where certain shells recognize it as a special character (#1490) 2024-08-15 17:21:06 +08:00
三咲雅 · Misaki Masa
c75960eae6
feat: add hidden file type to is rule (#1483) 2024-08-14 16:08:27 +08:00
三咲雅 · Misaki Masa
62fcf27dfb
feat: new empty previewer for empty and /proc files (#1482) 2024-08-14 15:03:38 +08:00
三咲雅 · Misaki Masa
71d6b0d9f2
feat: add status() method to Command (#1473) 2024-08-12 21:03:45 +08:00
三咲雅 · Misaki Masa
a39409e699
fix: 7zip shows different error messages for RAR and ZIP files (#1468) 2024-08-12 13:35:31 +08:00
三咲雅 · Misaki Masa
44f45fd8e1
fix: DDS static messages only work when at least two instances are running (#1467) 2024-08-11 16:38:25 +08:00
三咲雅 · Misaki Masa
ce944bca88
fix: close stdin before waiting for child process (#1464) 2024-08-11 13:14:16 +08:00
coolkiid
dac72eb39a
feat: start with multiple tabs with different paths (#1443)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-10 20:42:50 +08:00
sxyazi
b066652b65
refactor: tab locking 2024-08-10 20:25:35 +08:00
三咲雅 · Misaki Masa
36381e676f
fix: loss of order in Lua sequence table for inter-thread data exchange (#1457) 2024-08-10 13:28:51 +08:00
XYenon
17c7003426
chore(nix): update dependencies (#1456) 2024-08-10 12:29:58 +08:00
三咲雅 · Misaki Masa
4150f4014c
fix: 7zip shows different error messages for wrong password (#1451) 2024-08-09 21:50:28 +08:00
HE7086
3bb867c5bd
feat: add cursor option to the shell command (#1422)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-09 18:12:28 +08:00
三咲雅 · Misaki Masa
5f923e8706
feat: allows shorthand forms like <C-S-x> as <C-X> (#1448) 2024-08-09 16:55:07 +08:00
三咲雅 · Misaki Masa
c8add31606
feat: support F13 - F19 keys (#1446) 2024-08-09 12:14:05 +08:00
三咲雅 · Misaki Masa
0954f9c58c
fix: directory loading status (#1439) 2024-08-09 11:38:47 +08:00
Isabel
6e94776781
fix(nix): pin rust-overlay to workaround cargo-c (#1442) 2024-08-08 23:07:28 +08:00
Isabel
e02b030258
refactor(nix): home keeping (#1380) 2024-08-08 22:18:01 +08:00
P_Lee
407ad266e9
fix: resolve relative path when expanding path (#1428)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-08 15:55:22 +08:00
三咲雅 · Misaki Masa
a9d2d9cd2b
fix: newly created directories with the same name causing a false positive in directory loading optimization due to having the same modification time (#1434) 2024-08-08 02:02:01 +08:00
三咲雅 · Misaki Masa
1e08e09899
feat: new search_do command to make it easier to achieve a flat view (#1431) 2024-08-07 21:36:55 +08:00
三咲雅 · Misaki Masa
5df6873957
feat: switch to kitty unicode placeholders for Ghostty image previewing (#1427) 2024-08-07 19:13:32 +08:00
Konrad Baran
f865910481
ci: add automatic nightly builds to the Github Actions workflow (#1397)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-07 08:27:00 +08:00
Julian Chen
52681b19e4
chore: update snap to core24 (#1415) 2024-08-05 17:17:10 +08:00
P_Lee
cda7d3f2ea
feat: add support portrait orientation preview for EXIF image (#1412)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-05 17:15:24 +08:00
Xerxes-2
cc50f94de6
fix: preview files containing special \x1b characters as plain text and escape (#1395)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-05 13:21:28 +08:00
Vikdos
516cd23635
fix: precache for images with alpha (#1414) 2024-08-05 09:53:12 +08:00
karimElmougi
d2ebadb631
chore: move common dependencies to workspace Cargo.toml (#1388)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-03 10:45:46 +08:00
sxyazi
3fdbbfe915
chore: update issue templates 2024-08-02 17:43:41 +08:00
Chris Zarate
3533ac20f7
feat: add title_format manager config option (#1281)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-02 16:05:58 +08:00
Mark Zaytsev
9b7821a161
feat: add filtering tip in help component (#1361)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-08-02 15:20:14 +08:00
Xerxes-2
9d1fab84ef
fix: android building error caused by trash crate (#1393) 2024-08-02 12:46:43 +08:00
1593 changed files with 77695 additions and 25152 deletions

16
.cargo/config.toml Normal file
View file

@ -0,0 +1,16 @@
[env]
MACOSX_DEPLOYMENT_TARGET = "10.12"
JEMALLOC_SYS_WITH_LG_PAGE = "16"
# environment variable for tikv-jemalloc-sys
#
# https://jemalloc.net/jemalloc.3.html#opt.narenas
# narenas is the maximum number of arenas to use for automatic multiplexing
# of threads and arenas. The default is four times the number of CPUs,
# or one if there is a single CPU.
#
# Improve memory efficiency by reducing fragmentation and ensuring all threads allocate from the same pool
JEMALLOC_SYS_WITH_MALLOC_CONF = "narenas:1"
[target.aarch64-apple-darwin]
rustflags = [ "-Ctarget-cpu=apple-m1" ]

56
.github/DISCUSSION_TEMPLATE/1-q-a.yml vendored Normal file
View file

@ -0,0 +1,56 @@
body:
- type: dropdown
id: os
attributes:
label: What system are you running Yazi on?
options:
- Linux X11
- Linux Wayland
- macOS
- Windows
- Windows WSL
- FreeBSD X11
- FreeBSD Wayland
- Android
validations:
required: true
- type: input
id: terminal
attributes:
label: What terminal are you running Yazi in?
placeholder: "ex: kitty v0.32.2"
validations:
required: true
- type: textarea
id: env
attributes:
label: "`ya env` output"
description: Run `ya env` and paste the environment information here.
render: Shell
validations:
required: true
- type: textarea
id: description
attributes:
label: Describe the question
description: A clear and concise description of what the question is
placeholder: Tell us what you want to know
validations:
required: true
- type: textarea
id: other
attributes:
label: Anything else?
description: |
Add any other context about the problem here. You can attach screenshots by clicking
this area to highlight it and then drag the files in.
- type: checkboxes
id: checklist
attributes:
label: Checklist
description: Before submitting the post, please make sure you have completed the following
options:
- label: I have read all the documentation
required: true
- label: I have searched the existing discussions/issues
required: true

View file

@ -1,4 +1,4 @@
name: Bug Report
name: 🐞 Bug Report
description: Create a report to help us improve
labels: [bug]
assignees: []
@ -15,6 +15,7 @@ body:
- Windows WSL
- FreeBSD X11
- FreeBSD Wayland
- Android
validations:
required: true
- type: input
@ -25,29 +26,11 @@ body:
validations:
required: true
- type: textarea
id: debug
id: env
attributes:
label: "`yazi --debug` output"
description: Please run `yazi --debug` and paste the debug information here.
value: |
<details>
```sh
##### ↓↓↓ Paste the output here: ↓↓↓ #####
```
</details>
validations:
required: true
- type: dropdown
id: tried_main
attributes:
label: Did you try the latest nightly build to see if the problem got fixed?
options:
- Yes, and I updated the debug information above (`yazi --debug`) to the nightly that I tried
- No, and I'll explain why below
label: "`ya env` output"
description: Run `ya env` and paste the environment information here.
render: Shell
validations:
required: true
- type: textarea
@ -59,28 +42,14 @@ body:
validations:
required: true
- type: textarea
id: expected
id: reproducer
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen
validations:
required: true
- type: textarea
id: to_repro
attributes:
label: To Reproduce
description: Steps to reproduce the behavior
label: Minimal reproducer
description: A [minimal reproducer](https://stackoverflow.com/help/minimal-reproducible-example) is required, otherwise the issue might be closed without further notice.
placeholder: |
Please include as much information as possible that can help to reproduce and understand the issue.
validations:
required: true
- type: textarea
id: config
attributes:
label: Configuration
description: |
Please include the relevant section(s) of your `yazi.toml`, `keymap.toml`, or `theme.toml` configuration file.
You can enter "no config" if the issue happens without you having made a config file.
- type: textarea
id: other
attributes:
@ -88,3 +57,14 @@ body:
description: |
Add any other context about the problem here. You can attach screenshots by clicking
this area to highlight it and then drag the files in.
- type: checkboxes
id: checklist
attributes:
label: Checklist
description: Before submitting the issue, please make sure you have completed the following
options:
- label: I tried the [latest nightly build](https://yazi-rs.github.io/docs/installation#binaries), and the issue is still reproducible
required: true
- label: I updated the environment information (`ya env`) field to the nightly that I tried
required: true
- label: I can reproduce it after disabling all custom configs/plugins (`mv ~/.config/yazi ~/.config/yazi-backup`)

View file

@ -1,8 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: Discord server / Telegram group
- name: 🚧 Build Issues
url: https://github.com/sxyazi/yazi/discussions/new?category=3-build-issues
about: If you have issues building Yazi from source code
- name: 📝 Documentation Improvement
url: https://github.com/yazi-rs/yazi-rs.github.io
about: If you'd like to help improve the documentation
- name: 💬 GitHub Discussions
url: https://github.com/sxyazi/yazi/discussions/new?category=1-q-a
about: When you have questions that are not bug reports or feature requests
- name: 🌐 Discord Server / Telegram Group
url: https://github.com/sxyazi/yazi#discussion
about: If you'd prefer more realtime conversation with the community
- name: GitHub Discussions
url: https://github.com/sxyazi/yazi/discussions
about: When you have questions that are not bug reports or feature requests

View file

@ -1,8 +1,16 @@
name: Feature Request
name: 💡 Feature Request
description: Suggest an idea for this project
labels: [feature]
assignees: []
body:
- type: textarea
id: env
attributes:
label: "`ya env` output"
description: Run `ya env` and paste the environment information here.
render: Shell
validations:
required: true
- type: textarea
id: problem
attributes:
@ -29,3 +37,13 @@ body:
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here.
- type: checkboxes
id: checklist
attributes:
label: Checklist
description: Before submitting the issue, please make sure you have completed the following
options:
- label: I have searched the existing issues/discussions
required: true
- label: The [latest nightly build](https://yazi-rs.github.io/docs/installation/#binaries) doesn't already have this feature
required: true

15
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
- package-ecosystem: "npm"
directory: "/scripts/validate-form"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"

24
.github/pull_request_template.md vendored Normal file
View file

@ -0,0 +1,24 @@
## Which issue does this PR resolve?
<!--
For any fixes and enhancements, we usually require an associated issue to be filed where clearly detailed your proposed changes and why they are necessary, which ensures we are aligned and reduces the risk of re-work.
You can use GitHub syntax to link an issue to this PR, such as `Resolves #1000`, which indicates this PR will resolve issue #1000.
-->
Resolves #
## Rationale of this PR
<!--
A clear and concise description of the rationale of the changes, to help our reviewers understand your intent and why it is necessary.
If it has already been detailed in the associated issue, please skip this section.
-->
## Checklist
- [ ] I have read [CONTRIBUTING.md](https://github.com/sxyazi/yazi/blob/main/CONTRIBUTING.md)
- [ ] I confirm this PR follows the [AI Policy](https://github.com/sxyazi/yazi/blob/main/CONTRIBUTING.md#ai-policy)
<!-- AI bots are not allowed to open PRs in this repository. All PRs must be made by humans and comply with the AI policy. -->

View file

@ -1,8 +1,11 @@
name: Cachix
on:
push:
branches:
- main
branches: [main]
permissions:
contents: read
jobs:
publish:
@ -12,13 +15,13 @@ jobs:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Install Nix
uses: cachix/install-nix-action@v25
uses: cachix/install-nix-action@v31
- name: Authenticate with Cachix
uses: cachix/cachix-action@v14
uses: cachix/cachix-action@v17
with:
name: yazi
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"

View file

@ -6,19 +6,26 @@ on:
pull_request:
branches: [main]
env:
SCCACHE_GHA_ENABLED: true
RUSTC_WRAPPER: sccache
permissions:
contents: read
jobs:
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Setup Rust toolchain
run: |
rustup toolchain install stable --profile minimal
rustup component add clippy
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Clippy
run: cargo clippy --all
@ -27,24 +34,24 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Setup Rust toolchain
run: |
rustup toolchain install nightly --profile minimal
rustup component add rustfmt --toolchain nightly
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Rustfmt
run: cargo +nightly fmt --all -- --check
run: find . -name '*.rs' -not -path './target/*' -exec rustfmt +nightly --check {} +
stylua:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: JohnnyMorganz/stylua-action@v4
- uses: actions/checkout@v7
- uses: JohnnyMorganz/stylua-action@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest

View file

@ -2,8 +2,15 @@ name: Draft
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
branches: [main]
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
workflow_dispatch:
env:
SCCACHE_GHA_ENABLED: true
permissions:
contents: read
jobs:
build-unix:
@ -14,29 +21,50 @@ jobs:
target: x86_64-unknown-linux-gnu
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
gcc: gcc-aarch64-linux-gnu
- os: ubuntu-latest
target: i686-unknown-linux-gnu
gcc: gcc-i686-linux-gnu
- os: ubuntu-latest
target: riscv64gc-unknown-linux-gnu
gcc: gcc-riscv64-linux-gnu
- os: ubuntu-latest
target: sparc64-unknown-linux-gnu
gcc: gcc-sparc64-linux-gnu
- os: macos-latest
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin
runs-on: ${{ matrix.os }}
env:
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER: i686-linux-gnu-gcc
CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER: riscv64-linux-gnu-gcc
CARGO_TARGET_SPARC64_UNKNOWN_LINUX_GNU_LINKER: sparc64-linux-gnu-gcc
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Install gcc-aarch64-linux-gnu
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update && sudo apt-get install -yq gcc-aarch64-linux-gnu
echo "JEMALLOC_SYS_WITH_LG_PAGE=16" >> $GITHUB_ENV
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc" >> $GITHUB_ENV
- name: Install gcc
if: matrix.gcc != ''
run: sudo apt update && sudo apt install -yq ${{ matrix.gcc }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Build
run: ./scripts/build.sh ${{ matrix.target }}
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: yazi-${{ matrix.target }}.zip
path: yazi-${{ matrix.target }}.zip
name: ${{ matrix.target }}
path: |
yazi-${{ matrix.target }}.zip
yazi-${{ matrix.target }}.deb
build-windows:
strategy:
@ -47,38 +75,40 @@ jobs:
- os: windows-latest
target: aarch64-pc-windows-msvc
runs-on: ${{ matrix.os }}
env:
RUSTC_WRAPPER: sccache
YAZI_GEN_COMPLETIONS: true
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: lld-link.exe
CARGO_TARGET_AARCH64_PC_WINDOWS_MSVC_LINKER: lld-link.exe
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Setup Rust toolchain
run: rustup toolchain install stable --profile minimal
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Add target
run: rustup target add ${{ matrix.target }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Build
env:
YAZI_GEN_COMPLETIONS: true
run: |
cargo build -p yazi-cli --release --locked --target ${{ matrix.target }}
cargo build -p yazi-fm --release --locked --target ${{ matrix.target }}
run: cargo build --profile release-windows --locked --target ${{ matrix.target }}
- name: Pack artifact
if: matrix.os == 'windows-latest'
env:
TARGET_NAME: yazi-${{ matrix.target }}
run: |
New-Item -ItemType Directory -Path ${env:TARGET_NAME}
Copy-Item -Path "target\${{ matrix.target }}\release\ya.exe" -Destination ${env:TARGET_NAME}
Copy-Item -Path "target\${{ matrix.target }}\release\yazi.exe" -Destination ${env:TARGET_NAME}
Copy-Item -Path "yazi-boot\completions" -Destination ${env:TARGET_NAME} -Recurse
New-Item -ItemType Directory -Path "${env:TARGET_NAME}\completions"
Copy-Item -Path "target\${{ matrix.target }}\release-windows\ya.exe" -Destination ${env:TARGET_NAME}
Copy-Item -Path "target\${{ matrix.target }}\release-windows\yazi.exe" -Destination ${env:TARGET_NAME}
Copy-Item -Path "yazi-cli\completions\*" -Destination "${env:TARGET_NAME}\completions"
Copy-Item -Path "yazi-boot\completions\*" -Destination "${env:TARGET_NAME}\completions"
Copy-Item -Path "README.md", "LICENSE" -Destination ${env:TARGET_NAME}
Compress-Archive -Path ${env:TARGET_NAME} -DestinationPath "${env:TARGET_NAME}.zip"
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: yazi-${{ matrix.target }}.zip
name: ${{ matrix.target }}
path: yazi-${{ matrix.target }}.zip
build-musl:
@ -87,61 +117,144 @@ jobs:
matrix:
include:
- target: x86_64-unknown-linux-musl
image: rust-musl-cross:x86_64-musl
- target: aarch64-unknown-linux-musl
image: rust-musl-cross:aarch64-musl
container:
image: docker://ghcr.io/rust-cross/${{ matrix.image }}
image: docker://ghcr.io/cross-rs/${{ matrix.target }}:edge
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Build
run: ./scripts/build.sh ${{ matrix.target }}
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: yazi-${{ matrix.target }}.zip
path: yazi-${{ matrix.target }}.zip
name: ${{ matrix.target }}
path: |
yazi-${{ matrix.target }}.zip
yazi-${{ matrix.target }}.deb
build-snap:
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
arch: amd64
- os: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Setup LXD
uses: canonical/setup-lxd@v1
- name: Setup snapcraft
run: sudo snap install --classic snapcraft
- name: Build snap
uses: snapcore/action-build@v1
run: snapcraft --verbose
- name: Build
run: mv yazi_*.snap yazi-${{ matrix.target }}.snap
- name: Rename snap
run: mv yazi_*.snap yazi-${{ matrix.arch }}.snap
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: yazi-${{ matrix.target }}.snap
path: yazi-${{ matrix.target }}.snap
name: snap-${{ matrix.arch }}
path: yazi-${{ matrix.arch }}.snap
snap:
runs-on: ubuntu-latest
needs: [build-snap]
steps:
- uses: actions/download-artifact@v8
with:
pattern: snap-*
merge-multiple: true
- name: Setup snapcraft
run: sudo snap install --classic snapcraft
- name: Push snap to candidate channel
if: startsWith(github.ref, 'refs/tags/')
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }}
run: |
parallel 'snapcraft upload -v --release latest/candidate {}' ::: yazi-*.snap || true
- name: Push snap to edge channel
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }}
run: |
parallel 'snapcraft upload -v --release latest/edge {}' ::: yazi-*.snap || true
draft:
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: write
runs-on: ubuntu-latest
needs: [build-unix, build-windows, build-musl, build-snap]
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v8
with:
merge-multiple: true
- name: Draft
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v3
with:
draft: true
files: |
yazi-*.zip
yazi-*.deb
yazi-*.snap
generate_release_notes: true
nightly:
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
permissions:
contents: write
runs-on: ubuntu-latest
needs: [build-unix, build-windows, build-musl, build-snap]
steps:
- run: |
echo 'NIGHTLY_BODY<<EOF' >> $GITHUB_ENV
echo "From commit: ${GITHUB_SHA:0:8}" >> $GITHUB_ENV
echo "Generated on: $(date -u +"%Y-%m-%d %H:%M") UTC" >> $GITHUB_ENV
echo "Nightly changelog: https://github.com/sxyazi/yazi/blob/main/CHANGELOG.md#unreleased" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
with:
merge-multiple: true
- name: Update the tag
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag --force nightly && git push --force origin tag nightly
- name: Nightly
uses: softprops/action-gh-release@v3
with:
tag_name: nightly
prerelease: true
files: |
yazi-*.zip
yazi-*.deb
yazi-*.snap
name: Nightly Build
body: ${{ env.NIGHTLY_BODY }}
target_commitish: ${{ github.sha }}

View file

@ -16,14 +16,14 @@ jobs:
pull-requests: write
discussions: write
steps:
- uses: dessant/lock-threads@v5
- uses: dessant/lock-threads@v6
with:
issue-inactive-days: "30"
issue-comment: >
I'm going to lock this issue because it has been closed for _30 days_. ⏳
This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new
If you have found a problem that seems similar to this, please file a new
issue and complete the issue template so we can capture all the details
necessary to investigate further.
pr-inactive-days: "30"

View file

@ -4,11 +4,14 @@ on:
release:
types: [published]
permissions:
contents: read
jobs:
winget:
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v8
with:
merge-multiple: true
@ -18,3 +21,17 @@ jobs:
identifier: sxyazi.yazi
installers-regex: 'yazi-(x86_64|aarch64)-pc-windows-msvc\.zip$'
token: ${{ secrets.WINGET_TOKEN }}
snapcraft:
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v8
with:
merge-multiple: true
- name: Promote snap to stable
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }}
run: |
sudo snap install --classic snapcraft
snapcraft promote yazi --from-channel latest/candidate --to-channel latest/stable --yes

View file

@ -7,8 +7,13 @@ on:
branches: [main]
env:
SCCACHE_GHA_ENABLED: true
RUSTC_WRAPPER: sccache
CARGO_TERM_COLOR: always
permissions:
contents: read
jobs:
test:
strategy:
@ -16,16 +21,16 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Setup Rust toolchain
run: rustup toolchain install stable --profile minimal
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Build
run: cargo build --verbose
- name: Test
run: cargo test --all --verbose
run: cargo test --workspace --verbose

34
.github/workflows/validate-issue.yml vendored Normal file
View file

@ -0,0 +1,34 @@
name: Validate Issue
on:
issues:
types: [opened, edited]
schedule:
- cron: "20 * * * *"
jobs:
check-version:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: 20
- name: Install Dependencies
run: |
cd scripts/validate-form
npm ci
- name: Validate Issue
uses: actions/github-script@v9
with:
script: |
const script = require('./scripts/validate-form/main.js')
await script({github, context, core})
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

36
.github/workflows/validate-pr.yml vendored Normal file
View file

@ -0,0 +1,36 @@
name: Validate PR
on:
pull_request:
types: [opened, edited, reopened, synchronize]
permissions:
contents: read
pull-requests: read
jobs:
check-list:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.repository.default_branch }}
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: 20
- name: Install Dependencies
run: |
cd scripts/validate-form
npm ci
- name: Validate PR
uses: actions/github-script@v9
with:
script: |
const script = require('./scripts/validate-form/main.js')
await script({github, context, core})
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

5
.gitignore vendored
View file

@ -1,5 +1,6 @@
target/
yazi-config/completions
yazi-*/completions
node_modules/
.DS_Store
@ -9,3 +10,5 @@ result-*
.idea/
.vscode/
*.snap

9
.luarc.json Normal file
View file

@ -0,0 +1,9 @@
{
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
"runtime.version": "Lua 5.5",
"runtime.special": {
"fail": "error"
},
"workspace.library": ["~/.config/yazi/plugins/types.yazi/"],
"diagnostics.disable": ["redefined-local"]
}

View file

@ -1,2 +0,0 @@
# this file caused some issues with the build system
yazi-plugin/preset/plugins/mime.lua

1785
CHANGELOG.md Normal file

File diff suppressed because it is too large Load diff

76
CODE_OF_CONDUCT.md Normal file
View file

@ -0,0 +1,76 @@
# Code of Conduct
## Goal
Our goal is to create a welcoming and safe space where anyone can contribute and seek help for this project in a respectful, collaborative
and harassment-free way.
All contributions are welcome and encourage everyone to participate regardless of age, body size, disability, ethnicity, sex characteristics,
gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion,
or sexual identity and orientation.
## Standards
Our standards are as follows:
- Respect different viewpoints and opinions
- Do not harass, attack, or discriminate against others for any reason. We have zero tolerance for harassment
- Communicate professionally and constructively. Do not post spam or go off-topic
- Assume goodwill in conversations. Misunderstandings happen, so give others the benefit of the doubt before jumping to conclusions
Examples of unacceptable behavior include:
- Trolling, insulting or derogatory comments, and personal attacks
- Harassing or bullying another person
- Publishing others' private information without their explicit permission
- Posting things unrelated to the topic being discussed
- Other conduct that could reasonably be considered inappropriate in a professional setting
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported here: https://discord.com/users/638378964804698112
All reporters are guaranteed privacy, and your reports will always be kept private and secure.
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate.
The following is a list of consequences that you may face if you are found to be breaking the terms of the CoC.
### 1. Correction
A private warning with an explanation as to why the behavior was not appropriate.
### 2. Warning
A private or public warning with consequences for continued behavior.
### 3. Temporary Ban
A temporary ban from any sort of interaction or public communication with the community for a specified period of time.
### 4. Permanent Ban
A permanent ban from any sort of public interaction within the community.
## Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the
community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official
social media account, or acting as an appointed representative at an online or offline event.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View file

@ -10,7 +10,8 @@ This guide will help you understand how to contribute to the project.
2. [Project Structure](#project-structure)
3. [Development Setup](#development-setup)
4. [How to Contribute](#how-to-contribute)
5. [Pull Request Process](#pull-request-process)
5. [Pull Requests](#pull-requests)
6. [AI Policy](#ai-policy)
## Getting Started
@ -46,16 +47,23 @@ A brief overview of the project's structure:
├── scripts/ # Helper scripts used by CI/CD
├── snap/ # Snapcraft configuration
├── yazi-adapter/ # Yazi image adapter
├── yazi-binding/ # Yazi Lua bindings
├── yazi-boot/ # Yazi bootstrapper
├── yazi-cli/ # Yazi command-line interface
├── yazi-codegen/ # Yazi code generator
├── yazi-config/ # Yazi configuration file parser
├── yazi-core/ # Yazi core logic
├── yazi-dds/ # Yazi data distribution service
├── yazi-ffi/ # Yazi foreign function interface
├── yazi-fm/ # Yazi file manager
├── yazi-fs/ # Yazi file system
├── yazi-macro/ # Yazi macros
├── yazi-plugin/ # Yazi plugin system
├── yazi-proxy/ # Yazi event proxy
├── yazi-scheduler/ # Yazi task scheduler
├── yazi-shared/ # Yazi shared library
├── yazi-term/ # Yazi terminal extensions
├── yazi-widgets/ # Yazi user interface widgets
├── .github/ # GitHub-specific files and workflows
├── Cargo.toml # Rust workflow configuration
└── README.md # Project overview
@ -79,7 +87,7 @@ A brief overview of the project's structure:
3. Run the tests:
```sh
cargo test
cargo test --workspace --verbose
```
4. Format the code (requires `rustfmt` nightly):
@ -93,15 +101,21 @@ A brief overview of the project's structure:
### Reporting Bugs
If you find a bug, please file an issue.
If you encounter a bug and have found a way to reliably reproduce it on the latest `main` branch, please file a [bug report](https://github.com/sxyazi/yazi/issues/new?template=bug.yml) with a [minimal reproducer](https://stackoverflow.com/help/minimal-reproducible-example).
### Suggesting Features
If you have a feature request, please file an issue.
If you want to request a feature, please file a [feature request](https://github.com/sxyazi/yazi/issues/new?template=feature.yml). Please make sure to search for existing issues and discussions before submitting.
### Improving Documentation
Yazi's documentation placed at [yazi-rs/yazi-rs.github.io](https://github.com/yazi-rs/yazi-rs.github.io), contributions related to documentation need to be made within this repository.
Yazi's documentation placed at [yazi-rs/yazi-rs.github.io](https://github.com/yazi-rs/yazi-rs.github.io), contributions related to documentation need to be made there.
### Improving Icons
Yazi's icon originates from [`nvim-web-devicons`](https://github.com/nvim-tree/nvim-web-devicons), and it is periodically grabbed and updated with the latest changes from upstream via [`generate.lua`](https://github.com/sxyazi/yazi/blob/main/scripts/icons/generate.lua).
Contributions related to the icon should be made upstream to facilitate easier automation of this process.
### Submitting Code Changes
@ -119,11 +133,18 @@ Yazi's documentation placed at [yazi-rs/yazi-rs.github.io](https://github.com/ya
```
4. Push your changes to your fork:
```sh
git push origin your-branch-name
```
## Pull Request Process
## Pull Requests
If you have an idea, before raising a pull request, we encourage you to file an issue to propose it, ensuring that we are aligned and reducing the risk of re-work.
We want you to succeed, and it can be discouraging to find that a lot of re-work is needed.
### Process
1. Ensure your fork is up-to-date with the upstream repository:
@ -133,7 +154,7 @@ Yazi's documentation placed at [yazi-rs/yazi-rs.github.io](https://github.com/ya
git merge upstream/main
```
2. Rebase your feature branch onto the main branch:
2. Rebase your feature branch onto the `main` branch:
```sh
git checkout your-branch-name
@ -144,3 +165,10 @@ Yazi's documentation placed at [yazi-rs/yazi-rs.github.io](https://github.com/ya
- Your code passes all tests and lints.
- Your pull request description clearly explains the changes and why they are needed.
4. Address any review comments. Make sure to push updates to the same branch on your fork.
## AI Policy
1. All issue, PR, and discussion descriptions must be written by humans, not AI.
2. Any use of AI must be disclosed. You must declare which model you used and the extent of AI assistance.
3. Any AI-generated code must be reviewed, tested, and simplified by a human before publishing. This requires you to fully understand how it interacts with the greater system without AI assistance.
4. Any AI tools used must explicitly state they do not assert copyright over the work.

4336
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,97 @@
[workspace]
resolver = "2"
resolver = "3"
members = [ "yazi-*" ]
default-members = [ "yazi-fm", "yazi-cli" ]
[workspace.package]
edition = "2024"
version = "26.5.6"
license = "MIT"
authors = [ "sxyazi <sxyazi@gmail.com>" ]
homepage = "https://yazi-rs.github.io"
repository = "https://github.com/sxyazi/yazi"
rust-version = "1.95.0"
[profile.dev]
debug = "line-tables-only"
[profile.release]
codegen-units = 1
lto = true
panic = "abort"
strip = true
[profile.release-windows]
inherits = "release"
panic = "unwind"
[profile.dev-opt]
inherits = "release"
codegen-units = 256
incremental = true
lto = false
[profile.dev.package."*"]
debug = false
[workspace.dependencies]
ansi-to-tui = "8.0.1"
anyhow = "1.0.104"
arc-swap = { version = "1.9.2", features = [ "serde" ] }
base64 = "0.22.1"
bitflags = { version = "2.13.1", features = [ "serde" ] }
chrono = "0.4.45"
clap = { version = "4.6.2", features = [ "derive" ] }
compact_str = { version = "0.10.0", features = [ "serde" ] }
core-foundation-sys = "0.8.7"
data-encoding = "2.11.0"
dirs = "6.0.0"
dyn-clone = "1.0.20"
either = { version = "1.16.0" }
foldhash = "0.2.0"
futures = "0.3.33"
globset = "0.4.19"
hashbrown = { version = "0.17.1", features = [ "serde" ] }
image = { version = "0.25.10", default-features = false, features = [ "avif", "bmp", "dds", "exr", "ff", "gif", "hdr", "ico", "jpeg", "png", "pnm", "qoi", "tga", "tiff", "webp" ] }
indexmap = { version = "2.14.0", features = [ "serde" ] }
inventory = "0.3.24"
libc = "0.2.186"
lru = "0.18.1"
mlua = { version = "0.12.0", features = [ "anyhow", "async", "error-send", "lua55", "macros", "serde" ] }
objc2 = "0.6.4"
ordered-float = { version = "5.3.0", features = [ "serde" ] }
parking_lot = "0.12.5"
paste = "1.0.15"
percent-encoding = "2.3.2"
rand = { version = "0.10.2", default-features = false, features = [ "std", "sys_rng" ] }
ratatui-core = { version = "0.1.2", default-features = false, features = [ "std", "layout-cache", "serde", "underline-color" ] }
ratatui-widgets = { version = "0.3.2", default-features = false, features = [ "std", "unstable-rendered-line-info" ] }
regex = "1.13.1"
russh = { version = "0.62.2", default-features = false, features = [ "ring", "rsa" ] }
scopeguard = "1.2.0"
serde = { version = "1.0.229", features = [ "derive" ] }
serde_json = "1.0.151"
serde_with = "3.21.0"
strum = { version = "0.28.0", features = [ "derive" ] }
syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
thiserror = "2.0.19"
tokio = { version = "1.53.0", features = [ "full" ] }
tokio-stream = "0.1.18"
tokio-util = "0.7.18"
toml = { version = "1.1.3" }
tracing = { version = "0.1.44", features = [ "max_level_debug", "release_max_level_debug" ] }
twox-hash = { version = "2.1.3", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
typed-path = "0.12.3"
unicode-width = { version = "0.2.2", default-features = false }
uzers = "0.12.2"
[workspace.lints.clippy]
format_push_string = "warn"
if_same_then_else = "allow"
implicit_clone = "warn"
len_without_is_empty = "allow"
missing_safety_doc = "allow"
module_inception = "allow"
option_map_unit_fn = "allow"
unit_arg = "allow"
use_self = "warn"

View file

@ -1,5 +1,9 @@
<div align="center">
<img src="assets/logo.png" alt="Yazi logo" width="20%">
<sup>Special thanks to:</sup><br>
| <a href="https://go.warp.dev/yazi" target="_blank"><img alt="Warp sponsorship" width=350 src="https://github.com/warpdotdev/brand-assets/blob/main/Github/Sponsor/Warp-Github-LG-02.png"><br><b>Warp, built for coding with multiple AI agents</b><br><sup>Available for macOS, Linux and Windows</sup></a> |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
</div>
## Yazi - ⚡️ Blazing Fast Terminal File Manager
@ -12,19 +16,24 @@ Yazi (means "duck") is a terminal file manager written in Rust, based on non-blo
- 💪 **Powerful Async Task Scheduling and Management**: Provides real-time progress updates, task cancellation, and internal task priority assignment.
- 🖼️ **Built-in Support for Multiple Image Protocols**: Also integrated with Überzug++ and Chafa, covering almost all terminals.
- 🌟 **Built-in Code Highlighting and Image Decoding**: Combined with the pre-loading mechanism, greatly accelerates image and normal file loading.
- 🔌 **Concurrent Plugin System**: UI plugins (rewriting most of the UI), functional plugins, custom previewer/preloader/fetcher; Just some pieces of Lua.
- 🔌 **Concurrent Plugin System**: UI plugins (rewriting most of the UI), functional plugins, custom previewer/preloader/spotter/fetcher; Just some pieces of Lua.
- ☁️ **Virtual Filesystem**: Remote file management, custom search engines.
- 📡 **Data Distribution Service**: Built on a client-server architecture (no additional server process required), integrated with a Lua-based publish-subscribe model, achieving cross-instance communication and state persistence.
- 📦 **Package Manager**: Install plugins and themes with one command, keeping them up to date, or pin them to a specific version.
- 📦 **Package Manager**: Install plugins and themes with one command, keeping them up-to-date, or pin them to a specific version.
- 🧰 Integration with ripgrep, fd, fzf, zoxide
- 💫 Vim-like input/select/which/notify component, auto-completion for cd paths
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, directories, code, etc.)
- 🔄 Bulk Renaming, Visual Mode, File Chooser
- 🎨 Theme System, Mouse Support, Trash Bin, Custom Layouts, CSI u
- 💫 Vim-like input/pick/confirm/which/notify component, auto-completion for cd paths
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, code, directories, etc.)
- 🔄 Bulk Rename/Create, Archive Extraction, Visual Mode, File Chooser, [Git Integration](https://github.com/yazi-rs/plugins/tree/main/git.yazi), [Mount Manager](https://github.com/yazi-rs/plugins/tree/main/mount.yazi)
- 🎨 Theme System, Mouse Support, Drag and Drop, Trash Bin, Custom Layouts, CSI u, OSC 52
- ... and more!
https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265cc7
⚠️ Note: Yazi is currently in heavy development and may be unstable. The API is subject to change without prior notice.
## Project status
Public beta, can be used as a daily driver.
Yazi is currently in heavy development, expect breaking changes.
## Documentation
@ -38,24 +47,48 @@ https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265
## Image Preview
| Platform | Protocol | Support |
| ----------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| kitty | [Kitty unicode placeholders](https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders) | ✅ Built-in |
| Konsole | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/kitty_old.rs) | ✅ Built-in |
| iTerm2 | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
| WezTerm | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
| Mintty (Git Bash) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
| foot | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
| Ghostty | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/kitty_old.rs) | ✅ Built-in |
| Black Box | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
| VSCode | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
| Tabby | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
| Hyper | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
| X11 / Wayland | Window system protocol | ☑️ [Überzug++](https://github.com/jstkdng/ueberzugpp) required |
| Fallback | [ASCII art (Unicode block)](https://en.wikipedia.org/wiki/ASCII_art) | ☑️ [Chafa](https://hpjansson.org/chafa/) required |
| Platform | Protocol | Support |
| ---------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------- |
| [kitty](https://github.com/kovidgoyal/kitty) (>= 0.28.0) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
| [iTerm2](https://iterm2.com) | [Inline images protocol][iip] | ✅ Built-in |
| [WezTerm](https://github.com/wez/wezterm) | [Inline images protocol][iip] | ✅ Built-in |
| [Konsole](https://invent.kde.org/utilities/konsole) | [Kitty old protocol][kgp-old] | ✅ Built-in |
| [foot](https://codeberg.org/dnkl/foot) | [Sixel graphics format][sixel] | ✅ Built-in |
| [Ghostty](https://github.com/ghostty-org/ghostty) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
| [Windows Terminal](https://github.com/microsoft/terminal) (>= v1.22.10352.0) | [Sixel graphics format][sixel] | ✅ Built-in |
| [st with Sixel patch](https://github.com/bakkeby/st-flexipatch) | [Sixel graphics format][sixel] | ✅ Built-in |
| [Warp](https://www.warp.dev) (macOS/Linux only) | [Inline images protocol][iip] | ✅ Built-in |
| [Tabby](https://github.com/Eugeny/tabby) | [Inline images protocol][iip] | ✅ Built-in |
| [VSCode](https://github.com/microsoft/vscode) | [Inline images protocol][iip] | ✅ Built-in |
| [Rio](https://github.com/raphamorim/rio) (>= 0.3.9) | [Kitty unicode placeholders][kgp] | ✅ Built-in |
| [Black Box](https://gitlab.gnome.org/raggesilver/blackbox) | [Sixel graphics format][sixel] | ✅ Built-in |
| [Bobcat](https://github.com/ismail-yilmaz/Bobcat) | [Inline images protocol][iip] | ✅ Built-in |
| X11 / Wayland | Window system protocol | ☑️ [Überzug++][ueberzug] required |
| Fallback | [ASCII art (Unicode block)][ascii-art] | ☑️ [Chafa][chafa] required (>= 1.16.0) |
See https://yazi-rs.github.io/docs/image-preview for details.
<!-- Protocols -->
[kgp]: https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders
[kgp-old]: https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/drivers/kgp_old.rs
[iip]: https://iterm2.com/documentation-images.html
[sixel]: https://www.vt100.net/docs/vt3xx-gp/chapter14.html
[ascii-art]: https://en.wikipedia.org/wiki/ASCII_art
<!-- Dependencies -->
[ueberzug]: https://github.com/jstkdng/ueberzugpp
[chafa]: https://hpjansson.org/chafa/
## Special Thanks
<img alt="RustRover logo" align="right" width="200" src="https://resources.jetbrains.com/storage/products/company/brand/logos/RustRover.svg">
Thanks to RustRover team for providing open-source licenses to support the maintenance of Yazi.
Active code contributors can contact @sxyazi to get a license (if any are still available).
## License
Yazi is MIT-licensed. For more information check the [LICENSE](LICENSE) file.

View file

@ -1,11 +1,11 @@
[Desktop Entry]
Name=Yazi
Name=Yazi File Manager
Icon=yazi
Comment=Blazing fast terminal file manager written in Rust, based on async I/O
Terminal=true
TryExec=yazi
Exec=yazi %u
Exec=yazi %f
Type=Application
MimeType=inode/directory
Categories=Utility;Core;System;FileTools;FileManager;ConsoleOnly
Categories=System;FileManager;FileTools;ConsoleOnly
Keywords=File;Manager;Explorer;Browser;Launcher

View file

@ -1 +1 @@
{"flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp"," Überzug"," Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM"],"language":"en","version":"0.2"}
{"flagWords":[],"version":"0.2","language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","Konsole","Überzug","pkgs","pdftoppm","poppler","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","ffprobe","vframes","luma","obase","outln","errln","tmtheme","twox","cfgs","fstype","objc","rdev","runloop","exfat","rclone","DECRQSS","DECSCUSR","libvterm","Uninit","lockin","rposition","resvg","foldhash","tilded","futs","chdir","hashbrown","JEMALLOC","RUSTFLAGS","RDONLY","GETPATH","fcntl","casefold","inodes","Splatable","casefied","thiserror","memchr","memmem","russh","deadpool","keepalive","nodelay","publickey","deadpool","initing","treelize","TOCTOU","fellback","watchee","Textlike","sstr","pointee","writef","wakeup","nonblocking","sigwinch","timespec","termios","tcgetattr","tcsetattr","tcgetwinsize","rustix","codepoint","codepoints","Raterm","mimetypes","Mimelist","renderables","redrawer","Padable"]}

18
flake.lock generated
View file

@ -5,11 +5,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1722141560,
"narHash": "sha256-Ul3rIdesWaiW56PS/Ak3UlJdkwBrD4UcagCmXZR9Z7Y=",
"lastModified": 1783279667,
"narHash": "sha256-/NAkDSsve+GNM0Bt6tleJdCGfsTlK89nPjkVOzZMo0s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "038fb464fcfa79b4f08131b07f2d8c9a6bcc4160",
"rev": "f205b5574fd0cb7da5b702a2da51507b7f4fdd1b",
"type": "github"
},
"original": {
@ -48,11 +48,11 @@
]
},
"locked": {
"lastModified": 1722133294,
"narHash": "sha256-XKSVN+lmjVEFPjMa5Ui0VTay2Uvqa74h0MQT0HU1pqw=",
"lastModified": 1783320166,
"narHash": "sha256-l7C/OsjcnWDOk2K3ssj+SBduwL67LashjBqis9+t468=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "9803f6e04ca37a2c072783e8297d2080f8d0e739",
"rev": "20ee15370c9256669d66968b89ee20a4b0a4e673",
"type": "github"
},
"original": {

View file

@ -4,10 +4,7 @@
flake-utils.url = "github:numtide/flake-utils";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
};
inputs.nixpkgs.follows = "nixpkgs";
};
};
@ -15,47 +12,61 @@
{
self,
nixpkgs,
flake-utils,
rust-overlay,
flake-utils,
...
}@inputs:
let
# Nixpkgs overlays
overlays = [
rust-overlay.overlays.default
(final: _: {
rustToolchain = final.rust-bin.stable.latest.default.override { extensions = [ "rust-src" ]; };
})
];
in
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system overlays; };
rev = self.shortRev or "dirty";
pkgs = import nixpkgs {
inherit system;
overlays = [ rust-overlay.overlays.default ];
};
toolchain = pkgs.rust-bin.stable.latest.default;
rustPlatform = pkgs.makeRustPlatform {
cargo = toolchain;
rustc = toolchain;
};
rev = self.shortRev or self.dirtyShortRev or "dirty";
date = self.lastModifiedDate or self.lastModified or "19700101";
version =
(builtins.fromTOML (builtins.readFile ./yazi-fm/Cargo.toml)).package.version
(builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version
+ "pre${builtins.substring 0 8 date}_${rev}";
yazi-unwrapped = pkgs.callPackage ./nix/yazi-unwrapped.nix { inherit version rev date; };
yazi = pkgs.callPackage ./nix/yazi.nix { inherit yazi-unwrapped; };
in
{
packages = {
inherit yazi-unwrapped yazi;
default = yazi;
yazi-unwrapped = pkgs.callPackage ./nix/yazi-unwrapped.nix {
inherit
version
rev
date
rustPlatform
;
};
yazi = pkgs.callPackage ./nix/yazi.nix {
inherit (self.packages.${system}) yazi-unwrapped;
};
default = self.packages.${system}.yazi;
};
formatter = pkgs.nixfmt-rfc-style;
devShells = {
default = pkgs.callPackage ./nix/shell.nix {
inherit toolchain;
inherit (self.packages.${system}) yazi yazi-unwrapped;
};
};
devShells.default = import ./nix/shell.nix { inherit pkgs inputs; };
formatter = pkgs.nixfmt-tree;
}
)
// {
overlays = rec {
default = yazi;
yazi = final: _: { inherit (self.packages."${final.system}") yazi yazi-unwrapped; };
overlays = {
default = self.overlays.yazi;
yazi = _: prev: {
inherit (self.packages.${prev.stdenv.system}) yazi yazi-unwrapped;
};
};
};
}

View file

@ -1,28 +1,25 @@
{ pkgs, ... }:
{
mkShell,
yazi,
toolchain,
cspell,
yazi-unwrapped,
}:
pkgs.mkShell {
packages = with pkgs; [
rustToolchain
rust-analyzer
nodePackages.cspell
file
jq
poppler_utils
unar
ffmpegthumbnailer
fd
ripgrep
fzf
zoxide
mkShell {
packages = yazi.passthru.runtimePaths ++ [
(toolchain.override {
extensions = [
"rust-src"
"rustfmt"
"rust-analyzer"
"clippy"
];
})
cspell
];
buildInputs =
with pkgs;
lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Foundation ]);
inputsFrom = [ yazi-unwrapped ];
env = {
RUST_BACKTRACE = "1";
};
env.RUST_BACKTRACE = "1";
}

View file

@ -1,67 +1,88 @@
{
makeRustPlatform,
rustToolchain,
rustPlatform,
version ? "git",
rev,
date,
rev ? "unknown",
date ? "19700101",
lib,
installShellFiles,
stdenv,
darwin,
fetchFromGitHub,
rust-jemalloc-sys,
imagemagick,
}:
(makeRustPlatform {
cargo = rustToolchain;
rustc = rustToolchain;
}).buildRustPackage
{
pname = "yazi";
inherit version;
src = ../.;
cargoLock = {
lockFile = ../Cargo.lock;
outputHashes = {
"notify-6.1.1" = "sha256-5Ft2yvRPi2EaErcGBkF/3Xv6K7ijFGbdjmSqI4go/h4=";
};
};
env = {
YAZI_GEN_COMPLETIONS = true;
VERGEN_GIT_SHA = rev;
VERGEN_BUILD_DATE = builtins.concatStringsSep "-" (builtins.match "(.{4})(.{2})(.{2}).*" date);
};
nativeBuildInputs = [
installShellFiles
imagemagick
let
src = lib.fileset.toSource {
root = ../.;
fileset = lib.fileset.unions [
../assets
../Cargo.toml
../Cargo.lock
(lib.fileset.fromSource (lib.sources.sourceByRegex ../. [ "^yazi-.*" ]))
];
buildInputs = lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Foundation ]);
};
in
rustPlatform.buildRustPackage (finalAttrs: {
pname = "yazi";
inherit version src;
postInstall = ''
installShellCompletion --cmd yazi \
--bash ./yazi-boot/completions/yazi.bash \
--fish ./yazi-boot/completions/yazi.fish \
--zsh ./yazi-boot/completions/_yazi
cargoLock = {
lockFile = "${src}/Cargo.lock";
};
# Resize logo
for RES in 16 24 32 48 64 128 256; do
mkdir -p $out/share/icons/hicolor/"$RES"x"$RES"/apps
magick assets/logo.png -resize "$RES"x"$RES" $out/share/icons/hicolor/"$RES"x"$RES"/apps/yazi.png
done
env = {
YAZI_GEN_COMPLETIONS = true;
VERGEN_GIT_SHA = rev;
VERGEN_BUILD_DATE = builtins.concatStringsSep "-" (builtins.match "(.{4})(.{2})(.{2}).*" date);
};
mkdir -p $out/share/applications
install -m644 assets/yazi.desktop $out/share/applications/
'';
nativeBuildInputs = [
installShellFiles
imagemagick
];
meta = {
description = "Blazing fast terminal file manager written in Rust, based on async I/O";
homepage = "https://github.com/sxyazi/yazi";
license = lib.licenses.mit;
mainProgram = "yazi";
buildInputs = [
rust-jemalloc-sys
];
postInstall = ''
installShellCompletion --cmd yazi \
--bash ./yazi-boot/completions/yazi.bash \
--fish ./yazi-boot/completions/yazi.fish \
--zsh ./yazi-boot/completions/_yazi
installShellCompletion --cmd ya \
--bash ./yazi-cli/completions/ya.bash \
--fish ./yazi-cli/completions/ya.fish \
--zsh ./yazi-cli/completions/_ya
# Resize logo
for RES in 16 24 32 48 64 128 256; do
mkdir -p $out/share/icons/hicolor/"$RES"x"$RES"/apps
magick assets/logo.png -resize "$RES"x"$RES" $out/share/icons/hicolor/"$RES"x"$RES"/apps/yazi.png
done
installManPage ${finalAttrs.passthru.srcs.man_src}/yazi{.1,-config.5}
mkdir -p $out/share/applications
install -m644 assets/yazi.desktop $out/share/applications/
'';
passthru.srcs = {
man_src = fetchFromGitHub {
name = "manpages"; # needed to ensure name is unique
owner = "yazi-rs";
repo = "manpages";
rev = "8950e968f4a1ad0b83d5836ec54a070855068dbf";
hash = "sha256-kEVXejDg4ChFoMNBvKlwdFEyUuTcY2VuK9j0PdafKus=";
};
}
};
meta = {
description = "Blazing fast terminal file manager written in Rust, based on async I/O";
homepage = "https://github.com/sxyazi/yazi";
license = lib.licenses.mit;
mainProgram = "yazi";
};
})

View file

@ -1,52 +1,109 @@
{
lib,
formats,
runCommand,
makeWrapper,
runtimeDeps ? (ps: ps),
# deps
file,
yazi-unwrapped,
withFile ? true,
file,
withJq ? true,
# default optional deps
jq,
withPoppler ? true,
poppler_utils,
withUnar ? true,
unar,
withFfmpegthumbnailer ? true,
ffmpegthumbnailer,
withFd ? true,
poppler-utils,
_7zz,
ffmpeg,
fd,
withRipgrep ? true,
ripgrep,
withFzf ? true,
resvg,
fzf,
withZoxide ? true,
zoxide,
}:
imagemagick,
chafa,
settings ? { },
plugins ? { },
flavors ? { },
initLua ? null,
}:
let
inherit (lib) optional makeBinPath;
runtimePaths =
optional withFile file
++ optional withJq jq
++ optional withPoppler poppler_utils
++ optional withUnar unar
++ optional withFfmpegthumbnailer ffmpegthumbnailer
++ optional withFd fd
++ optional withRipgrep ripgrep
++ optional withFzf fzf
++ optional withZoxide zoxide;
inherit (lib)
concatStringsSep
concatMapStringsSep
optionalString
makeBinPath
mapAttrsToList
;
defaultDeps = [
jq
poppler-utils
_7zz
ffmpeg
fd
ripgrep
resvg
fzf
zoxide
imagemagick
chafa
];
runtimePaths = [ file ] ++ (runtimeDeps defaultDeps);
settingsFormat = formats.toml { };
files = [
"yazi"
"theme"
"keymap"
];
configHome =
if (settings == { } && initLua == null && plugins == { } && flavors == { }) then
null
else
runCommand "YAZI_CONFIG_HOME" { } ''
mkdir -p $out
${concatMapStringsSep "\n" (
name:
optionalString (settings ? ${name} && settings.${name} != { }) ''
ln -s ${settingsFormat.generate "${name}.toml" settings.${name}} $out/${name}.toml
''
) files}
mkdir $out/plugins
${optionalString (plugins != { }) ''
${concatStringsSep "\n" (
mapAttrsToList (name: value: "ln -s ${value} $out/plugins/${name}") plugins
)}
''}
mkdir $out/flavors
${optionalString (flavors != { }) ''
${concatStringsSep "\n" (
mapAttrsToList (name: value: "ln -s ${value} $out/flavors/${name}") flavors
)}
''}
${optionalString (initLua != null) "ln -s ${initLua} $out/init.lua"}
'';
in
runCommand yazi-unwrapped.name
{
inherit (yazi-unwrapped) pname version meta;
nativeBuildInputs = [ makeWrapper ];
passthru.runtimePaths = runtimePaths;
}
''
mkdir -p $out/bin
ln -s ${yazi-unwrapped}/share $out/share
ln -s ${yazi-unwrapped}/bin/ya $out/bin/ya
makeWrapper ${yazi-unwrapped}/bin/yazi $out/bin/yazi \
--prefix PATH : "${makeBinPath runtimePaths}"
--prefix PATH : "${makeBinPath runtimePaths}" \
${optionalString (configHome != null) "--set YAZI_CONFIG_HOME ${configHome}"}
''

View file

@ -1,6 +1,6 @@
color = "Never"
condense_wildcard_suffixes = true
edition = "2021"
edition = "2024"
enum_discrim_align_threshold = 99
fn_single_line = true
format_code_in_doc_comments = false
@ -10,7 +10,7 @@ format_macro_bodies = true
format_strings = false
hard_tabs = true
hex_literal_case = "Lower"
hide_parse_errors = true
show_parse_errors = false
imports_indent = "Visual"
imports_layout = "Horizontal"
imports_granularity = "Crate"
@ -27,5 +27,5 @@ unstable_features = true
use_field_init_shorthand = true
use_small_heuristics = "Max"
use_try_shorthand = true
version = "Two"
style_edition = "2024"
wrap_comments = true

View file

@ -1,31 +1,34 @@
#!/bin/bash
#!/usr/bin/env bash
set -euo pipefail
export ARTIFACT_NAME="yazi-$1"
export YAZI_GEN_COMPLETIONS=1
# Setup Rust toolchain
if [[ "$1" == *-musl ]]; then
rustup target add "$1"
else
rustup toolchain install stable --profile minimal --target "$1"
fi
# Build the target
git config --global --add safe.directory "*"
cargo build --release --locked --target "$1"
# Build for the target
cargo build -p yazi-cli --release --locked --target "$1"
cargo build -p yazi-fm --release --locked --target "$1"
# Copy the binaries to a known location
mkdir -p "target/release"
cp "target/$1/release/ya" "target/release/ya"
cp "target/$1/release/yazi" "target/release/yazi"
# Package deb
if [[ "$ARTIFACT_NAME" == *-linux-* ]] && { [[ "$ARTIFACT_NAME" == *-aarch64-* ]] || [[ "$ARTIFACT_NAME" == *-x86_64-* ]]; }; then
cargo install cargo-deb
cargo deb -p yazi-packing --no-build --target "$1" -o "$ARTIFACT_NAME.deb"
fi
# Create the artifact
mkdir -p "$ARTIFACT_NAME/completions"
cp "target/$1/release/ya" "$ARTIFACT_NAME"
cp "target/$1/release/yazi" "$ARTIFACT_NAME"
cp "target/release/ya" "$ARTIFACT_NAME"
cp "target/release/yazi" "$ARTIFACT_NAME"
cp yazi-cli/completions/* "$ARTIFACT_NAME/completions"
cp yazi-boot/completions/* "$ARTIFACT_NAME/completions"
cp README.md LICENSE "$ARTIFACT_NAME"
# Zip the artifact
if ! command -v zip &> /dev/null
then
sudo apt-get update && sudo apt-get install -yq zip
if ! command -v zip &> /dev/null; then
apt-get update && apt-get install -yq zip
fi
zip -r "$ARTIFACT_NAME.zip" "$ARTIFACT_NAME"

View file

@ -1,13 +1,20 @@
#!/bin/bash
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $SCRIPT_DIR/..
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR/.."
echo "Bumping version: $1"
TOML_FILES="$(git ls-files '*Cargo.toml')"
perl -pi -e "s/^version .*= .*\$/version = \"$1\"/" -- $TOML_FILES
perl -pi -e "s/^(yazi-[a-z]+)\\s*=\\s*{.*\$/\\1 = { path = \"..\/\\1\", version = \"$1\" }/" -- $TOML_FILES
perl -pi -e 's/^version .*= .*$/version = "'"$1"'"/' -- $TOML_FILES
perl -pi -e 's/^(yazi-[a-z]+)\s*=\s*{.*$/\1 = { path = "..\/\1", version = "'"$1"'" }/' -- $TOML_FILES
ESLINT_USE_FLAT_CONFIG=true eslint -c ~/.config/rules/eslint/eslint.config.cjs --fix -- $TOML_FILES
# Insert "## [v$1]" after "## [Unreleased]"
perl -0777 -pe "s/^(## \[Unreleased\]\s*)/\\1## [v$1]\n\n/m" -i CHANGELOG.md
# Determine previous version and append compare link
prev_ver=$(grep -oE '^\[v[0-9][^]]+\]' CHANGELOG.md | tail -n1 | tr -d '[]')
link="\[v$1\]: https://github.com/sxyazi/yazi/compare/$prev_ver...v$1"
perl -pi -e 's{(\['"$prev_ver"'\]:[^\n]+\n)}{$1'"$link"'\n}s' CHANGELOG.md
eslint -c ~/.config/rules/eslint/eslint.config.js --fix -- $TOML_FILES

View file

@ -1,5 +1,11 @@
local dark = require("icons-default")
local light = require("icons-light")
local dark = {
icons_by_filename = require("default.icons_by_filename"),
icons_by_file_extension = require("default.icons_by_file_extension"),
}
local light = {
icons_by_filename = require("light.icons_by_filename"),
icons_by_file_extension = require("light.icons_by_file_extension"),
}
function rearrange(by)
local map = {}
@ -21,16 +27,25 @@ function dump(map)
list[#list + 1] = { name = k, text = v.icon, fg_dark = v.fg_dark, fg_light = v.fg_light }
end
table.sort(list, function(a, b) return a.name:lower() < b.name:lower() end)
local dark, light = "", ""
for _, v in ipairs(list) do
-- stylua: ignore
print(string.format('\t{ name = "%s", text = "%s", fg_dark = "%s", fg_light = "%s" },', v.name, v.text, v.fg_dark, v.fg_light))
dark = dark .. string.format('\t{ name = "%s", text = "%s", fg = "%s" },\n', v.name, v.text, v.fg_dark)
light = light .. string.format('\t{ name = "%s", text = "%s", fg = "%s" },\n', v.name, v.text, v.fg_light)
end
return dark, light
end
print("files = [")
dump(rearrange("files"))
print("]")
function save(typ, files, exts)
local p = string.format("../../yazi-config/preset/theme-%s.toml", typ)
local s = io.open(p, "r"):read("*a")
s = s:gsub("files = %[\n(.-)\n%]", string.format("files = [\n%s]", files))
s = s:gsub("exts = %[\n(.-)\n%]", string.format("exts = [\n%s]", exts))
io.open(p, "w"):write(s)
end
print("exts = [")
dump(rearrange("exts"))
print("]")
local dark_files, light_files = dump(rearrange("files"))
local dark_exts, light_exts = dump(rearrange("exts"))
save("dark", dark_files, dark_exts)
save("light", light_files, light_exts)

View file

@ -1,11 +0,0 @@
cargo publish -p yazi-shared
cargo publish -p yazi-config
cargo publish -p yazi-proxy
cargo publish -p yazi-adapter
cargo publish -p yazi-boot
cargo publish -p yazi-dds
cargo publish -p yazi-scheduler
cargo publish -p yazi-plugin
cargo publish -p yazi-core
cargo publish -p yazi-fm
cargo publish -p yazi-cli

View file

@ -0,0 +1,269 @@
const LABEL_NAME = "needs info"
const RE_VERSION = /Yazi\s+Version\s*:\s\d+\.\d+\.\d+\s\(/gm
const RE_DEPENDENCIES = /Dependencies\s+[/a-z]+\s*:\s/gm
const RE_CHECKLIST = /#{3}\s+Checklist\s+(?:^-\s+\[x]\s+.+?(?:\n|\r\n|$)){2}/gm
const RE_PR_CHECKLIST = /#{2}\s+Checklist\s+(?:^-\s+\[x]\s+.+?(?:\n|\r\n|$)){2}/gm
function pullRequestBody(content) {
if (RE_PR_CHECKLIST.test(content)) {
return null
}
return "All required checklist items must be checked in the PR description."
}
function bugReportBody(creator, content, hash) {
if (RE_DEPENDENCIES.test(content) && RE_CHECKLIST.test(content) && new RegExp(` \\(${hash}[a-f0-9]? `).test(content)) {
return null
}
return `Hey @${creator}, thank you for opening the issue to help improve Yazi, appreciate it!
I noticed that you did not correctly follow the issue template. Please ensure that:
- The bug can still be reproduced on the [newest nightly build](https://yazi-rs.github.io/docs/installation/#binaries).
- The environment info (\`ya env\`) is updated for the newest nightly.
- The non-optional items in the checklist are checked.
Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
Our maintainers work on Yazi in their free time, this helps them work efficiently, understand your setup quickly, and find a more appropriate solution. Thanks for your understanding! 🙏
`
}
function featureRequestBody(creator, content) {
if (RE_VERSION.test(content) && RE_DEPENDENCIES.test(content) && RE_CHECKLIST.test(content)) {
return null
}
return `Hey @${creator}, thank you for opening the issue to help improve Yazi, appreciate it!
I noticed that you did not correctly follow the issue template. Please ensure that:
- The requested feature does not exist in the [newest nightly build](https://yazi-rs.github.io/docs/installation/#binaries).
- The environment info (\`ya env\`) is updated for the newest nightly.
- The non-optional items in the checklist are checked.
Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
Our maintainers work on Yazi in their free time, this helps them work efficiently, understand your setup quickly, and find a more appropriate solution. Thanks for your understanding! 🙏
`
}
function skipValidation(context) {
const login = context.payload.issue?.user?.login || context.payload.pull_request?.user?.login
const owner = context.payload.repository?.owner?.login || context.repo.owner
return !!login && login === owner
}
module.exports = async ({ github, context, core }) => {
async function nightlyHash() {
try {
const { data: tagRef } = await github.rest.git.getRef({ owner: "sxyazi", repo: "yazi", ref: "tags/nightly" })
return tagRef.object.sha.slice(0, 7)
} catch (e) {
if (e.status === 404) {
core.error("Nightly tag not found")
} else {
core.error(`Error fetching nightly version: ${e.message}`)
}
return null
}
}
async function hasLabel(id, label) {
try {
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
...context.repo,
issue_number: id,
})
return labels.some(l => l.name === label)
} catch (e) {
core.error(`Error checking labels: ${e.message}`)
return false
}
}
async function lastLabeledAt(id) {
try {
const { data: events } = await github.rest.issues.listEvents({
...context.repo,
issue_number: id,
per_page: 100,
})
const all = events.filter(v => v.event === "labeled" && v.label?.name === LABEL_NAME)
return all.at(-1)?.created_at
} catch (e) {
core.error(`Error getting label timestamp: ${e.message}`)
return null
}
}
async function removedLabelManually(id) {
try {
const { data: events } = await github.rest.issues.listEvents({
...context.repo,
issue_number: id,
per_page: 100,
})
const all = events.filter(v => v.event === "unlabeled" && v.label?.name === LABEL_NAME)
return all.length === 0 ? false : !all.at(-1).actor.login.endsWith("[bot]")
} catch (e) {
core.error(`Error checking label removal history: ${e.message}`)
return false
}
}
async function updateLabels(id, mark, body) {
try {
const marked = await hasLabel(id, LABEL_NAME)
if (!mark && marked) {
await github.rest.issues.removeLabel({
...context.repo,
issue_number: id,
name: LABEL_NAME,
})
await hideOldComments(id)
} else if (mark && !marked && !await removedLabelManually(id)) {
await github.rest.issues.addLabels({
...context.repo,
issue_number: id,
labels: [LABEL_NAME],
})
await hideOldComments(id)
await github.rest.issues.createComment({
...context.repo,
issue_number: id,
body,
})
}
} catch (e) {
core.error(`Error updating labels: ${e.message}`)
}
}
async function hideOldComments(id) {
try {
const comments = await github.paginate(github.rest.issues.listComments, {
...context.repo,
issue_number: id,
per_page: 100,
})
for (const c of comments) {
const byBot = c.user?.login?.endsWith("[bot]") || c.user?.type === "Bot"
const contains = c?.body?.includes("or closed after 2 days of inactivity")
if (!byBot || !contains || !c.node_id) continue
try {
await github.graphql(
`mutation($subjectId: ID!, $classifier: ReportedContentClassifiers!) {
minimizeComment(input: {subjectId: $subjectId, classifier: $classifier}) {
minimizedComment { isMinimized }
}
}`,
{ subjectId: c.node_id, classifier: "OUTDATED" },
)
} catch (e) {
core.error(`Error minimizing comment ${c.id}: ${e.message}`)
}
}
} catch (e) {
core.error(`Error listing comments: ${e.message}`)
}
}
async function closeOldIssues() {
try {
const { data: issues } = await github.rest.issues.listForRepo({
...context.repo,
state: "open",
labels: LABEL_NAME,
})
const now = new Date()
const twoDaysAgo = new Date(now - 2 * 24 * 60 * 60 * 1000)
for (const issue of issues) {
const markedAt = new Date(await lastLabeledAt(issue.number) || issue.created_at)
if (markedAt < twoDaysAgo) {
await github.rest.issues.update({
...context.repo,
issue_number: issue.number,
state: "closed",
state_reason: "not_planned",
})
await github.rest.issues.createComment({
...context.repo,
issue_number: issue.number,
body: `This issue has been automatically closed because it was marked as \`${LABEL_NAME}\` for more than 2 days without updates.
If the problem persists, please file a new issue and complete the issue template so we can capture all the details necessary to investigate further.`,
})
}
}
} catch (e) {
core.error(`Error checking old issues: ${e.message}`)
}
}
async function closeUnsupportedIssue(id) {
try {
await github.rest.issues.update({
...context.repo,
issue_number: id,
state: "closed",
state_reason: "not_planned",
})
await github.rest.issues.createComment({
...context.repo,
issue_number: id,
body: `Unsupported issue template.
Either the [Bug Report](https://github.com/sxyazi/yazi/issues/new?template=bug.yml) or [Feature Request](https://github.com/sxyazi/yazi/issues/new?template=feature.yml) template should be used.`,
})
} catch (e) {
core.error(`Error closing unsupported issue: ${e.message}`)
}
}
async function main() {
if (context.eventName === "schedule") {
await closeOldIssues()
return
}
if (skipValidation(context)) {
return
}
if (context.eventName === "issues") {
const id = context.payload.issue.number
const content = context.payload.issue.body || ""
const creator = context.payload.issue.user.login
const hash = await nightlyHash()
if (!hash) return
if (await hasLabel(id, "bug")) {
const body = bugReportBody(creator, content, hash)
await updateLabels(id, !!body, body)
} else if (await hasLabel(id, "feature")) {
const body = featureRequestBody(creator, content)
await updateLabels(id, !!body, body)
} else if (context.payload.action === "opened") {
await closeUnsupportedIssue(id)
}
} else if (context.eventName === "pull_request" || context.eventName === "pull_request_target") {
const content = context.payload.pull_request.body || ""
const body = pullRequestBody(content)
if (body) {
core.setFailed(body)
}
}
}
await main()
}

256
scripts/validate-form/package-lock.json generated Normal file
View file

@ -0,0 +1,256 @@
{
"name": "validate-form",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "validate-form",
"version": "1.0.0",
"dependencies": {
"@actions/core": "^3.0.1",
"@actions/github": "^9.1.1"
}
},
"node_modules/@actions/core": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz",
"integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==",
"license": "MIT",
"dependencies": {
"@actions/exec": "^3.0.0",
"@actions/http-client": "^4.0.0"
}
},
"node_modules/@actions/exec": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
"license": "MIT",
"dependencies": {
"@actions/io": "^3.0.2"
}
},
"node_modules/@actions/github": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.1.tgz",
"integrity": "sha512-tL5JbYOBZHc0ngEnCsaDcryUizIUIlQyIMwy1Wkx93H5HzbBJ7TbiPx2PnFjBwZW0Vh05JmfFZhecE6gglYegA==",
"license": "MIT",
"dependencies": {
"@actions/http-client": "^3.0.2",
"@octokit/core": "^7.0.6",
"@octokit/plugin-paginate-rest": "^14.0.0",
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
"@octokit/request": "^10.0.7",
"@octokit/request-error": "^7.1.0",
"undici": "^6.23.0"
}
},
"node_modules/@actions/github/node_modules/@actions/http-client": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.2.tgz",
"integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==",
"license": "MIT",
"dependencies": {
"tunnel": "^0.0.6",
"undici": "^6.23.0"
}
},
"node_modules/@actions/http-client": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz",
"integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==",
"license": "MIT",
"dependencies": {
"tunnel": "^0.0.6",
"undici": "^6.23.0"
}
},
"node_modules/@actions/io": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==",
"license": "MIT"
},
"node_modules/@octokit/auth-token": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz",
"integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==",
"license": "MIT",
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/core": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
"integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
"license": "MIT",
"dependencies": {
"@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^9.0.3",
"@octokit/request": "^10.0.6",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"before-after-hook": "^4.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/endpoint": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz",
"integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/graphql": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
"integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^10.0.6",
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
"integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz",
"integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/request": {
"version": "10.0.8",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.8.tgz",
"integrity": "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^11.0.3",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"fast-content-type-parse": "^3.0.0",
"json-with-bigint": "^3.5.3",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/request-error": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/types": {
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^27.0.0"
}
},
"node_modules/before-after-hook": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
"integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==",
"license": "Apache-2.0"
},
"node_modules/fast-content-type-parse": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
"integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT"
},
"node_modules/json-with-bigint": {
"version": "3.5.8",
"resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz",
"integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==",
"license": "MIT"
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"license": "MIT",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/undici": {
"version": "6.27.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz",
"integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==",
"license": "MIT",
"engines": {
"node": ">=18.17"
}
},
"node_modules/universal-user-agent": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
"license": "ISC"
}
}
}

View file

@ -0,0 +1,12 @@
{
"name": "validate-form",
"version": "1.0.0",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"private": true,
"dependencies": {
"@actions/core": "^3.0.1",
"@actions/github": "^9.1.1"
}
}

View file

@ -1,5 +1,5 @@
name: yazi
base: core22
base: core24
adopt-info: yazi
summary: Blazing fast terminal file manager written in Rust, based on async I/O.
description: |
@ -9,25 +9,157 @@ license: MIT
grade: stable
confinement: classic
architectures:
- amd64
# - arm64
platforms:
amd64:
arm64:
apps:
yazi:
command: yazi
environment:
PATH: $SNAP/bin:$PATH
PATH: $SNAP/bin:$SNAP/usr/bin:$PATH
ya:
command: ya
environment:
PATH: $SNAP/bin:$SNAP/usr/bin:$PATH
parts:
yazi:
plugin: rust
source: https://github.com/sxyazi/yazi.git
stage-snaps:
- jq
stage-packages:
- 7zip-standalone
- chafa
- fd-find
- ffmpeg
# - fzf
- libglu1-mesa
- libglut3.12
- poppler-utils
- ripgrep
- wl-clipboard
- xclip
- zoxide
override-build: |
craftctl default
craftctl set version=$(git describe --tags --abbrev=0)
cargo install fd-find --root $CRAFT_PART_INSTALL
cargo install ripgrep --root $CRAFT_PART_INSTALL
cargo install zoxide --root $CRAFT_PART_INSTALL
git clone --depth 1 https://github.com/junegunn/fzf.git fzf
fzf/install --bin && mv fzf/bin/fzf $CRAFT_PART_INSTALL/bin/
build-attributes:
- enable-patchelf
organize:
# Ubuntu's `fd` package installs a binary named `fdfind`. Rename it in the snap.
usr/bin/fdfind: usr/bin/fd
prime:
# Remove unused items bought in by dependency packages
- -usr/bin/fc-*
- -usr/bin/ffplay
- -usr/bin/pdfattach
- -usr/bin/pdfdetach
- -usr/bin/pdffonts
- -usr/bin/pdfimages
- -usr/bin/pdfinfo
- -usr/bin/pdfseparate
- -usr/bin/pdfsig
- -usr/bin/pdftocairo
- -usr/bin/pdftohtml
- -usr/bin/pdftops
- -usr/bin/pdftotext
- -usr/bin/pdfunite
# Remove unused libraries identified by snapcraft's linter
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_bad_*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_civil_time.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_cord*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_examine_stack.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_exponential_biased.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_failure_signal_handler.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_flags*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_hash*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_log_severity.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_periodic_sampler.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_random*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_raw_hash_set.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_scoped_set_env.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_statusor.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_status.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_strerror.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libabsl_str_format_internal.so.*
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libcaca++.so.0.99.20
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libcjson_utils.so.1.7.17
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libfftw3_omp.so.3.6.10
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libfftw3_threads.so.3.6.10
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libflite_cmu_grapheme_lang.so.2.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libflite_cmu_grapheme_lex.so.2.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libflite_cmu_indic_lang.so.2.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libflite_cmu_indic_lex.so.2.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libflite_cmu_time_awb.so.2.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libfreebl3.so
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libfreeblpriv3.so
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libGLX_mesa.so.0.0.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libhwy_contrib.so.1.0.7
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libhwy_test.so.1.0.7
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicui18n.so.74.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicuio.so.74.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicutest.so.74.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libicutu.so.74.2
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libjacknet.so.0.1.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libjackserver.so.0.1.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libnssckbi.so
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libnssdbm3.so
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libpulse-simple.so.0.1.1
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libsoftokn3.so
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libsphinxad.so.3.0.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libssl3.so
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libtheora.so.0.3.10
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libxcb-dri2.so.0.0.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libxcb-glx.so.0.0.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libxcb-present.so.0.0.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libxcb-sync.so.1.0.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libxshmfence.so.1.0.0
- -usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libzvbi-chains.so.0.0.0
# The Ubuntu `imagemagick` package does not ship a `magick` binary,
# which `yazi` looks for. Building the package oursleves yields the
# expected binary without much overhead, and works across platforms.
magick:
plugin: autotools
source: https://github.com/ImageMagick/ImageMagick.git
source-type: git
source-tag: 7.1.2-0
source-depth: 1
stage-packages:
- libgomp1
autotools-configure-parameters:
- --prefix=/usr
build-attributes:
- enable-patchelf
organize:
# `libgomp1` installs libgomp into the multiarch directory, but the
# `magick` binary's RPATH only searches `$ORIGIN/../lib` (i.e. usr/lib).
# Move it alongside the Magick libraries so the bundled binary can load
# it at runtime; otherwise magick fails with:
# "libgomp.so.1: cannot open shared object file: No such file or directory"
usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libgomp.so*: usr/lib/
prime:
- usr/bin/magick
- usr/lib/libgomp.so*
- usr/lib/libMagickCore-7.Q16HDRI.so*
- usr/lib/libMagickWand-7.Q16HDRI.so*
cleanup:
after: [yazi, magick]
plugin: nil
build-packages:
- patchelf
build-snaps:
- core24
override-prime: |
# Ubuntu's /usr/bin/7zz is a simple bash wrapper that just exec's
# /usr/lib/7zip/7zz - this just shortcuts that and places the actual
# executable at $SNAP/usr/bin/7zz.
mv $CRAFT_PRIME/usr/lib/7zip/7zz $CRAFT_PRIME/usr/bin/7zz
# Ensure we don't ship duplicates of files that exist in the core24
# snap.
cd /snap/core24/current
find . -type f,l -exec rm -rf "${CRAFT_PRIME}/{}" \;

View file

@ -1,3 +1,4 @@
syntax = "Lua54"
indent_width = 2
call_parentheses = "NoSingleTable"
collapse_simple_statement = "FunctionOnly"

58
yazi-actor/Cargo.toml Normal file
View file

@ -0,0 +1,58 @@
[package]
name = "yazi-actor"
description = "Yazi actor model"
version.workspace = true
edition.workspace = true
license.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
rust-version.workspace = true
[lints]
workspace = true
[features]
default = [ "vendored-lua" ]
vendored-lua = [ "mlua/vendored" ]
[dependencies]
yazi-binding = { path = "../yazi-binding", version = "26.5.6" }
yazi-boot = { path = "../yazi-boot", version = "26.5.6" }
yazi-config = { path = "../yazi-config", version = "26.5.6" }
yazi-core = { path = "../yazi-core", version = "26.5.6" }
yazi-dds = { path = "../yazi-dds", version = "26.5.6" }
yazi-emulator = { path = "../yazi-emulator", version = "26.5.6" }
yazi-fs = { path = "../yazi-fs", version = "26.5.6" }
yazi-macro = { path = "../yazi-macro", version = "26.5.6" }
yazi-parser = { path = "../yazi-parser", version = "26.5.6" }
yazi-plugin = { path = "../yazi-plugin", version = "26.5.6" }
yazi-proxy = { path = "../yazi-proxy", version = "26.5.6" }
yazi-runner = { path = "../yazi-runner", version = "26.5.6" }
yazi-scheduler = { path = "../yazi-scheduler", version = "26.5.6" }
yazi-shared = { path = "../yazi-shared", version = "26.5.6" }
yazi-shim = { path = "../yazi-shim", version = "26.5.6" }
yazi-term = { path = "../yazi-term", version = "26.5.6" }
yazi-tty = { path = "../yazi-tty", version = "26.5.9" }
yazi-tui = { path = "../yazi-tui", version = "26.5.6" }
yazi-vfs = { path = "../yazi-vfs", version = "26.5.6" }
yazi-watcher = { path = "../yazi-watcher", version = "26.5.6" }
yazi-widgets = { path = "../yazi-widgets", version = "26.5.6" }
# External dependencies
anyhow = { workspace = true }
either = { workspace = true }
futures = { workspace = true }
hashbrown = { workspace = true }
indexmap = { workspace = true }
inventory = { workspace = true }
mlua = { workspace = true }
paste = { workspace = true }
ratatui-core = { workspace = true }
scopeguard = { workspace = true }
tokio = { workspace = true }
tokio-stream = { workspace = true }
tracing = { workspace = true }
[target."cfg(unix)".dependencies]
libc = { workspace = true }

5
yazi-actor/README.md Normal file
View file

@ -0,0 +1,5 @@
# yazi-actor
This crate is part of [Yazi][source], and it is not supposed to be used outside, as there are no guarantees about the stability of its API.
[source]: https://github.com/sxyazi/yazi

15
yazi-actor/src/actor.rs Normal file
View file

@ -0,0 +1,15 @@
use anyhow::Result;
use yazi_parser::spark::SparkKind;
use yazi_shared::data::Data;
use crate::Ctx;
pub trait Actor {
type Form;
const NAME: &str;
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data>;
fn hook(_cx: &Ctx, _form: &Self::Form) -> Option<SparkKind> { None }
}

View file

@ -0,0 +1,42 @@
use anyhow::Result;
use mlua::IntoLua;
use tracing::error;
use yazi_actor::lives::Lives;
use yazi_binding::runtime_scope;
use yazi_dds::{LOCAL, Payload, REMOTE};
use yazi_macro::succ;
use yazi_plugin::LUA;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct AcceptPayload;
impl Actor for AcceptPayload {
type Form = Payload<'static>;
const NAME: &str = "accept_payload";
fn act(cx: &mut Ctx, payload: Payload) -> Result<Data> {
let kind = payload.body.kind();
let lock = if payload.receiver == 0 || payload.receiver != payload.sender {
REMOTE.read()
} else {
LOCAL.read()
};
let Some(handlers) = lock.get(kind).filter(|&m| !m.is_empty()).cloned() else { succ!() };
drop(lock);
let kind = kind.to_owned();
succ!(Lives::scope(cx.core, |_| {
let body = payload.body.into_lua(&LUA)?;
for (id, cb) in handlers {
if let Err(e) = runtime_scope!(LUA, &id, cb.call::<()>(body.clone())) {
error!("Failed to run `{kind}` event handler in your `{id}` plugin: {e}");
}
}
Ok(())
})?);
}
}

View file

@ -0,0 +1,32 @@
use anyhow::Result;
use yazi_actor::Ctx;
use yazi_boot::BOOT;
use yazi_core::mgr::CdSource;
use yazi_macro::{act, succ};
use yazi_parser::VoidForm;
use yazi_shared::{data::Data, strand::StrandLike, url::UrlLike};
use crate::Actor;
pub struct Bootstrap;
impl Actor for Bootstrap {
type Form = VoidForm;
const NAME: &str = "bootstrap";
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> {
cx.mgr.tabs.resize_with(BOOT.files.len(), Default::default);
for (i, file) in BOOT.files.iter().enumerate().rev() {
cx.tab = i;
if file.is_empty() {
act!(mgr:cd, cx, (BOOT.cwds[i].clone(), CdSource::Tab))?;
} else if let Ok(u) = BOOT.cwds[i].try_join(file) {
act!(mgr:reveal, cx, (u, CdSource::Tab))?;
}
}
succ!();
}
}

View file

@ -0,0 +1,24 @@
use anyhow::Result;
use yazi_core::notify::{MessageLevel, MessageOpt};
use yazi_macro::act;
use yazi_parser::app::DeprecateForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Deprecate;
impl Actor for Deprecate {
type Form = DeprecateForm;
const NAME: &str = "deprecate";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
act!(notify:push, cx, MessageOpt {
title: "Deprecated API".to_owned(),
content: form.content.into_owned(),
level: MessageLevel::Warn,
timeout: std::time::Duration::from_secs(20),
})
}
}

43
yazi-actor/src/app/dnd.rs Normal file
View file

@ -0,0 +1,43 @@
use anyhow::Result;
use mlua::{ObjectLike, Table};
use tracing::error;
use yazi_actor::lives::Lives;
use yazi_binding::runtime_scope;
use yazi_macro::succ;
use yazi_parser::app::DndForm;
use yazi_plugin::LUA;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Dnd;
impl Actor for Dnd {
type Form = DndForm;
const NAME: &str = "dnd";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let Some(size) = cx.term.as_ref().and_then(|t| t.size().ok()) else { succ!() };
let area = yazi_binding::elements::Rect::from(size);
let result = Lives::scope(cx.core, move |_| {
runtime_scope!(LUA, "root", {
let root = LUA.globals().raw_get::<Table>("Root")?.call_method::<Table>("new", area)?;
if form.event.is_drag() {
root.call_method::<()>("drag", form.event)?;
} else {
root.call_method::<()>("drop", form.event)?;
}
Ok(())
})
});
if let Err(ref e) = result {
error!("{e}");
}
succ!(result?);
}
}

View file

@ -0,0 +1,17 @@
use anyhow::Result;
use yazi_actor::Ctx;
use yazi_macro::act;
use yazi_parser::VoidForm;
use yazi_shared::data::Data;
use crate::Actor;
pub struct Focus;
impl Actor for Focus {
type Form = VoidForm;
const NAME: &str = "focus";
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> { act!(mgr:refresh, cx) }
}

24
yazi-actor/src/app/lua.rs Normal file
View file

@ -0,0 +1,24 @@
use anyhow::Result;
use yazi_binding::runtime_scope;
use yazi_macro::succ;
use yazi_parser::app::LuaForm;
use yazi_plugin::LUA;
use yazi_shared::data::{Data, Sendable};
use crate::{Actor, Ctx, lives::Lives};
pub struct Lua;
impl Actor for Lua {
type Form = LuaForm;
const NAME: &str = "lua";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let chunk = LUA.load(&*form.code).set_name("anonymous");
let result = Lives::scope(cx.core, |_| {
runtime_scope!(LUA, "inline", Sendable::value_to_data(&LUA, chunk.eval()?))
});
succ!(result?);
}
}

19
yazi-actor/src/app/mod.rs Normal file
View file

@ -0,0 +1,19 @@
yazi_macro::mod_flat!(
accept_payload
bootstrap
deprecate
dnd
focus
lua
mouse
plugin
plugin_do
quit
reflow
resize
resume
stop
theme
title
update_progress
);

View file

@ -0,0 +1,52 @@
use anyhow::Result;
use mlua::{ObjectLike, Table};
use tracing::error;
use yazi_actor::lives::Lives;
use yazi_binding::runtime_scope;
use yazi_macro::succ;
use yazi_parser::app::MouseForm;
use yazi_plugin::LUA;
use yazi_shared::data::Data;
use yazi_term::event::MouseEventKind;
use crate::{Actor, Ctx};
pub struct Mouse;
impl Actor for Mouse {
type Form = MouseForm;
const NAME: &str = "mouse";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let Some(size) = cx.term.as_ref().and_then(|t| t.size().ok()) else { succ!() };
let area = yazi_binding::elements::Rect::from(size);
let result = Lives::scope(cx.core, move |_| {
runtime_scope!(LUA, "root", {
let root = LUA.globals().raw_get::<Table>("Root")?.call_method::<Table>("new", area)?;
match form.event.kind {
MouseEventKind::Down(_) => root.call_method("click", (form.event, false))?,
MouseEventKind::Up(_) => root.call_method("click", (form.event, true))?,
MouseEventKind::ScrollDown => root.call_method("scroll", (form.event, 1))?,
MouseEventKind::ScrollUp => root.call_method("scroll", (form.event, -1))?,
MouseEventKind::ScrollRight => root.call_method("touch", (form.event, 1))?,
MouseEventKind::ScrollLeft => root.call_method("touch", (form.event, -1))?,
MouseEventKind::Moved => root.call_method("move", form.event)?,
MouseEventKind::Drag(_) => root.call_method("drag", form.event)?,
}
Ok(())
})
});
if let Err(ref e) = result {
error!("{e}");
}
succ!(result?);
}
}

View file

@ -0,0 +1,40 @@
use anyhow::Result;
use yazi_core::app::PluginMode;
use yazi_macro::{act, succ};
use yazi_parser::app::PluginForm;
use yazi_proxy::AppProxy;
use yazi_runner::loader::LOADER;
use yazi_scheduler::NotifyProxy;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Plugin;
impl Actor for Plugin {
type Form = PluginForm;
const NAME: &str = "plugin";
fn act(cx: &mut Ctx, Self::Form { mut opt }: Self::Form) -> Result<Data> {
let mut hits = false;
if let Some(chunk) = LOADER.read().get(&*opt.id) {
hits = true;
opt.mode = opt.mode.auto_then(chunk.sync_entry);
}
if opt.mode == PluginMode::Async {
succ!(cx.core.tasks.scheduler.plugin_entry(opt.into()));
} else if opt.mode == PluginMode::Sync && hits {
return act!(app:plugin_do, cx, opt);
}
tokio::spawn(async move {
match LOADER.ensure(&opt.id, |_| ()).await {
Ok(()) => AppProxy::plugin_do(opt),
Err(e) => NotifyProxy::push_error("Plugin load failed", e.to_string()),
}
});
succ!();
}
}

View file

@ -0,0 +1,58 @@
use anyhow::Result;
use mlua::ObjectLike;
use scopeguard::defer;
use tracing::{error, warn};
use yazi_binding::runtime_mut;
use yazi_core::app::PluginMode;
use yazi_macro::succ;
use yazi_parser::app::PluginForm;
use yazi_plugin::LUA;
use yazi_runner::{entry::EntryJob, loader::{LOADER, Loader}};
use yazi_scheduler::NotifyProxy;
use yazi_shared::data::Data;
use crate::{Actor, Ctx, lives::Lives};
pub struct PluginDo;
impl Actor for PluginDo {
type Form = PluginForm;
const NAME: &str = "plugin_do";
fn act(cx: &mut Ctx, Self::Form { opt }: Self::Form) -> Result<Data> {
let loader = LOADER.read();
let Some(chunk) = loader.get(&*opt.id) else {
succ!(warn!("plugin `{}` not found", opt.id));
};
if let Err(e) = Loader::compatible_or_error(&opt.id, chunk) {
succ!(NotifyProxy::push_error("Incompatible plugin", e.to_string()));
}
if opt.mode.auto_then(chunk.sync_entry) != PluginMode::Sync {
succ!(cx.core.tasks.scheduler.plugin_entry(opt.into()));
}
let blocking = runtime_mut!(LUA)?.critical_push(&opt.id, true);
defer! { _ = runtime_mut!(LUA).map(|mut r| r.critical_pop(blocking)) }
let plugin = match LOADER.load_chunk(&LUA, &opt.id, chunk) {
Ok(t) => t,
Err(e) => succ!(warn!("{e}")),
};
drop(loader);
let result = Lives::scope(cx.core, |_| {
if let Some(cb) = opt.callback {
cb(&LUA, plugin)
} else {
plugin.call_method("entry", EntryJob { args: opt.args, ..Default::default() })
}
});
if let Err(ref e) = result {
error!("Sync plugin `{}` failed: {e}", opt.id);
}
succ!(result?);
}
}

View file

@ -0,0 +1,50 @@
use std::process;
use anyhow::Result;
use yazi_boot::ARGS;
use yazi_fs::engine::{Engine, local::Local};
use yazi_parser::app::QuitForm;
use yazi_shared::{data::Data, strand::{StrandBuf, StrandLike, ToStrand}};
use yazi_tui::Raterm;
use crate::{Actor, Ctx};
pub struct Quit;
impl Actor for Quit {
type Form = QuitForm;
const NAME: &str = "quit";
fn act(cx: &mut Ctx, Self::Form { opt }: Self::Form) -> Result<Data> {
cx.tasks.shutdown();
cx.mgr.shutdown();
futures::executor::block_on(async {
_ = futures::join!(
yazi_dds::shutdown(),
yazi_dds::STATE.drain(),
Self::cwd_to_file(cx, opt.no_cwd_file),
Self::selected_to_file(opt.selected)
);
});
Raterm::stop();
process::exit(opt.code);
}
}
impl Quit {
async fn cwd_to_file(cx: &Ctx<'_>, no: bool) {
if let Some(p) = ARGS.cwd_file.as_ref().filter(|_| !no) {
let cwd = cx.mgr.cwd().to_strand();
Local::regular(p).write(cwd.encoded_bytes()).await.ok();
}
}
async fn selected_to_file(selected: Option<StrandBuf>) {
if let (Some(s), Some(p)) = (selected, &ARGS.chooser_file) {
Local::regular(p).write(s.encoded_bytes()).await.ok();
}
}
}

View file

@ -0,0 +1,54 @@
use anyhow::Result;
use mlua::{LuaString, Value};
use ratatui_core::layout::Position;
use tracing::error;
use yazi_actor::lives::Lives;
use yazi_config::LAYOUT;
use yazi_macro::{render, succ};
use yazi_parser::app::ReflowForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Reflow;
impl Actor for Reflow {
type Form = ReflowForm;
const NAME: &str = "reflow";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let Some(size) = cx.term.as_ref().and_then(|t| t.size().ok()) else { succ!() };
let mut layout = LAYOUT.get();
let result = Lives::scope(cx.core, |_| {
let comps = (form.reflow)((Position::ORIGIN, size).into())?;
for v in comps.sequence_values::<Value>() {
let Value::Table(t) = v? else {
error!("`reflow()` must return a table of components");
continue;
};
let id: LuaString = t.get("_id")?;
match &*id.as_bytes() {
b"current" => layout.current = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
b"preview" => layout.preview = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
b"progress" => layout.progress = *t.raw_get::<yazi_binding::elements::Rect>("_area")?,
_ => {}
}
}
Ok(())
});
if layout != LAYOUT.get() {
LAYOUT.set(layout);
render!();
}
if let Err(ref e) = result {
error!("Failed to `reflow()` the `Root` component:\n{e}");
}
succ!();
}
}

View file

@ -0,0 +1,25 @@
use anyhow::Result;
use yazi_actor::Ctx;
use yazi_macro::act;
use yazi_parser::app::ReflowForm;
use yazi_shared::data::Data;
use crate::Actor;
pub struct Resize;
impl Actor for Resize {
type Form = ReflowForm;
const NAME: &str = "resize";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
act!(app:reflow, cx, form)?;
cx.current_mut().arrow(0);
cx.parent_mut().map(|f| f.arrow(0));
cx.current_mut().sync_page(true);
act!(mgr:peek, cx)
}
}

View file

@ -0,0 +1,29 @@
use anyhow::Result;
use yazi_macro::{act, render, succ};
use yazi_parser::app::ReflowForm;
use yazi_shared::data::Data;
use yazi_tui::Raterm;
use crate::{Actor, Ctx};
pub struct Resume;
impl Actor for Resume {
type Form = ReflowForm;
const NAME: &str = "resume";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
cx.active_mut().preview.reset();
drop(cx.term.take());
*cx.term = Some(Raterm::start()?);
// While the app resumes, it's possible that the terminal size has changed.
// We need to trigger a resize, and render the UI based on the resized area.
act!(app:resize, cx, form.reflow)?;
act!(app:title, cx).ok();
succ!(render!());
}
}

View file

@ -0,0 +1,22 @@
use anyhow::Result;
use yazi_macro::succ;
use yazi_parser::VoidForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Stop;
impl Actor for Stop {
type Form = VoidForm;
const NAME: &str = "stop";
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> {
cx.active_mut().preview.reset_image();
*cx.term = None;
succ!();
}
}

View file

@ -0,0 +1,25 @@
use anyhow::Result;
use yazi_actor::Ctx;
use yazi_config::{THEME, build_flavor};
use yazi_emulator::EMULATOR;
use yazi_macro::{render, succ};
use yazi_parser::VoidForm;
use yazi_shared::data::Data;
use yazi_shim::serde::Overlay;
use crate::Actor;
pub struct Theme;
impl Actor for Theme {
type Form = VoidForm;
const NAME: &str = "theme";
fn act(_cx: &mut Ctx, _: Self::Form) -> Result<Data> {
THEME.overlay(build_flavor(EMULATOR.light, true)?);
yazi_plugin::theme::reset()?;
succ!(render!());
}
}

View file

@ -0,0 +1,32 @@
use anyhow::Result;
use yazi_actor::Ctx;
use yazi_macro::{succ, writef};
use yazi_parser::{app::TitleForm, spark::SparkKind};
use yazi_shared::{Source, data::Data};
use yazi_tty::{TTY, sequence::SetTitle};
use yazi_tui::RatermState;
use crate::Actor;
pub struct Title;
impl Actor for Title {
type Form = TitleForm;
const NAME: &str = "title";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let s = form.value.unwrap_or_else(|| format!("Yazi: {}", cx.tab().name()).into());
writef!(TTY.writer(), "{}", SetTitle(&s))?;
yazi_tui::STATE.set(RatermState { title: !s.is_empty(), ..yazi_tui::STATE.get() });
succ!()
}
fn hook(cx: &Ctx, _form: &Self::Form) -> Option<SparkKind> {
match cx.source() {
Source::Ind => Some(SparkKind::IndAppTitle),
_ => None,
}
}
}

View file

@ -0,0 +1,40 @@
use anyhow::Result;
use yazi_actor::Ctx;
use yazi_macro::{act, render, render_partial, succ};
use yazi_parser::app::UpdateProgressForm;
use yazi_shared::data::Data;
use crate::Actor;
pub struct UpdateProgress;
impl Actor for UpdateProgress {
type Form = UpdateProgressForm;
const NAME: &str = "update_progress";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
// Update the progress of all tasks.
let tasks = &mut cx.tasks;
let progressed = tasks.summary != form.summary;
tasks.summary = form.summary;
// If the task manager is visible, update the snaps with a full render.
if tasks.visible {
let new = tasks.paginate();
if tasks.snaps != new {
tasks.snaps = new;
act!(tasks:arrow, cx)?;
succ!(render!());
}
}
if !progressed {
succ!()
} else if tasks.summary.total == 0 {
succ!(render!())
} else {
succ!(render_partial!())
}
}
}

View file

@ -0,0 +1,19 @@
use anyhow::Result;
use yazi_macro::{render, succ};
use yazi_parser::ArrowForm;
use yazi_shared::data::Data;
use yazi_widgets::Scrollable;
use crate::{Actor, Ctx};
pub struct Arrow;
impl Actor for Arrow {
type Form = ArrowForm;
const NAME: &str = "arrow";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
succ!(render!(cx.cmp.scroll(form.step)));
}
}

View file

@ -0,0 +1,47 @@
use std::mem;
use anyhow::Result;
use yazi_macro::{act, render, succ};
use yazi_parser::cmp::CloseForm;
use yazi_shared::data::Data;
use yazi_widgets::input::parser::CompleteOpt;
use crate::{Actor, Ctx};
pub struct Close;
impl Actor for Close {
type Form = CloseForm;
const NAME: &str = "close";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
if form.submit && cx.cmp.visible {
Self::flush_last_input(cx)?;
}
let cmp = &mut cx.cmp;
if let Some(item) = cmp.selected().filter(|_| form.submit).cloned() {
return act!(input:complete, cx, CompleteOpt { name: item.name, is_dir: item.is_dir, ticket: cmp.ticket });
}
cmp.caches.clear();
cmp.ticket = Default::default();
cmp.handle.take().map(|h| h.abort());
succ!(render!(mem::replace(&mut cmp.visible, false)));
}
}
impl Close {
fn flush_last_input(cx: &mut Ctx) -> Result<Data> {
let Some(guard) = cx.input.lock() else { succ!() };
if cx.cmp.ticket == guard.ticket.current() {
succ!();
}
let before = guard.partition().0.to_owned();
drop(guard);
act!(cmp:trigger, cx, before)
}
}

View file

@ -0,0 +1 @@
yazi_macro::mod_flat!(arrow close show trigger);

View file

@ -0,0 +1,76 @@
use std::{mem, ops::ControlFlow};
use anyhow::Result;
use yazi_core::cmp::CmpItem;
use yazi_macro::{render, succ};
use yazi_parser::cmp::ShowForm;
use yazi_shared::{data::Data, path::{DynPath, PathDyn}, strand::StrandLike};
use crate::{Actor, Ctx};
const LIMIT: usize = 30;
pub struct Show;
impl Actor for Show {
type Form = ShowForm;
const NAME: &str = "show";
fn act(cx: &mut Ctx, Self::Form { opt }: Self::Form) -> Result<Data> {
let cmp = &mut cx.cmp;
if cmp.ticket != opt.ticket {
succ!();
}
if !opt.cache.is_empty() {
cmp.caches.insert(opt.cache_name.clone(), opt.cache);
}
let Some(cache) = cmp.caches.get(&opt.cache_name) else {
succ!();
};
cmp.matches = Self::match_candidates(opt.word.dyn_path(), cache);
if cmp.matches.is_empty() {
succ!(render!(mem::replace(&mut cmp.visible, false)));
}
cmp.offset = 0;
cmp.cursor = 0;
cmp.visible = true;
succ!(render!());
}
}
impl Show {
fn match_candidates(word: PathDyn, cache: &[CmpItem]) -> Vec<CmpItem> {
let smart = !word.encoded_bytes().iter().any(|&b| b.is_ascii_uppercase());
let flow = cache.iter().try_fold((Vec::new(), Vec::new()), |(mut exact, mut fuzzy), item| {
let starts_with = if smart {
item.name.starts_with_ignore_ascii_case(word)
} else {
item.name.starts_with(word)
};
if starts_with {
exact.push(item);
if exact.len() >= LIMIT {
return ControlFlow::Break((exact, fuzzy));
}
} else if fuzzy.len() < LIMIT - exact.len() && item.name.contains(word) {
// Here we don't break the control flow, since we want more exact matching.
fuzzy.push(item)
}
ControlFlow::Continue((exact, fuzzy))
});
let (exact, fuzzy) = match flow {
ControlFlow::Continue(v) => v,
ControlFlow::Break(v) => v,
};
let it = fuzzy.into_iter().take(LIMIT - exact.len());
exact.into_iter().chain(it).cloned().collect()
}
}

View file

@ -0,0 +1,155 @@
use std::{io, mem};
use anyhow::Result;
use yazi_core::cmp::{CmpItem, CmpOpt};
use yazi_fs::{engine::{DirReader, FileHolder}, path::clean_url};
use yazi_macro::{act, render, succ};
use yazi_parser::cmp::TriggerForm;
use yazi_proxy::CmpProxy;
use yazi_shared::{AnyAsciiChar, BytePredictor, data::Data, natsort, path::{DynPath, PathBufDyn, PathLike}, spec::Spec, strand::{AsStrand, StrandLike}, url::{UrlBuf, UrlCow, UrlLike}};
use yazi_vfs::engine;
use crate::{Actor, Ctx};
pub struct Trigger;
impl Actor for Trigger {
type Form = TriggerForm;
const NAME: &str = "trigger";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
if form.ticket.is_some_and(|t| t != cx.cmp.ticket) {
succ!();
} else if form.ticket.is_none() {
cx.cmp.ticket = cx.input.lock().map(|g| g.ticket.current()).unwrap_or_default();
}
cx.cmp.handle.take().map(|h| h.abort());
let Some((parent, word)) = Self::split_url(&form.word) else {
return act!(cmp:close, cx, false);
};
let ticket = cx.cmp.ticket;
if cx.cmp.caches.contains_key(&parent) {
return act!(cmp:show, cx, CmpOpt { cache: vec![], cache_name: parent, word, ticket });
}
cx.cmp.handle = Some(tokio::spawn(async move {
let mut dir = engine::read_dir(&parent).await?;
let mut cache = vec![];
// "/" is both a directory separator and the root directory per se
// As there's no parent directory for the FS root, it is a special case
if parent.loc() == "/" {
cache.push(CmpItem { name: Default::default(), is_dir: true });
}
while let Ok(Some(ent)) = dir.next().await {
if let Ok(ft) = ent.file_type().await {
cache.push(CmpItem { name: ent.name().into_owned(), is_dir: ft.is_dir() });
}
}
if !cache.is_empty() {
cache
.sort_unstable_by(|a, b| natsort(a.name.encoded_bytes(), b.name.encoded_bytes(), true));
CmpProxy::show(CmpOpt { cache, cache_name: parent, word, ticket });
}
Ok::<_, io::Error>(())
}));
succ!(render!(mem::replace(&mut cx.cmp.visible, false)));
}
}
impl Trigger {
fn split_url(s: &str) -> Option<(UrlBuf, PathBufDyn)> {
let (spec, path) = Spec::parse(s.as_bytes()).ok()?;
if path.is_empty() && !AnyAsciiChar::SEP.predicate(s.bytes().last()?) {
return None; // We don't complete a `sftp://test`, but `sftp://test/`
}
// Spec
let spec = spec.zeroed();
if spec.kind.is_local() && path.as_strand() == "~" {
return None; // We don't complete a `~`, but `~/`
}
// Child
let child = path.rsplit_pred(AnyAsciiChar::SEP).map_or(path.dyn_path(), |(_, c)| c).to_owned();
// Parent
let url = UrlCow::try_from((spec.clone().zeroed(), path)).ok()?;
let abs = if let Some(u) = engine::try_absolute(&url) { u } else { url };
let parent = abs.loc().try_strip_suffix(&child).ok()?;
Some((clean_url(UrlCow::try_from((spec, parent)).ok()?), child))
}
}
#[cfg(test)]
mod tests {
use yazi_fs::CWD;
use yazi_shared::url::UrlLike;
use super::*;
fn compare(s: &str, parent: &str, child: &str) {
let (mut p, c) = Trigger::split_url(s).unwrap();
if let Ok(u) = p.try_strip_prefix(yazi_fs::CWD.load().as_ref()) {
p = UrlBuf::Regular(u.as_os().unwrap().into());
}
assert_eq!((p, c.to_str().unwrap()), (parent.parse().unwrap(), child));
}
#[cfg(unix)]
#[test]
fn test_split() {
yazi_shared::init_tests();
yazi_config::init_tests();
yazi_fs::init();
assert_eq!(Trigger::split_url(""), None);
assert_eq!(Trigger::split_url("sftp://vps"), None);
compare(" ", "", " ");
compare("/", "/", "");
compare("//", "/", "");
compare("///", "/", "");
compare("/foo", "/", "foo");
compare("//foo", "/", "foo");
compare("///foo", "/", "foo");
compare("/foo/", "/foo/", "");
compare("//foo/", "/foo/", "");
compare("/foo/bar", "/foo/", "bar");
compare("///foo/bar", "/foo/", "bar");
CWD.set(&"sftp://vps".parse::<UrlBuf>().unwrap(), || {});
compare("sftp://vps/a", "sftp://vps/.", "a");
compare("sftp://vps//a", "sftp://vps//", "a");
compare("test-scope://aws/a", "test-scope://aws/.", "a");
compare("test-scope://aws//a", "test-scope://aws//", "a");
}
#[cfg(windows)]
#[test]
fn test_split() {
yazi_shared::init_tests();
yazi_config::init_tests();
yazi_fs::init();
compare("foo", "", "foo");
compare(r"foo\", r"foo\", "");
compare(r"foo\bar", r"foo\", "bar");
compare(r"foo\bar\", r"foo\bar\", "");
compare(r"C:\", r"C:\", "");
compare(r"C:\foo", r"C:\", "foo");
compare(r"C:\foo\", r"C:\foo\", "");
compare(r"C:\foo\bar", r"C:\foo\", "bar");
}
}

View file

@ -0,0 +1,26 @@
use anyhow::Result;
use yazi_macro::{render, succ};
use yazi_parser::ArrowForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Arrow;
impl Actor for Arrow {
type Form = ArrowForm;
const NAME: &str = "arrow";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let confirm = &mut cx.core.confirm;
let area = cx.core.mgr.area(confirm.position);
let len = confirm.list.line_count(area.width);
let old = confirm.offset;
confirm.offset = form.step.add(confirm.offset, len, area.height as _, 0, 0);
succ!(render!(old != confirm.offset));
}
}

View file

@ -0,0 +1,20 @@
use anyhow::Result;
use yazi_macro::{render, succ};
use yazi_parser::confirm::CloseForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Close;
impl Actor for Close {
type Form = CloseForm;
const NAME: &str = "close";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
cx.confirm.token.complete(form.submit);
cx.confirm.visible = false;
succ!(render!());
}
}

View file

@ -0,0 +1 @@
yazi_macro::mod_flat!(arrow close show);

View file

@ -0,0 +1,31 @@
use anyhow::Result;
use yazi_macro::{act, render, succ};
use yazi_parser::confirm::ShowForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Show;
impl Actor for Show {
type Form = ShowForm;
const NAME: &str = "show";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
act!(confirm:close, cx)?;
let confirm = &mut cx.confirm;
confirm.title = form.cfg.title;
confirm.body = form.cfg.body;
confirm.list = form.cfg.list;
confirm.position = form.cfg.position;
confirm.offset = 0;
confirm.token = form.token;
confirm.visible = true;
succ!(render!());
}
}

123
yazi-actor/src/context.rs Normal file
View file

@ -0,0 +1,123 @@
use std::ops::{Deref, DerefMut};
use anyhow::{Result, anyhow};
use yazi_core::{Core, mgr::Tabs, tab::{Folder, Tab}};
use yazi_fs::file::File;
use yazi_shared::{Source, event::Action, id::Id, url::UrlBuf};
use yazi_tui::Raterm;
pub struct Ctx<'a> {
pub core: &'a mut Core,
pub term: &'a mut Option<Raterm>,
pub tab: usize,
pub level: usize,
pub source: Source,
#[cfg(debug_assertions)]
pub backtrace: Vec<&'static str>,
}
impl Deref for Ctx<'_> {
type Target = Core;
fn deref(&self) -> &Self::Target { self.core }
}
impl DerefMut for Ctx<'_> {
fn deref_mut(&mut self) -> &mut Self::Target { self.core }
}
impl<'a> Ctx<'a> {
pub fn new(action: &Action, core: &'a mut Core, term: &'a mut Option<Raterm>) -> Result<Self> {
let tab = if let Ok(id) = action.get::<Id>("tab") {
core
.mgr
.tabs
.iter()
.position(|t| t.id == id)
.ok_or_else(|| anyhow!("Tab with id {id} not found"))?
} else {
core.mgr.tabs.cursor
};
Ok(Self {
core,
term,
tab,
level: 0,
source: action.source,
#[cfg(debug_assertions)]
backtrace: vec![],
})
}
pub fn renew<'b>(cx: &'a mut Ctx<'b>) -> Self {
let tab = cx.core.mgr.tabs.cursor;
Self {
core: cx.core,
term: cx.term,
tab,
level: cx.level,
source: cx.source,
#[cfg(debug_assertions)]
backtrace: vec![],
}
}
pub fn active(core: &'a mut Core, term: &'a mut Option<Raterm>) -> Self {
let tab = core.mgr.tabs.cursor;
Self {
core,
term,
tab,
level: 0,
source: Source::Unknown,
#[cfg(debug_assertions)]
backtrace: vec![],
}
}
}
impl<'a> Ctx<'a> {
#[inline]
pub fn tabs(&self) -> &Tabs { &self.mgr.tabs }
#[inline]
pub fn tabs_mut(&mut self) -> &mut Tabs { &mut self.mgr.tabs }
#[inline]
pub fn tab(&self) -> &Tab { &self.tabs()[self.tab] }
#[inline]
pub fn tab_mut(&mut self) -> &mut Tab { &mut self.core.mgr.tabs[self.tab] }
#[inline]
pub fn cwd(&self) -> &UrlBuf { self.tab().cwd() }
#[inline]
pub fn parent(&self) -> Option<&Folder> { self.tab().parent.as_ref() }
#[inline]
pub fn parent_mut(&mut self) -> Option<&mut Folder> { self.tab_mut().parent.as_mut() }
#[inline]
pub fn current(&self) -> &Folder { &self.tab().current }
#[inline]
pub fn current_mut(&mut self) -> &mut Folder { &mut self.tab_mut().current }
#[inline]
pub fn hovered(&self) -> Option<&File> { self.tab().hovered() }
#[inline]
pub fn hovered_url(&self) -> Option<&UrlBuf> { self.tab().hovered_url() }
#[inline]
pub fn hovered_folder(&self) -> Option<&Folder> { self.tab().hovered_folder() }
#[inline]
pub fn hovered_folder_mut(&mut self) -> Option<&mut Folder> {
self.tab_mut().hovered_folder_mut()
}
pub fn source(&self) -> Source { if self.level != 1 { Source::Ind } else { self.source } }
}

View file

@ -0,0 +1 @@
yazi_macro::mod_flat!(preflight);

View file

@ -0,0 +1,37 @@
use anyhow::Result;
use mlua::{ErrorContext, ExternalError, IntoLua, Value};
use yazi_binding::runtime_scope;
use yazi_dds::LOCAL;
use yazi_parser::spark::{Spark, SparkKind};
use yazi_plugin::LUA;
use crate::{Ctx, lives::Lives};
pub struct Preflight;
impl Preflight {
pub fn act<'a>(cx: &mut Ctx, opt: (SparkKind, Spark<'a>)) -> Result<Spark<'a>> {
let kind = opt.0;
let Some(handlers) = LOCAL.read().get(kind.into()).filter(|&m| !m.is_empty()).cloned() else {
return Ok(opt.1);
};
Ok(Lives::scope(cx.core, |_| {
let mut body = opt.1.into_lua(&LUA)?;
for (id, cb) in handlers {
match runtime_scope!(LUA, &id, cb.call::<Value>(&body)) {
Ok(Value::Nil) => {
Err(format!("`{kind}` event cancelled by `{id}` plugin on preflight").into_lua_err())?
}
Ok(v) => body = v,
Err(e) => Err(
format!("Failed to run `{kind}` event handler in `{id}` plugin: {e}").into_lua_err(),
)?,
};
}
Spark::from_lua(&LUA, kind, body)
.with_context(|e| format!("Unexpected return type from `{kind}` event handlers: {e}"))
})?)
}
}

View file

@ -0,0 +1,19 @@
use anyhow::Result;
use yazi_macro::{render, succ};
use yazi_parser::ArrowForm;
use yazi_shared::data::Data;
use yazi_widgets::Scrollable;
use crate::{Actor, Ctx};
pub struct Arrow;
impl Actor for Arrow {
type Form = ArrowForm;
const NAME: &str = "arrow";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
succ!(render!(cx.help.scroll(form.step)));
}
}

View file

@ -0,0 +1,25 @@
use anyhow::Result;
use yazi_macro::{emit, render, succ};
use yazi_parser::help::CloseForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Close;
impl Actor for Close {
type Form = CloseForm;
const NAME: &str = "close";
fn act(cx: &mut Ctx, opt: Self::Form) -> Result<Data> {
let help = &mut cx.help;
if let Some(chord) = help.bindings.get(help.cursor).filter(|_| opt.submit) {
emit!(Seq(chord.to_seq(help.layer)));
}
help.visible = false;
succ!(render!());
}
}

View file

@ -0,0 +1,24 @@
use anyhow::Result;
use yazi_macro::{act, render, succ};
use yazi_parser::VoidForm;
use yazi_shared::data::Data;
use yazi_widgets::input::InputMode;
use crate::{Actor, Ctx};
pub struct Escape;
impl Actor for Escape {
type Form = VoidForm;
const NAME: &str = "escape";
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> {
if cx.help.input.mode() == InputMode::Normal {
return act!(help:close, cx);
}
act!(escape, cx.help.input)?;
succ!(render!());
}
}

View file

@ -0,0 +1 @@
yazi_macro::mod_flat!(arrow close escape toggle);

View file

@ -0,0 +1,39 @@
use anyhow::Result;
use ratatui_core::layout::Margin;
use yazi_config::popup::Help;
use yazi_macro::{render, succ};
use yazi_parser::help::ToggleForm;
use yazi_shared::data::Data;
use yazi_widgets::input::Input;
use crate::{Actor, Ctx};
pub struct Toggle;
impl Actor for Toggle {
type Form = ToggleForm;
const NAME: &str = "toggle";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let position = Help::position();
let area = cx.mgr.area(position);
let input_area = area.inner(Margin::new(1, 1));
let help = &mut cx.help;
help.visible = true;
help.layer = form.layer;
help.position = position;
help.height = area.height;
help.input = Input::default();
help.input.repos(input_area);
help.keyword.clear();
help.offset = 0;
help.cursor = 0;
help.filter_apply();
succ!(render!());
}
}

View file

@ -0,0 +1,47 @@
use anyhow::Result;
use yazi_core::input::InputMutGuard;
use yazi_macro::{act, render, succ};
use yazi_parser::{input::CloseForm, spark::SparkKind};
use yazi_shared::{Source, data::Data};
use yazi_widgets::input::InputEvent;
use crate::{Actor, Ctx};
pub struct Close;
impl Actor for Close {
type Form = CloseForm;
const NAME: &str = "close";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let Some(mut guard) = cx.input.lock_mut() else {
succ!();
};
guard.ticket.next();
if let Some(cb) = guard.cb.take() {
let value = guard.value().to_owned();
cb(if form.submit { InputEvent::Submit(value) } else { InputEvent::Cancel(value) });
}
if form.submit
&& let InputMutGuard::Main(input) = guard
{
input.histories.remember(&input.main.history.name, input.main.value());
}
cx.input.main.visible = false;
act!(cmp:close, cx)?;
succ!(render!());
}
fn hook(cx: &Ctx, _form: &Self::Form) -> Option<SparkKind> {
match cx.source() {
Source::Key => Some(SparkKind::KeyInputClose),
Source::Ind => Some(SparkKind::IndInputClose),
_ => None,
}
}
}

View file

@ -0,0 +1,26 @@
use anyhow::Result;
use yazi_macro::{act, succ};
use yazi_shared::data::Data;
use yazi_widgets::input::parser::CompleteOpt;
use crate::{Actor, Ctx};
pub struct Complete;
impl Actor for Complete {
type Form = CompleteOpt;
const NAME: &str = "complete";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let Some(mut guard) = cx.input.lock_mut() else {
succ!();
};
if guard.ticket.current() != form.ticket {
succ!();
}
act!(complete, guard, form)
}
}

View file

@ -0,0 +1,34 @@
use anyhow::Result;
use yazi_macro::{act, render, succ};
use yazi_parser::VoidForm;
use yazi_shared::data::Data;
use yazi_widgets::input::InputOp;
use crate::{Actor, Ctx};
pub struct Escape;
impl Actor for Escape {
type Form = VoidForm;
const NAME: &str = "escape";
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> {
use yazi_widgets::input::InputMode as M;
let Some(mut guard) = cx.input.lock_mut() else {
succ!();
};
let (mode, op) = (guard.snap().mode, guard.snap().op);
act!(escape, guard)?;
drop(guard);
match mode {
M::Normal if op == InputOp::None => act!(input:close, cx),
M::Insert => act!(cmp:close, cx),
M::Normal | M::Replace => Ok(().into()),
}?;
succ!(render!());
}
}

View file

@ -0,0 +1 @@
yazi_macro::mod_flat!(close complete escape recall remember show);

View file

@ -0,0 +1,32 @@
use anyhow::Result;
use yazi_core::input::InputMutGuard;
use yazi_macro::succ;
use yazi_parser::input::RecallForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Recall;
impl Actor for Recall {
type Form = RecallForm;
const NAME: &str = "recall";
fn act(cx: &mut Ctx, form: Self::Form) -> Result<Data> {
let Some(input) = cx.input.lock_mut() else {
succ!();
};
match input {
InputMutGuard::Main(input) => {
let entries = input.histories.get(&input.main.history.name);
input.main.recall(entries, form.step)
}
InputMutGuard::Alt(input, mut guard) => {
let entries = input.histories.get(&guard.history.name);
guard.recall(entries, form.step)
}
}
}
}

View file

@ -0,0 +1,33 @@
use anyhow::Result;
use yazi_core::input::InputMutGuard;
use yazi_macro::succ;
use yazi_parser::VoidForm;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Remember;
impl Actor for Remember {
type Form = VoidForm;
const NAME: &str = "remember";
fn act(cx: &mut Ctx, _: Self::Form) -> Result<Data> {
let Some(mut input) = cx.input.lock_mut() else {
succ!();
};
match &mut input {
InputMutGuard::Main(input) => {
input.histories.remember(&input.main.history.name, input.main.value());
}
InputMutGuard::Alt(input, guard) => {
input.histories.remember(&guard.history.name, guard.value());
}
}
input.history.take();
succ!();
}
}

View file

@ -0,0 +1,36 @@
use std::ops::DerefMut;
use anyhow::Result;
use yazi_config::{THEME, YAZI};
use yazi_macro::{act, render, succ};
use yazi_parser::input::ShowForm;
use yazi_shared::data::Data;
use yazi_shim::ratatui::Padable;
use crate::{Actor, Ctx};
pub struct Show;
impl Actor for Show {
type Form = ShowForm;
const NAME: &str = "show";
fn act(cx: &mut Ctx, Self::Form { mut opt }: Self::Form) -> Result<Data> {
act!(input:close, cx)?;
let area = cx.mgr.area(opt.position).padding(cx.input.padding());
let input = &mut cx.input;
input.main.name = opt.name.clone();
input.main.title = opt.title.clone();
input.main.position = opt.position;
input.main.visible = true;
opt.styles = (&THEME.input).into();
opt.blinking = YAZI.input.cursor_blink;
*input.main.deref_mut() = yazi_widgets::input::Input::new(opt)?;
input.main.repos(area);
succ!(render!());
}
}

7
yazi-actor/src/lib.rs Normal file
View file

@ -0,0 +1,7 @@
extern crate self as yazi_actor;
yazi_macro::mod_pub!(app cmp confirm core help input lives mgr notify pick spot tasks which);
yazi_macro::mod_flat!(actor context);
pub fn init() { lives::init(); }

View file

@ -0,0 +1,29 @@
use std::ops::Deref;
use mlua::{AnyUserData, UserData, UserDataMethods};
use super::{Lives, PtrCell};
pub(super) struct Behavior {
inner: PtrCell<yazi_scheduler::Behavior>,
}
impl Deref for Behavior {
type Target = yazi_scheduler::Behavior;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Behavior {
pub(super) fn make(inner: &yazi_scheduler::Behavior) -> mlua::Result<AnyUserData> {
let inner = PtrCell::from(inner);
Lives::scoped_userdata(Self { inner })
}
}
impl UserData for Behavior {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_method("reset", |_, me, ()| Ok(me.reset()));
}
}

View file

@ -0,0 +1,71 @@
use std::ops::Deref;
use mlua::{AnyUserData, IntoLua, LuaString, MetaMethod, UserData, UserDataMethods, UserDataRef, Value};
use paste::paste;
use super::{Lives, PtrCell};
pub(super) type CoreRef = UserDataRef<Core>;
pub(super) struct Core {
inner: PtrCell<yazi_core::Core>,
c_active: Option<Value>,
c_tabs: Option<Value>,
c_tasks: Option<Value>,
c_yanked: Option<Value>,
c_input: Option<Value>,
c_which: Option<Value>,
c_layer: Option<Value>,
}
impl Deref for Core {
type Target = yazi_core::Core;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Core {
pub(super) fn make(inner: &yazi_core::Core) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self {
inner: inner.into(),
c_active: None,
c_tabs: None,
c_tasks: None,
c_yanked: None,
c_input: None,
c_which: None,
c_layer: None,
})
}
}
impl UserData for Core {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method_mut(MetaMethod::Index, |lua, me, key: LuaString| {
macro_rules! reuse {
($key:ident, $value:expr) => {
match paste! { &me.[<c_ $key>] } {
Some(v) => v.clone(),
None => {
let v = $value?.into_lua(lua)?;
paste! { me.[<c_ $key>] = Some(v.clone()); };
v
}
}
};
}
Ok(match &*key.as_bytes() {
b"active" => reuse!(active, super::Tab::make(me.active())),
b"tabs" => reuse!(tabs, super::Tabs::make(&me.mgr.tabs)),
b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)),
b"yanked" => reuse!(yanked, super::Yanked::make(&me.mgr.yanked)),
b"input" => reuse!(input, super::Input::make(&me.input)),
b"which" => reuse!(which, super::Which::make(&me.which)),
b"layer" => reuse!(layer, Ok::<_, mlua::Error>(me.layer())),
_ => Value::Nil,
})
});
}
}

View file

@ -0,0 +1,47 @@
use std::ops::{Deref, Range};
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
use yazi_shim::mlua::UserDataFieldsExt;
use super::{File, Filter, Lives, PtrCell};
pub(super) struct Entries {
window: Range<usize>,
folder: PtrCell<yazi_core::tab::Folder>,
tab: PtrCell<yazi_core::tab::Tab>,
}
impl Deref for Entries {
type Target = yazi_fs::Entries;
fn deref(&self) -> &Self::Target { &self.folder.entries }
}
impl Entries {
pub(super) fn make(
window: Range<usize>,
folder: &yazi_core::tab::Folder,
tab: &yazi_core::tab::Tab,
) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self { window, folder: folder.into(), tab: tab.into() })
}
}
impl UserData for Entries {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_static_field("filter", |_, me| me.filter().map(Filter::make).transpose());
}
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.window.end - me.window.start));
methods.add_meta_method(MetaMethod::Index, |_, me, mut idx: usize| {
idx += me.window.start;
if idx > me.window.end || idx == 0 {
Ok(None)
} else {
Some(File::make(idx - 1, &me.folder, &me.tab)).transpose()
}
});
}
}

View file

@ -0,0 +1,157 @@
use std::{ops::Deref, ptr};
use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods};
use yazi_binding::{Range, style::Style};
use yazi_config::THEME;
use yazi_fs::file::FileInventory;
use yazi_shared::{path::DynPath, url::UrlLike};
use super::{FILE_CACHE, Lives};
use crate::lives::{CoreRef, PtrCell};
pub(super) struct File {
idx: usize,
folder: PtrCell<yazi_core::tab::Folder>,
tab: PtrCell<yazi_core::tab::Tab>,
}
impl Deref for File {
type Target = yazi_fs::file::File;
fn deref(&self) -> &Self::Target { &self.folder.entries[self.idx] }
}
impl AsRef<yazi_fs::file::File> for File {
fn as_ref(&self) -> &yazi_fs::file::File { self }
}
impl File {
pub(super) fn make(
idx: usize,
folder: &yazi_core::tab::Folder,
tab: &yazi_core::tab::Tab,
) -> mlua::Result<AnyUserData> {
use hashbrown::hash_map::Entry;
Ok(
match unsafe { (*FILE_CACHE.get()).assume_init_mut() }.entry(PtrCell(&folder.entries[idx])) {
Entry::Occupied(oe) => oe.into_mut().clone(),
Entry::Vacant(ve) => {
let ud = Lives::scoped_userdata(Self { idx, folder: folder.into(), tab: tab.into() })?;
ve.insert(ud.clone());
ud
}
},
)
}
#[inline]
fn is_hovered(&self) -> bool { self.idx == self.folder.cursor }
}
impl UserData for File {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
yazi_binding::impl_file_fields!(fields);
fields.add_field_method_get("idx", |_, me| Ok(me.idx + 1));
fields.add_field_method_get("is_hovered", |_, me| Ok(me.is_hovered()));
fields.add_field_method_get("in_current", |_, me| Ok(ptr::eq(&*me.folder, &me.tab.current)));
fields.add_field_method_get("in_preview", |_, me| {
Ok(me.idx == me.folder.cursor && me.tab.hovered().is_some_and(|f| f.url == me.folder.url))
});
}
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
yazi_binding::impl_file_methods!(methods);
methods.add_method("icon", |lua, me, ()| {
yazi_binding::deprecate!(
lua,
"{}: `File:icon()` is deprecated, use `th.icon:match(file)` instead"
);
// TODO: use a cache
Ok(yazi_config::THEME.icon.matches(me, me.is_hovered()))
});
methods.add_method("size", |_, me, ()| {
Ok(if me.is_dir() {
me.folder.entries.sizes.get(&me.entry_key()).copied()
} else {
Some(me.len)
})
});
methods.add_method("mime", |lua, me, ()| {
let core: CoreRef = lua.named_registry_value("cx")?;
core.mgr.mimetype.get(&me.url).map(|s| lua.create_string(s)).transpose()
});
methods.add_method("prefix", |lua, me, ()| {
if !me.url.has_trail() {
return Ok(None);
}
let mut comp = me.url.try_strip_prefix(me.url.trail()).unwrap_or(me.url.loc()).components();
comp.next_back();
Some(lua.create_string(comp.dyn_path().encoded_bytes())).transpose()
});
methods.add_method("style", |lua, me, ()| {
let core: CoreRef = lua.named_registry_value("cx")?;
let mime = core.mgr.mimetype.get(&me.url).unwrap_or_default();
Ok(THEME.filetype.match_style(me, mime).map(Style::from))
});
methods.add_method("is_yanked", |lua, me, ()| {
let core: CoreRef = lua.named_registry_value("cx")?;
Ok(if !core.mgr.yanked.contains(&me.url) {
0u8
} else if core.mgr.yanked.cut {
2u8
} else {
1u8
})
});
methods.add_method("is_marked", |_, me, ()| {
let Some(visual) = me.tab.mode.visual() else {
return Ok(0u8);
};
if !visual.contains(me.idx, me.tab.current.cursor, me.folder.entries.len()) {
return Ok(0u8);
}
if me.folder.url != me.tab.current.url {
return Ok(0u8);
}
Ok(if me.tab.mode.is_select() { 1u8 } else { 2u8 })
});
methods.add_method("is_selected", |_, me, ()| Ok(me.tab.selected.contains(&me.url)));
methods.add_method("found", |lua, me, ()| {
let core: CoreRef = lua.named_registry_value("cx")?;
let Some(finder) = &core.active().finder else {
return Ok(None);
};
let Some(idx) = finder.matched_idx(&me.folder, me.entry_key()) else {
return Ok(None);
};
lua.create_sequence_from([idx.into_lua(lua)?, finder.matched.len().into_lua(lua)?]).map(Some)
});
methods.add_method("highlights", |lua, me, ()| {
let core: CoreRef = lua.named_registry_value("cx")?;
let Some(finder) = &core.active().finder else {
return Ok(None);
};
if me.folder.url != me.tab.current.url {
return Ok(None);
}
let Some(Some(h)) = me.url.name().map(|s| finder.filter.highlighted(s)) else {
return Ok(None);
};
lua.create_sequence_from(h.into_iter().map(Range::from)).map(Some)
});
}
}
inventory::submit! {
FileInventory {
register: |_| {},
borrow: |ud, f| f(&*ud.borrow::<File>()?),
}
}

View file

@ -0,0 +1,27 @@
use std::ops::Deref;
use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods};
use super::{Lives, PtrCell};
pub(super) struct Filter {
inner: PtrCell<yazi_fs::Filter>,
}
impl Deref for Filter {
type Target = yazi_fs::Filter;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Filter {
pub(super) fn make(inner: &yazi_fs::Filter) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self { inner: inner.into() })
}
}
impl UserData for Filter {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string()));
}
}

View file

@ -0,0 +1,27 @@
use std::ops::Deref;
use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods};
use super::{Lives, PtrCell};
pub(super) struct Finder {
inner: PtrCell<yazi_core::tab::Finder>,
}
impl Deref for Finder {
type Target = yazi_core::tab::Finder;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Finder {
pub(super) fn make(inner: &yazi_core::tab::Finder) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self { inner: inner.into() })
}
}
impl UserData for Finder {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.filter.to_string()));
}
}

View file

@ -0,0 +1,52 @@
use std::ops::{Deref, Range};
use mlua::{AnyUserData, UserData, UserDataFields};
use yazi_config::LAYOUT;
use yazi_shim::mlua::UserDataFieldsExt;
use super::{Entries, File, Lives, PtrCell};
pub(super) struct Folder {
window: Range<usize>,
inner: PtrCell<yazi_core::tab::Folder>,
tab: PtrCell<yazi_core::tab::Tab>,
}
impl Deref for Folder {
type Target = yazi_core::tab::Folder;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Folder {
pub(super) fn make(
window: Option<Range<usize>>,
inner: &yazi_core::tab::Folder,
tab: &yazi_core::tab::Tab,
) -> mlua::Result<AnyUserData> {
let window = match window {
Some(w) => w,
None => {
let limit = LAYOUT.get().preview.height as usize;
inner.offset..inner.entries.len().min(inner.offset + limit)
}
};
Lives::scoped_userdata(Self { window, inner: inner.into(), tab: tab.into() })
}
}
impl UserData for Folder {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_cached_field("cwd", |_, me| Ok(me.url.clone()));
fields.add_static_field("files", |_, me| Entries::make(0..me.entries.len(), me, &me.tab));
fields.add_cached_field("stage", |_, me| Ok(me.stage.clone()));
fields.add_static_field("window", |_, me| Entries::make(me.window.clone(), me, &me.tab));
fields.add_field_method_get("offset", |_, me| Ok(me.offset));
fields.add_field_method_get("cursor", |_, me| Ok(me.cursor));
fields.add_static_field("hovered", |_, me| {
me.hovered().map(|_| File::make(me.cursor, me, &me.tab)).transpose()
});
}
}

View file

@ -0,0 +1,29 @@
use std::ops::Deref;
use mlua::{AnyUserData, UserData, UserDataFields};
use yazi_shim::mlua::UserDataFieldsExt;
use super::{Lives, PtrCell};
use crate::lives::InputAlt;
pub(super) struct Input {
inner: PtrCell<yazi_core::input::Input>,
}
impl Deref for Input {
type Target = yazi_core::input::Input;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Input {
pub(super) fn make(inner: &yazi_core::input::Input) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self { inner: inner.into() })
}
}
impl UserData for Input {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_cached_field("alt", |_, me| me.alt.as_ref().map(InputAlt::make).transpose());
}
}

View file

@ -0,0 +1,26 @@
use std::ops::Deref;
use mlua::{AnyUserData, UserData, UserDataFields};
use yazi_shim::mlua::UserDataFieldsExt;
use super::{Lives, PtrCell};
pub(super) struct InputAlt(PtrCell<yazi_core::input::InputAlt>);
impl Deref for InputAlt {
type Target = yazi_core::input::InputAlt;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl InputAlt {
pub(super) fn make(inner: &yazi_core::input::InputAlt) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self(inner.into()))
}
}
impl UserData for InputAlt {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_cached_field("value", |lua, me| lua.create_string(me.lock().value()));
}
}

View file

@ -0,0 +1,51 @@
use std::mem::MaybeUninit;
use hashbrown::HashMap;
use mlua::{AnyUserData, UserData};
use scopeguard::defer;
use tracing::error;
use yazi_plugin::LUA;
use super::{Core, PtrCell};
use crate::lives::MutCell;
pub(super) static TO_DESTROY: MutCell<Vec<AnyUserData>> = MutCell::new(Vec::new());
pub(super) static FILE_CACHE: MutCell<
MaybeUninit<HashMap<PtrCell<yazi_fs::file::File>, AnyUserData>>,
> = MutCell::new(MaybeUninit::uninit());
pub struct Lives;
impl Lives {
pub fn scope<T, F>(core: &mut yazi_core::Core, f: F) -> mlua::Result<T>
where
F: FnOnce(&mut yazi_core::Core) -> mlua::Result<T>,
{
defer! {
unsafe {
(*FILE_CACHE.get()).assume_init_mut().clear();
for ud in (*TO_DESTROY.get()).drain(..) {
ud.destroy().expect("failed to destruct scoped userdata");
}
}
}
LUA.set_named_registry_value("cx", Core::make(core)?)?;
LUA.globals().raw_set("cx", Core::make(core)?)?;
let result = f(core);
if let Err(ref e) = result {
error!("{e}");
}
result
}
pub(crate) fn scoped_userdata<T>(data: T) -> mlua::Result<AnyUserData>
where
T: UserData + 'static,
{
let ud = LUA.create_userdata(data)?;
unsafe { &mut *TO_DESTROY.get() }.push(ud.clone());
Ok(ud)
}
}

View file

@ -0,0 +1,5 @@
yazi_macro::mod_flat!(behavior core entries file filter finder folder input input_alt lives mode mut_cell preference preview ptr selected tab tabs task tasks which yanked);
pub(super) fn init() {
unsafe { FILE_CACHE.get().write(std::mem::MaybeUninit::new(<_>::default())) };
}

View file

@ -0,0 +1,38 @@
use std::ops::Deref;
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
use yazi_binding::deprecate;
use super::{Lives, PtrCell};
pub(super) struct Mode {
inner: PtrCell<yazi_core::tab::Mode>,
}
impl Deref for Mode {
type Target = yazi_core::tab::Mode;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Mode {
pub(super) fn make(inner: &yazi_core::tab::Mode) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self { inner: inner.into() })
}
}
impl UserData for Mode {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("is_normal", |_, me| Ok(me.is_normal()));
fields.add_field_method_get("is_select", |_, me| Ok(me.is_select()));
fields.add_field_method_get("is_unset", |_, me| Ok(me.is_unset()));
fields.add_field_method_get("is_visual", |lua, me| {
deprecate!(lua, "{}: `mode.is_visual` is deprecated, use `not mode.is_normal` instead. \nSee #4101 for more details: https://github.com/sxyazi/yazi/pull/4101.");
Ok(!me.is_normal())
});
}
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string()));
}
}

View file

@ -0,0 +1,11 @@
use std::cell::UnsafeCell;
pub(super) struct MutCell<T>(UnsafeCell<T>);
unsafe impl<T> Sync for MutCell<T> {}
impl<T> MutCell<T> {
pub(super) const fn new(value: T) -> Self { Self(UnsafeCell::new(value)) }
pub(super) fn get(&self) -> *mut T { self.0.get() }
}

Some files were not shown because too many files have changed in this diff Show more