Compare commits

...

1191 commits
v0.1.5 ... 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
三咲雅 · Misaki Masa
7a380c2f0f
chore: bump version to 0.3 (#1374) 2024-08-01 14:36:16 +08:00
uncenter
c7b002581a
refactor(nix): cleanup and switch to nixfmt-rfc-style (#1376)
Co-authored-by: Isabel <isabel@isabelroses.com>
2024-08-01 11:01:07 +08:00
uncenter
bb29e238b5
feat(nix): set VERGEN_* build env vars (#1375) 2024-08-01 02:39:47 +08:00
uncenter
4257b95e8d
fix(nix): add outputHashes for notify git dependency (#1373) 2024-08-01 02:12:10 +08:00
三咲雅 · Misaki Masa
23a56c24a4
feat: new extract builtin plugin for archive extracting (#1321) 2024-07-31 08:27:22 +08:00
sxyazi
f024ce03e7
fix: adapt to a wider range of terminal cursor management through DECSET and DECRQM requests again 2024-07-26 23:45:40 +08:00
leihaojun
c086f2f34d
fix: can't rewatch a directory that has been deleted once before (#1335)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-26 00:14:38 +08:00
三咲雅 · Misaki Masa
df1f094a28
fix: adapt to a wider range of terminal cursor management through DECSET and DECRQM requests (#1346) 2024-07-25 22:25:26 +08:00
三咲雅 · Misaki Masa
152b9ea75e
fix: help menu multi-line text rendering (#1347) 2024-07-25 07:54:24 +08:00
Vladimir Panteleev
af0fb5955b
feat: make F1 also show the help menu (#1336)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-24 19:13:52 +08:00
三咲雅 · Misaki Masa
4a0522640d
fix: wrong directory loading optimization condition (#1331) 2024-07-24 16:26:09 +08:00
三咲雅 · Misaki Masa
a9eb218a5b
feat: add support for %@ argument extension on Windows to align with Unix platforms (#1319) 2024-07-22 19:06:02 +08:00
Moaid Hathot
66e83f3e18
feat: add Winget publishes to CI/CD (#1299)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2024-07-20 16:48:52 +08:00
Lauri Niskanen
093c13ac22
refactor: fix Clippy warnings (#1312)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-20 16:34:04 +08:00
Joshua Li
bba32ed0b2
fix: add use-dev-tty to fix piping to Yazi on macOS (#1317)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-20 16:26:37 +08:00
三咲雅 · Misaki Masa
640efcee26
fix: destroy term before stopping signals (#1310) 2024-07-19 22:41:15 +08:00
三咲雅 · Misaki Masa
d6081fbe6f
refactor: reimplement the signal system (#1307) 2024-07-18 23:41:02 +08:00
Mika Vilpas
f0cb365839
feat: allow setting YAZI_ID as a command line argument (#1305)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-18 15:04:46 +08:00
Mika Vilpas
67fb66c2e2
feat: help users migrate shell key bindings to v0.3 (#1304)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-18 13:56:40 +08:00
三咲雅 · Misaki Masa
ed6ae000d6
feat: add children_add and children_remove methods to the Header component as well (#1297) 2024-07-16 18:50:12 +08:00
三咲雅 · Misaki Masa
ec33085f67
feat: add ctime linemode (#1295) 2024-07-14 20:42:26 +08:00
Lauri Niskanen
ab88588c0e
feat: support displaying files with inaccessible metadata (#1275) 2024-07-14 14:42:42 +08:00
zooeywm
2cf722ed48
feat: add random option to the sort command (#1291)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-14 00:50:40 +08:00
三咲雅 · Misaki Masa
f5598ebb8a
feat: make UI extensions easier (#1257) 2024-07-13 14:22:03 +08:00
Lauri Niskanen
54eb0cc663
feat: new command hardlink (#1268)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-10 12:50:50 +08:00
Lauri Niskanen
afa5936bf5
feat: add nlink property to the Cha plugin API (#1279)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-09 07:05:42 +08:00
三咲雅 · Misaki Masa
9d0ef9a5dc
fix: build jemalloc with 64KB pagesize for linux/arm64 (#1270) 2024-07-07 10:30:03 +08:00
AidanV
11547eefe0
feat: ownership linemode (#1238)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-07-02 23:08:54 +08:00
三咲雅 · Misaki Masa
3c88edbc4d
feat: support AVIF image preview (#1249) 2024-07-02 22:44:08 +08:00
sxyazi
987b1d5c49
feat: simplify keybindings (#1241) 2024-07-01 23:58:03 +08:00
三咲雅 · Misaki Masa
1a1da216ca
feat: support right-click to open files (#1232) 2024-06-29 11:25:45 +08:00
hankertrix
9961251248
feat: add --hovered option to the rename and remove commands (#1227)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-06-28 08:59:23 +08:00
三咲雅 · Misaki Masa
626053da25
perf!: reimplement and significantly speed up archive previewing (#1220) 2024-06-27 00:47:56 +08:00
三咲雅 · Misaki Masa
c64530b35b
fix: magick plugin not working properly (#1213) 2024-06-25 23:49:54 +08:00
三咲雅 · Misaki Masa
9a5b75662a
fix: ueberzug image adapter should respect the user's max_width and max_height settings (#1200) 2024-06-24 18:47:31 +08:00
Xerxes-2
f1cf136df4
fix: suppress warnings for different name representations of the same file in the case-insensitive file system when renaming (#1185)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-06-24 00:59:33 +08:00
三咲雅 · Misaki Masa
696dcf2668
feat: support x-ndjson mime-type for JSON files (#1190) 2024-06-23 18:37:52 +08:00
Xerxes-2
804662ef82
fix: accommodate all hover events for DDS (#1187)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-06-23 18:23:26 +08:00
三咲雅 · Misaki Masa
0c5d621348
feat!: include the sender ID in static messages (#1172) 2024-06-23 01:33:59 +08:00
thelamb
505de05d66
feat: include file filter state in the header (#1182)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-06-22 19:01:51 +08:00
三咲雅 · Misaki Masa
f5a7aceac0
fix: file watcher didn't handle realname resolution used for case-insensitive file systems correctly (#1179) 2024-06-21 18:43:43 +08:00
sxyazi
0f84717a1b
feat: keep file creation time on macOS and Windows (#1169) 2024-06-20 14:54:42 +08:00
sxyazi
b5b6c9642a
feat: expose Finder API to Lua 2024-06-18 18:19:37 +08:00
sxyazi
f35712a768
refactor: prefer FromStr over Default for configuration parsing with side effects 2024-06-18 16:26:29 +08:00
Mika Vilpas
2a35d30f38
feat: support ya sub subcommand for the Ya CLI (#1004)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-06-16 15:37:11 +08:00
三咲雅 · Misaki Masa
794694e2d6
fix: different filenames should be treated as the same file on case-insensitive file systems (#1151) 2024-06-13 20:38:08 +08:00
sxyazi
189cb81db3
refactor: rename crate yazi-adaptor to yazi-adapter 2024-06-08 19:28:46 +08:00
三咲雅 · Misaki Masa
1166f86523
feat: support completely disabling mouse with mouse_events=[]; add new cursor_blink to control cursor style of input components (#1139) 2024-06-08 18:29:50 +08:00
三咲雅 · Misaki Masa
94628cad9e
fix: block SIGINT signal from the spawned subprocess (#1131) 2024-06-07 06:11:32 +08:00
sxyazi
9df256f7f4
fix: disable error reporting for the kitty graphics protocol 2024-06-05 17:00:18 +08:00
sxyazi
5f8c20e2b5
fix: use kitty old protocol for Konsole 2024-06-04 11:46:19 +08:00
Omar Magdy
2c84c48208
feat: add some dependency version information to yazi --debug (#1112)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-06-04 06:29:47 +08:00
Tianyang Zhou
162218c345
feat: support mouse event (#1038) 2024-06-03 14:31:55 +08:00
三咲雅 · Misaki Masa
e4d67121f8
feat!: DDS client-server version check (#1111) 2024-06-02 03:04:53 +08:00
Filipe Paniguel
add801f28e
feat: add pack --list subcommand to Ya CLI (#1110)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2024-06-02 00:30:14 +08:00
三咲雅 · Misaki Masa
95e960a64a
refactor!: v0.3 API changes (#1108) 2024-05-31 01:09:30 +08:00
sxyazi
46cd42f923
refactor: rename the domain term prefetcher to fetcher 2024-05-28 00:28:17 +08:00
sxyazi
b81b707a3e
fix: match_mime() should return true if pattern is "*" 2024-05-27 21:36:15 +08:00
Mika Vilpas
4c46862506
feat: support case insensitive special keys in keymappings (#1082)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-27 19:21:16 +08:00
三咲雅 · Misaki Masa
2eec94652a
fix: Sixel support from certain st forks cannot be detected (#1094) 2024-05-27 19:11:14 +08:00
George Nelson
1ab3df6850
feat!: transliteration option for natural sorting (#1053)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-27 07:28:10 +08:00
三咲雅 · Misaki Masa
061faea1c5
feat!: redesign icons (#1086) 2024-05-25 22:56:08 +08:00
三咲雅 · Misaki Masa
5f21998665
feat: cd path auto-completion supports ~ expansion (#1081) 2024-05-23 17:59:58 +08:00
sxyazi
58e5d2280a
fix: glob pattern for zip files 2024-05-22 17:59:46 +08:00
三咲雅 · Misaki Masa
f2b7f3eaf7
fix: remove the default keybinding for going to the temporary directory (#1073) 2024-05-22 14:16:18 +08:00
三咲雅 · Misaki Masa
d9ecffd19e
feat: support Super/Command/Windows key notation D- (#1069) 2024-05-22 13:11:23 +08:00
三咲雅 · Misaki Masa
f41e3c8d8b
fix: cursor gets out of sync occasionally at image previewing through IIP under tmux (#1070) 2024-05-22 13:10:16 +08:00
三咲雅 · Misaki Masa
0ebfacb677
fix: inconsistent tab width in unassociated text files (#1068) 2024-05-21 15:11:54 +08:00
三咲雅 · Misaki Masa
7177317465
feat: Chafa integration (#1066) 2024-05-21 02:46:28 +08:00
三咲雅 · Misaki Masa
a68e151194
fix: ePUB file mime-type matching for the opener rule (#1063) 2024-05-20 21:04:20 +08:00
三咲雅 · Misaki Masa
bf1c325d00
feat: prefetcher (#1061) 2024-05-20 17:25:55 +08:00
三咲雅 · Misaki Masa
c2affae3a9
feat: add a next property to the preloader rules to allow running multiple preloaders (#1058) 2024-05-19 19:04:04 +08:00
Johan Naizu
0ff4835f8d
docs: add CONTRIBUTING.md (#1052)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-18 17:49:14 +08:00
三咲雅 · Misaki Masa
5a83577259
feat: SVG, HEIC, and JPEG XL preview support (#1050) 2024-05-17 16:28:10 +08:00
三咲雅 · Misaki Masa
65afe6027a
feat: font preview (#1048) 2024-05-17 13:56:27 +08:00
Chris Zarate
f2329a3b35
fix: remove ignore options from rg and fd search (#1043)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-16 19:02:37 +08:00
三咲雅 · Misaki Masa
50ae6ebe39
feat: use Ctrl-c instead of Ctrl-q as the universal close key for all components (#1047) 2024-05-16 18:40:24 +08:00
三咲雅 · Misaki Masa
2683b1d6a2
refactor: eliminate exec (#1045) 2024-05-16 18:20:47 +08:00
George Nelson
dcd23f2cd3
ci: fix cargo unit tests execution (#1041) 2024-05-15 23:23:23 +08:00
Mika Vilpas
f0108dba40
ci: consistently enforce Lua coding style (#1029)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2024-05-15 10:54:20 +08:00
三咲雅 · Misaki Masa
28dfe728ab
feat: support stdin and pipe for Child API (#1033) 2024-05-14 22:07:19 +08:00
David Tolnay
07342a29ef
fix: recognize TERM=rxvt-unicode-256color (#1027) 2024-05-12 09:35:44 +08:00
三咲雅 · Misaki Masa
c1e1f26c4c
feat: add new debounce option to ya.input() API (#1025) 2024-05-11 17:42:35 +08:00
三咲雅 · Misaki Masa
eed82c1386
fix: broaden file watcher event types to accommodate permission changes on certain platforms (#1024) 2024-05-11 16:15:13 +08:00
June
6ff42c1a6d
fix: correct wasm target condition (#1018) 2024-05-09 10:10:09 +08:00
Gui
0ffba5c648
feat: new --args parameter for fd an rg search (#1013)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-09 03:01:16 +08:00
Mika Vilpas
386dd4c9c1
feat: ya pack displays help if no arguments are given (#1012) 2024-05-08 14:14:34 +08:00
三咲雅 · Misaki Masa
faa1d9f37b
feat: package manager (#985) 2024-05-07 13:42:45 +08:00
like
fdecf629a6
feat: add git commit hash to ya --version (#1006)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-05 01:16:31 +08:00
Mika Vilpas
668279814c
feat: yazi --debug shows ya version in its output (#1005)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-04 22:18:18 +08:00
slowsage
8d741eb62a
feat: support cargo binstall yazi-fm and cargo binstall yazi-cli (#1003) 2024-05-04 22:14:48 +08:00
三咲雅 · Misaki Masa
aee65bc4d1
fix: notification title width does not include the width of the icon (#1000) 2024-05-04 00:35:04 +08:00
三咲雅 · Misaki Masa
0e26f5d3c7
feat: close confirmation prompts and exit automatically when the ongoing task gone (#997) 2024-05-03 23:51:43 +08:00
GOWxx
2fdc0dd7bf
feat: add --force-window option to mpv (#998)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2024-05-03 23:42:35 +08:00
sxyazi
36b3ffafc1
fix: temporarily disable the file creation time until Rust v1.78.0 becomes popular (#991) 2024-05-03 02:22:27 +08:00
Rafael Bodill
a9cf8002d6
feat: re-enable the file created attribute (#987) 2024-05-02 09:10:05 +08:00
Mika Vilpas
28972ff54d
feat: add ya.clipboard() Lua API (#980)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-05-01 20:44:00 +08:00
Brixy
bdb28f7691
feat: add more rules to [filetype] and [icon] (#966)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-30 17:54:45 +08:00
三咲雅 · Misaki Masa
4c35f26e1f
feat: detect terminal type in tmux with CSI sequence in passthrough mode (#977) 2024-04-30 01:43:04 +08:00
Mika Vilpas
0016876dc9
fix: avoiding duplicate candidates in the which component (#975)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-30 01:38:54 +08:00
Brixy
3a09155328
fix: improve accessibility by avoiding hex color code for white (#968) 2024-04-28 21:00:38 +08:00
Brixy
9dd07017b0
feat: add *.opus file icon (#967) 2024-04-28 20:55:41 +08:00
sxyazi
d01e18067c
fix: move the DDS socket file out of the cache directory to avoid being affected by yazi --clear-cache 2024-04-27 16:47:50 +08:00
三咲雅 · Misaki Masa
681612f976
fix: correct the glob pattern for the icons to fit the new matching algorithm (#959) 2024-04-26 22:47:29 +08:00
三咲雅 · Misaki Masa
42a0fcd5cf
feat: support previewing files containing non-UTF-8 characters (#958) 2024-04-26 20:42:39 +08:00
三咲雅 · Misaki Masa
bf91f35d3e
fix: always create XDG cache directory even if user has set a custom one (#956) 2024-04-26 19:51:12 +08:00
Mika Vilpas
2febbee595
feat: add new bulk event kind to DDS (#937)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-25 20:14:52 +08:00
三咲雅 · Misaki Masa
1a3565963c
feat: support expanding Windows paths like "D:" that only have a drive letter but no root (#948) 2024-04-25 16:39:44 +08:00
Matthias Ahouansou
8456d3a7dc
feat: allow building with the system Lua (#943) 2024-04-24 18:49:46 +08:00
XYenon
8fc8770c28
feat: support yazi-cli for Nix flake (#944) 2024-04-24 17:44:04 +08:00
sxyazi
c65a14c0e6
chore: bump version to 0.2.5 2024-04-23 16:35:17 +08:00
三咲雅 · Misaki Masa
cb92bb7980
feat: new builtin session.lua plugin (#940) 2024-04-22 14:18:00 +08:00
三咲雅 · Misaki Masa
68da8998aa
feat: split ya send into ya pub and ya pub-static to make it more ergonomic (#933) 2024-04-21 09:25:38 +08:00
三咲雅 · Misaki Masa
55da9e342c
perf: cache each file's icon to avoid redundant calculations at rendering (#931) 2024-04-20 15:43:08 +08:00
Rolv Apneseth
80000cfd86
feat: preserve files' modified at timestamp while copying (#926)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-20 13:23:29 +08:00
Rolv Apneseth
a0b4ee6e6e
fix: prevent pasting a directory into itself (#925)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-20 11:15:57 +08:00
AidanV
669373a030
feat: change status bar percent at 100 to Bot (#930) 2024-04-20 10:11:50 +08:00
三咲雅 · Misaki Masa
ff14b9a265
fix: always persist static messages even when there are no remote clients (#928) 2024-04-19 20:36:27 +08:00
三咲雅 · Misaki Masa
09bc9aa371
feat: expand the types supported by the event system (#923) 2024-04-19 13:45:01 +08:00
三咲雅 · Misaki Masa
2975b999bf
fix: rollback ratatui to v0.26.1 to avoid panicking (#922) 2024-04-17 11:07:54 +08:00
Mika Vilpas
1d15fd96c5
feat: allow opening interactively with the --chosen-file flag (#920)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-17 07:14:48 +08:00
三咲雅 · Misaki Masa
9e75ed5c71
feat: generate autocomplete script for ya command (#919) 2024-04-16 12:40:14 +08:00
三咲雅 · Misaki Masa
4b04cb24b4
feat: allow creating a tab with the startup directory when the tab_create command is called without specifying a path parameter (#917) 2024-04-15 16:16:09 +08:00
三咲雅 · Misaki Masa
280529c2cd
feat: add a new ya send command to allow standalone client processes to communicate with DDS from the command line (#913) 2024-04-15 15:42:44 +08:00
Nguyễn Đức Toàn
64c5e85457
feat: smart case completion in cd paths (#910)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-14 23:34:02 +08:00
Nguyễn Đức Toàn
f442ae2adf
feat: trigger path completion with both / and \ on Windows (#909)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-04-14 23:16:23 +08:00
三咲雅 · Misaki Masa
a70374fced
perf: switch to globset to reduce CPU time spent on matching icons (#908) 2024-04-14 11:11:31 +08:00
三咲雅 · Misaki Masa
0cc14f44d7
feat: default "Reveal" opener for Linux (#907) 2024-04-14 01:43:10 +08:00
三咲雅 · Misaki Masa
5fc2789c78
feat: add loading state to directories (#904) 2024-04-13 10:33:42 +08:00
三咲雅 · Misaki Masa
3c67cae42d
feat: when there are no files in the list, add a placeholder message (#900) 2024-04-12 10:09:29 +08:00
三咲雅 · Misaki Masa
23c38ebae0
feat: add YAZI_ID environment variable (#895) 2024-04-11 23:57:47 +08:00
Mika Vilpas
38813413ec
feat: add new move, trash, and delete event kinds to DDS (#880)
Co-authored-by: 三咲雅 · Misaki Masa <sxyazi@gmail.com>
2024-04-11 01:09:29 +08:00
三咲雅 · Misaki Masa
e7dc971416
fix: file list expansion arguments ($@, $*) of shell command under opener rules are out of order (#890) 2024-04-10 08:31:03 +08:00
三咲雅 · Misaki Masa
884de41b66
feat: add new --orphan option to the shell command (#887) 2024-04-08 08:29:21 +08:00
三咲雅 · Misaki Masa
0cfb50bd49
feat: re-implement fzf as a built-in plugin (#884) 2024-04-07 19:28:09 +08:00
sxyazi
cd2e7ff945
feat: re-implement zoxide as a built-in plugin (#881) 2024-04-07 09:00:58 +08:00
三咲雅 · Misaki Masa
0650affb76
fix: CJK text rendering issue where the input popup component overlaps with images (#879) 2024-04-06 08:53:48 +08:00
三咲雅 · Misaki Masa
1b910ddc96
perf: re-implement file watcher in an async way (#877) 2024-04-05 17:47:17 +08:00
三咲雅 · Misaki Masa
4755654224
feat: add is_exec and is_sticky to Cha bindings (#875) 2024-04-05 17:11:40 +08:00
sxyazi
d04b549f4e
feat: merge the sender and severity in the DDS payload into the same field to simplify the protocol (#871) 2024-04-04 02:33:58 +08:00
三咲雅 · Misaki Masa
1b030e0f52
fix: a race condition in DDS static messages sent as internal events (#868) 2024-04-03 00:31:11 +08:00
三咲雅 · Misaki Masa
ec83c5dc5c
feat: detect CSI u through Stderr to allow using Stdout as the carrier of DDS payload without an ANSI sequence response timeout (#867) 2024-04-02 20:50:36 +08:00
三咲雅 · Misaki Masa
b51babde1c
feat: the cd event in DDS will now also be triggered when the tab is first created (#861) 2024-04-02 01:39:20 +08:00
sxyazi
7a99ea4409
fix: wrong state pointed to and ignore plugin/flavor directory creation errors 2024-04-01 00:11:07 +08:00
三咲雅 · Misaki Masa
bfcf401b40
feat: add a new sender property to the DDS payload (#855) 2024-03-31 22:29:52 +08:00
Solomon Jacobs
fd455a1ae4
feat: readable toml parsing error (#854)
Previously, the yazi displayed the following error.
```
Backtrace omitted. Run with RUST_BACKTRACE=1 to display it.
Run with RUST_BACKTRACE=full to include source snippets.

The application panicked (crashed).
  called `Result::unwrap()` on an `Err` value: Error { inner: Error { inner: TomlError { message: "invalid key", raw: Some("{ mime = \"application/octet-stream\",\nuse = [ \"extract_zlib\", \"reveal\" ] }\n"), keys: [], span: Some(0..1) } } }
in yazi-config/src/preset.rs, line 42
thread: main
```

It now displays the following message instead:

```
Error: Loading "/home/solo/.config/yazi/yazi.toml"

Caused by:
    TOML parse error at line 1, column 1
      |
    1 | { mime = "application/octet-stream",
      | ^
    invalid key
```

For more information see issue GH-847.

---------

Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-03-31 21:44:17 +08:00
sxyazi
3553a4a61e
fix: do not default to passing self to setup to respect user invocation behavior 2024-03-31 15:37:03 +08:00
三咲雅 · Misaki Masa
c240602046
perf: port require() and ya.sync() to Rust to avoid plugin information initialization process (#853) 2024-03-30 22:15:05 +08:00
三咲雅 · Misaki Masa
903f3da7e5
feat: DDS (Data Distribution Service) (#826) 2024-03-29 23:30:30 +08:00
三咲雅 · Misaki Masa
66d12da09d
perf: add BufWriter to Stderr to avoid frequent system calls and increase rendering frame rate (#849) 2024-03-29 15:40:04 +08:00
三咲雅 · Misaki Masa
06e9fb8e67
fix: Windows cmd.exe not responding to correct CSI sequences due to ConPTY (#845) 2024-03-29 00:22:10 +08:00
三咲雅 · Misaki Masa
e903320d95
feat: add support for YAZI_FILE_ONE to the built-in file previewer (#846) 2024-03-28 17:14:11 +08:00
三咲雅 · Misaki Masa
f6f2c30709
feat: time-based selection order preservation (#843) 2024-03-28 00:13:29 +08:00
三咲雅 · Misaki Masa
e619a97ee2
fix: mime-type for xz archives (#841) 2024-03-26 21:21:41 +08:00
三咲雅 · Misaki Masa
f8e0aee311
perf: accelerate kitty graphics protocol encoding by avoiding string reallocation (#837) 2024-03-23 13:34:46 +08:00
三咲雅 · Misaki Masa
9ba47141bf
feat: enhance the ya.dbg() and ya.err() debugging functions (#835) 2024-03-22 16:44:04 +08:00
Rolv Apneseth
e5c543cf80
fix: disable ANSI colours for the tracing_subscriber so that the logs are not polluted with escape codes (#832) 2024-03-22 11:40:22 +08:00
Rolv Apneseth
9918ceb7f4
fix: adjust calculation for number of lines in a notification message (#828)
Co-authored-by: sxyazi <sxyazi@gmail.com>
2024-03-20 13:14:48 +08:00
sxyazi
955e8f59a9
feat: add a bunch of new debugging information to yazi --debug (#824) 2024-03-17 01:03:39 +08:00
sxyazi
ca49a2d70b
fix: kill all spawned processes when exiting Yazi (#812) 2024-03-16 09:07:07 +08:00
三咲雅 · Misaki Masa
80aebda22c
feat: fix all dependencies to specific version numbers to allow non---locked builds (#821) 2024-03-16 02:29:37 +08:00
三咲雅 · Misaki Masa
411ba2fe85
refactor: switch to stderr (#819) 2024-03-15 20:31:39 +08:00
三咲雅 · Misaki Masa
094d44e3ec
fix: respond to the SIGTERM signal even when Yazi is in the background and has passed control of the terminal to the spawned process (#797) 2024-03-13 23:26:17 +08:00
sxyazi
457c2a5c06
fix: wrong type in iterator binding 2024-03-13 00:13:17 +08:00
三咲雅 · Misaki Masa
cddd0727ef
refactor: wrap Opener with Cow to avoid unnecessary memory reallocations when opening files (#805) 2024-03-12 23:35:26 +08:00
三咲雅 · Misaki Masa
78b98a98c3
fix: use BTreeSet for selected files to maintain order (#799) 2024-03-10 20:12:54 +08:00
sxyazi
b10f2de16d
feat: add --debug flag to print debug information (#794) 2024-03-09 19:04:46 +08:00
三咲雅 · Misaki Masa
9396d8760c
feat: ya.hide() plugin API (#792) 2024-03-09 03:07:20 +08:00
翊小久
3f80bc56a6
feat: truncate path for deeply nested directories (#787) 2024-03-08 17:54:29 +08:00
三咲雅 · Misaki Masa
d96af54574
fix: track the latest file changes for the selected, yanked state when available (#791) 2024-03-08 15:37:53 +08:00
三咲雅 · Misaki Masa
33782f1224
feat: cx.yanked plugin API (#788) 2024-03-07 17:26:18 +08:00
Prajna
1aed6e8b36
feat: send a foreground notification to the user when the process fails to run (#775) 2024-03-06 23:43:39 +08:00
hankertrix
b6e458f221
feat: add <C-p> and <C-n> to the select component for moving the cursor up/down (#779) 2024-03-06 23:39:52 +08:00
sxyazi
42307ee037
feat: test new color system 2024-03-06 21:44:38 +08:00
三咲雅 · Misaki Masa
4e873e62f1
feat: ui.Clear component for UI plugins (#786) 2024-03-06 19:07:37 +08:00
三咲雅 · Misaki Masa
37acd94345
feat: ya.notify() plugin API (#780) 2024-03-05 16:46:12 +08:00
sxyazi
497aa26f75
feat: add parse method to Line element 2024-03-05 00:53:01 +08:00
hankertrix
b7d9a0ad6e
feat: add Ctrl-[ as an escape key (#763) 2024-03-04 20:43:03 +08:00
三咲雅 · Misaki Masa
5169bb90f2
refactor: add new run property (#773) 2024-03-04 17:54:40 +08:00
三咲雅 · Misaki Masa
b4c9ec1de2
fix: nested conflict detection exception when performing cross-level searches (#769) 2024-03-04 11:27:30 +08:00
Konrad Baran
cc54205cc7
feat: add musl linux build targets (#759) 2024-03-03 15:36:49 +08:00
sxyazi
1835fba8ea
fix: remove redundant check to allow operations on the shell command with an empty file list 2024-03-03 09:55:37 +08:00
三咲雅 · Misaki Masa
bd572706cd
feat: ya.input() plugin API (#762) 2024-03-02 20:33:34 +08:00
三咲雅 · Misaki Masa
b39b506e27
feat: support %0 as the hovered file for Windows (#761) 2024-03-02 13:00:39 +08:00
三咲雅 · Misaki Masa
6a1063d376
perf: apply add_many()/remove_many() to the visual mode items for selection conflict detecting (#758) 2024-03-02 11:01:52 +08:00
Nguyễn Đức Toàn
fa2632eda9
feat: allow both '/' and '\' in folder creation (#751) 2024-03-01 11:26:58 +08:00
Nguyễn Đức Toàn
8508a5f577
feat: support YAZI_FILE_ONE environment variable for file(1) path (#752) 2024-03-01 11:21:44 +08:00
Filipe Paniguel
7f062359e8
feat: add prepend_rules and append_rules for [open] in yazi.toml (#754) 2024-03-01 10:38:02 +08:00
sxyazi
c3a1103529
feat: switch to inline images protocol for VSCode, Tabby, and Hyper 2024-03-01 10:22:12 +08:00
little camel
73b7e5acf7
feat: add a new [notify] section to the theme.toml to configure the notify component's style (#749) 2024-02-29 12:02:27 +08:00
sxyazi
4d8e276a6f
feat: flavor (#753) 2024-02-29 11:54:41 +08:00
rrveex
2efda755f1
feat: add hovered as $0 for shell and opener (#738) 2024-02-29 03:12:09 +08:00
musjj
b6fb02fda3
ci: add cachix workflow (#740) 2024-02-28 08:43:55 +08:00
三咲雅 · Misaki Masa
82071bd06b
refactor: prefer Display over ToString (#734) 2024-02-27 09:17:09 +08:00
sxyazi
d8abb3ed79
perf: prefer raw_get() and raw_set() 2024-02-26 12:49:58 +08:00
sxyazi
4e7e135cb5
feat: support is rule for [icon] (#720) 2024-02-26 10:25:35 +08:00
Diogo Duarte
aa8448677e
fix: initialize logs right after configurations (#708) 2024-02-26 09:55:16 +08:00
三咲雅 · Misaki Masa
46516dab74
refactor: new yazi-boot crate (#728) 2024-02-26 09:14:04 +08:00
sxyazi
42cbedbe42
feat: add idx field to the file API 2024-02-25 03:41:00 +08:00
三咲雅 · Misaki Masa
b4d91df767
fix: skip when the mime-type cannot match due to file permissions (#725) 2024-02-25 02:56:40 +08:00
三咲雅 · Misaki Masa
5e43f878c6
fix: rendering fails when no file type style is matched (#721) 2024-02-25 00:28:12 +08:00
三咲雅 · Misaki Masa
8ea7556625
feat: better accessibility (#719) 2024-02-24 09:11:53 +08:00
Filipe Paniguel
e51e8ad789
feat: add csharp, kdl and nu icons (#711) 2024-02-22 07:02:55 +08:00
三咲雅 · Misaki Masa
d954784643
perf: cache loaded plugins (#710) 2024-02-22 07:01:23 +08:00
三咲雅 · Misaki Masa
17f946dcdb
fix: ignore further classified mime-types (#707) 2024-02-21 17:28:18 +08:00
sxyazi
0cb572a837
feat: state now accepts a name for the bucket 2024-02-21 02:29:39 +08:00
Diogo Duarte
ed22be731a
fix: allow running ya.sync in a sync plugin call (#702) 2024-02-21 02:16:17 +08:00
sxyazi
2e9b6b7b7b
fix: any_file and any_dir should check is_folder 2024-02-20 17:45:41 +08:00
sxyazi
8efafd6c91
docs: move image preview details to the website 2024-02-20 00:15:40 +08:00
三咲雅 · Misaki Masa
3f27532c57
feat: cross-directory selection (#693) 2024-02-18 23:28:08 +08:00
TornaxO7
6aae7683ba
docs: Yazi must have a duck logo in README (#691) 2024-02-18 15:37:17 +08:00
little camel
c7bfdc556c
feat: nested selection conflict detection (#689) 2024-02-18 15:28:59 +08:00
sxyazi
2f784e7ae7
fix: if block in paste command was wrong 2024-02-17 20:42:23 +08:00
三咲雅 · Misaki Masa
1ec9943af2
refactor: using definite patterns to simplify keybindings (#690) 2024-02-17 19:03:26 +08:00
Lang Yang
53525b511e
feat: add a new option --hovered to the open command allowing users to only open the currently hovered file (#687) 2024-02-17 00:10:14 +08:00
Jaakko Paju
5c078aa18b
feat: add icons for Scala, Elm and Java (.jar & .class) 2024-02-16 13:13:33 +08:00
Rolv Apneseth
b82587e2c9
feat: add counter component to the header for displaying currently yanked/selected items (#646) 2024-02-15 22:54:57 +08:00
三咲雅 · Misaki Masa
52d91c0e42
feat: add new file marked state (#682) 2024-02-15 20:24:20 +08:00
三咲雅 · Misaki Masa
95d2358100
feat: expose selected/yanked files as API (#674) 2024-02-15 20:20:28 +08:00
Andy
ebe0257180
feat: add color to icons (#683) 2024-02-15 19:29:15 +08:00
Diogo Duarte
b55c5dc9a1
feat: add new scrolloff option to [manager] (#679) 2024-02-15 19:23:04 +08:00
grig-iv
b027487d12
feat: add prepend_rules and append_rules for [icon] (#670) 2024-02-13 16:30:55 +08:00
sxyazi
8bf0d6428f
fix: allow access to the current tab via tabs for consistency 2024-02-13 16:19:34 +08:00
三咲雅 · Misaki Masa
22ecad47ab
feat: Vim-like notification (#659) 2024-02-13 03:26:17 +08:00
三咲雅 · Misaki Masa
a764e42098
refactor: tab-specific selection (#653) 2024-02-13 02:40:13 +08:00
AbhaySP
84616bd15f
feat: enable the ability to sort the which key (#662) 2024-02-13 02:39:36 +08:00
uncenter
3213674dc7
ci: add clippy/rustfmt workflow (#663) 2024-02-12 15:12:49 +08:00
grig-iv
4b1783765f
feat: add <Delete> to [input] keymap (#665) 2024-02-12 15:00:12 +08:00
grig-iv
4222c0ed45
feat: add <Home> and <End> to [input] keymap 2024-02-11 15:48:58 +08:00
三咲雅 · Misaki Masa
dc1718fcf0
feat: calling sync functions within the async plugin (#649) 2024-02-09 17:28:14 +08:00
sxyazi
ed46456f8c
feat: merge wildcard preloader and previewer rules via append_preloaders and append_previewers 2024-02-09 12:37:46 +08:00
sxyazi
20b6f26247
fix: initialize window in Folder::make for folder preview 2024-02-09 11:08:39 +08:00
sxyazi
8851269585
fix: do not use jemalloc on macOS and Windows 2024-02-09 09:41:27 +08:00
三咲雅 · Misaki Masa
25c96557ed
feat: allows access to complete app data for all tabs (#644) 2024-02-08 16:05:37 +08:00
三咲雅 · Misaki Masa
c12a735f68
perf: cheaper sync context initialization (#643) 2024-02-08 12:14:01 +08:00
sxyazi
0d7e977076
chore: bump version to 0.2.3 2024-02-07 11:18:23 +08:00
Rolv Apneseth
fab5bc16cc
feat: if input is empty, close it on backspace command (#630) 2024-02-06 22:51:34 +08:00
sxyazi
19791d8328
feat: add ya.quote() function instead of ya.shell_join() 2024-02-06 10:47:57 +08:00
三咲雅 · Misaki Masa
d754044aae
fix: task manager not re-rendering after progress update (#633) 2024-02-06 08:35:50 +08:00
三咲雅 · Misaki Masa
59e889a3b5
fix: hidden attribute of files on Windows (#632) 2024-02-06 08:27:00 +08:00
HE7086
d776ce1074
feat: support char device in filetype (#628) 2024-02-05 09:50:39 +08:00
sxyazi
9e113a9337
feat: add ya.shell_join() API 2024-02-05 09:00:48 +08:00
三咲雅 · Misaki Masa
715fbf5b65
fix: attach plugin args to the entry method for better future optimization possibilities (#627) 2024-02-05 02:49:17 +08:00
三咲雅 · Misaki Masa
a027c1be12
feat: app_emit and manager_emit accepts boolean, integer, and number as option values (#625) 2024-02-04 08:38:10 +08:00
sxyazi
82359ef290
fix: image rotation with orientation 4
https://github.com/image-rs/image/issues/1958#issuecomment-1925350954
2024-02-03 23:01:42 +08:00
sxyazi
5086c02380
feat: add plugin command to each layer 2024-02-03 02:49:44 +08:00
三咲雅 · Misaki Masa
b51d1f26d0
feat: plugin interface for key events via ya.which() (#617) 2024-02-03 01:09:26 +08:00
sxyazi
920afe29bd
perf: use lazy sorting when loading large directories to reduce unnecessary CPU consumption (#607) 2024-02-01 18:43:59 +08:00
三咲雅 · Misaki Masa
e6079438a0
feat: make trash crate optional on Android (#600) 2024-01-31 21:54:19 +08:00
Sinkerine
b013dff4fe
feat: support unyank (#313) 2024-01-31 21:53:30 +08:00
三咲雅 · Misaki Masa
9d912b07aa
refactor: use Cmd instead of Exec (#604) 2024-01-31 08:59:47 +08:00
三咲雅 · Misaki Masa
9d9d954870
perf: read directory in bulk in the background at startup (#599) 2024-01-31 01:22:55 +08:00
三咲雅 · Misaki Masa
0f48fd58c7
feat: preview image over SSH (#585) 2024-01-31 00:35:23 +08:00
三咲雅 · Misaki Masa
68ffd82c0d
feat: plugin-specific state persistence (#590) 2024-01-28 00:30:41 +08:00
三咲雅 · Misaki Masa
c325c332de
feat: support passing arguments to plugin (#587) 2024-01-27 15:20:16 +08:00
三咲雅 · Misaki Masa
f31f78b063
feat: allow to configure image filter (#586) 2024-01-26 22:59:49 +08:00
sxyazi
c02d69590b
feat: shorten unit names and add more units to ya.readable_size 2024-01-26 16:35:36 +08:00
sxyazi
a9ce714571
fix: parent folder not tracking CWD (#581) 2024-01-26 13:18:15 +08:00
三咲雅 · Misaki Masa
ba0c860b2e
feat: new image_quality and sixel_fraction options to allow users to configure the image preview quality (#576) 2024-01-25 15:47:59 +08:00
三咲雅 · Misaki Masa
087448fd94
fix: input offset is not reset when renaming with --cursor=start and the filename is too long (#575) 2024-01-25 08:01:18 +08:00
三咲雅 · Misaki Masa
28870ad26e
feat: customizing the number of columns of "which key" component (#571) 2024-01-24 16:18:40 +08:00
三咲雅 · Misaki Masa
a19e263242
feat: image preview in Tabby terminal (#569) 2024-01-24 09:11:11 +08:00
三咲雅 · Misaki Masa
3248dbd8bb
feat: support submit completion and input at once by using <Enter> key (#565) 2024-01-23 16:45:57 +08:00
sxyazi
0c0a0f319d
fix: manager_emit should be sync 2024-01-23 12:31:53 +08:00
sxyazi
8cc18976d9
refactor: split router from executor 2024-01-23 10:35:00 +08:00
三咲雅 · Misaki Masa
56ede51c53
perf: new event system (#561) 2024-01-22 18:43:50 +08:00
三咲雅 · Misaki Masa
acb8b47eee
feat: improve search input title (#559) 2024-01-22 14:25:07 +08:00
sxyazi
e1d7f79191
feat: support Windows ARM64 (#558) 2024-01-22 13:57:36 +08:00
三咲雅 · Misaki Masa
701c08ce1e
feat: allow the spawned child processes to suspend (#556) 2024-01-22 08:43:51 +08:00
sxyazi
2b1b66e5e0
fix: ensure that changing directories occurs before searching 2024-01-22 04:35:34 +08:00
三咲雅 · Misaki Masa
69dec96833
fix: alternate tabs with the same path as the active tab cannot complete partial updates and cursor reset (#552) 2024-01-21 17:00:14 +08:00
三咲雅 · Misaki Masa
74bcae037b
feat: new host_name() API (#550) 2024-01-21 11:30:16 +08:00
三咲雅 · Misaki Masa
93dc1b78e2
feat: add prepend_keymap and append_keymap for configuring mixing (#546) 2024-01-20 13:55:57 +08:00
sxyazi
97a7eb7d47
feat: add file(1) as the file fallback previewer (#543) 2024-01-20 08:41:46 +08:00
三咲雅 · Misaki Masa
1bfd1c002f
fix: shell input code highlighting is not adapted for the default ANSI theme (#536) 2024-01-19 11:26:59 +08:00
三咲雅 · Misaki Masa
453ca94e18
fix: follow symlinks when detecting mime-type on Windows (#527) 2024-01-19 01:00:57 +08:00
三咲雅 · Misaki Masa
e987855fca
fix: can't display file name with invalid utf-8 (#529) 2024-01-19 00:49:15 +08:00
Mihai Fufezan
d41cd5684e
feat: add desktop entry and logo (#534) 2024-01-18 00:46:04 +08:00
Julian Chen
4647ec0dd0
feat: add support for snap packages (#531) 2024-01-18 00:20:45 +08:00
三咲雅 · Misaki Masa
6145bc38dc
fix: can't open and reveal paths with spaces on Windows (#526) 2024-01-17 00:13:23 +08:00
三咲雅 · Misaki Masa
9083535741
fix: can't clear screen and restore cursor when exit on Windows (#525) 2024-01-17 00:12:57 +08:00
sxyazi
1036685f91
chore: update trash to 3.2.1 2024-01-16 08:29:26 +08:00
三咲雅 · Misaki Masa
89848ad779
fix: renaming may cause a crash when encountering Unicode characters (#519) 2024-01-16 08:16:45 +08:00
István Donkó
cb80ca81da
feat: add YAZI_LEVEL env variable for shells (#514) 2024-01-16 00:30:43 +08:00
Azad
ca78f4c9b0
feat: add --empty and --cursor options to the rename command (#513) 2024-01-16 00:14:49 +08:00
sxyazi
85334457f3
fix: ensure that LINK and ORPHAN cannot coexist 2024-01-15 20:31:31 +08:00
三咲雅 · Misaki Masa
a1c963accc
perf: partial rendering progress and composite into a complete UI to reduce CPU consumption caused by frequent progress updates (#509) 2024-01-15 18:30:50 +08:00
sxyazi
ee8b8fc730
fix: support unicode characters in kill command 2024-01-15 16:47:44 +08:00
Azad
bf9f8f4273
feat: add support for highlighting by file type (#510) 2024-01-13 23:19:40 +08:00
sxyazi
876419a6c4
chore: bump version to 0.2.0 2024-01-13 21:13:23 +08:00
三咲雅 · Misaki Masa
c335b0272b
fix: update paged files after filter done (#505) 2024-01-13 15:23:18 +08:00
uncenter
e41266dbe3
chore: add schema urls to preset config (#506) 2024-01-12 20:15:36 +08:00
三咲雅 · Misaki Masa
a735b3234f
fix: prevent recursive caching - don't cache files in the cache directory (#504) 2024-01-12 01:35:57 +08:00
三咲雅 · Misaki Masa
560a1bf3f9
feat: icon color and ordered icon rules support (#503) 2024-01-10 23:24:36 +08:00
sxyazi
cd84386ead
fix: ignore peek task cancellation error 2024-01-10 03:12:57 +08:00
Alexander Serowy
d7d000c213
refactor: quit command (#484) 2024-01-10 03:10:26 +08:00
sxyazi
c3a8bdc3b6
fix: can't cancel help filter with Esc 2024-01-09 16:28:20 +08:00
sxyazi
59f79a2ae5
fix: hover(Some) should track the location of the file regardless 2024-01-09 14:58:43 +08:00
sxyazi
085f7e39bf
refactor: remove unnecessary .lua extension 2024-01-08 12:12:06 +08:00
三咲雅 · Misaki Masa
7e752df78a
feat: image orientation support (#488) 2024-01-08 11:31:22 +08:00
三咲雅 · Misaki Masa
1908ff2047
fix: resize isn't triggered on app restoring (#483) 2024-01-07 22:12:17 +08:00
sxyazi
72f924b9e5
feat: add new ya.render() API 2024-01-07 19:46:46 +08:00
sxyazi
93c8d90a51
feat: add new prepend_preloaders, append_preloaders, prepend_previewers, append_previewers config options 2024-01-06 12:58:42 +08:00
sxyazi
ac4afaf44e
feat: support display images in Ghostty 2024-01-06 11:11:08 +08:00
sxyazi
b229c8a5e3
fix: sort and hidden commands should update mime-type for paged files promptly 2024-01-06 05:14:54 +08:00
sxyazi
9bdbc55117
feat: add new plugin command 2024-01-05 15:22:28 +08:00
sxyazi
3fcc2014bc
fix: inability to restore default cursor on Windows 2024-01-05 11:41:24 +08:00
三咲雅 · Misaki Masa
43878fd92e
perf: detection of changes in the directory (#476) 2024-01-05 03:21:55 +08:00
sxyazi
63f81f6431
refactor: replace FilesOp::IOErr with FilesOp::Deleting 2024-01-03 09:46:47 +08:00
Urie
cf769bf533
feat: add user and group-related plugin APIs (#469) 2024-01-03 02:37:48 +08:00
三咲雅 · Misaki Masa
5c62cf2c65
perf: new UI rendering architecture (#468) 2024-01-02 08:38:26 +08:00
Sam Mohr
10a78b5dbc
feat: support ANSI themes (#460) 2024-01-01 22:07:06 +08:00
Mag Mell
6b0495f2c5
fix: add --follow option to paste command (#436) 2024-01-01 22:05:56 +08:00
三咲雅 · Misaki Masa
5fb0fceacb
perf: chunk loading for mime-types (#467) 2024-01-01 21:15:38 +08:00
sxyazi
ccb98ac21f
feat: v0.2.0 API 2023-12-30 23:41:41 +08:00
三咲雅 · Misaki Masa
32aa1909cf
feat: fine-grained scheduling priority (#462) 2023-12-29 22:37:43 +08:00
sxyazi
bfa5e0af0c
fix: os.date only accepts integer in Lua 5.4 2023-12-28 16:55:20 +08:00
三咲雅 · Misaki Masa
2d3512e965
fix: panic caused by set_hook (#459) 2023-12-28 03:32:39 +08:00
Rolv Apneseth
d2599b80b0
feat: filter files in real-time (#454) 2023-12-28 00:33:16 +08:00
三咲雅 · Misaki Masa
82bab0f24a
feat!: custom preloader & previewer (#401) 2023-12-26 19:48:33 +08:00
sxyazi
df42ca799e
feat: use a global clipboard 2023-12-19 22:49:54 +08:00
三咲雅 · Misaki Masa
d6ca524c53
feat: copy content over SSH (#447) 2023-12-12 10:46:19 +08:00
Mag Mell
a771308782
fix: do not use LuaJIT in riscv64 and loongarch64 architecture (#439) 2023-12-10 13:29:00 +08:00
againstpetra
1d1a512710
feat: new config option to suppress pre-caching tasks (#430) 2023-12-06 01:07:23 +08:00
sxyazi
dc1649f9ba
fix: generate wrong-sized cache images on pre-caching 2023-12-04 18:02:50 +08:00
三咲雅 · Misaki Masa
638a360d51
fix: crashes when selection indicator exceeds the visible area while a wrong folder_offset specified (#416) 2023-12-01 21:49:02 +08:00
XYenon
d54983143a
fix: build with rust-overlay (#410) 2023-11-29 21:45:47 +08:00
XYenon
8998753625
fix: catchup with the latest stable Rust (#409) 2023-11-29 20:37:10 +08:00
sxyazi
57c7d20d39
fix: documentation link 2023-11-29 16:07:58 +08:00
三咲雅 · Misaki Masa
6d29420e2f
refactor: integrate tasks into scheduler (#406) 2023-11-29 01:37:06 +08:00
JYShaw
b41bea9e8f
feat: support sorting by file extension (#405) 2023-11-28 15:16:42 +08:00
三咲雅 · Misaki Masa
a1984725e4
refactor: move event to shared (#403) 2023-11-28 02:21:36 +08:00
sxyazi
4d7d2ef082
feat: add a warning about <Backspace> key 2023-11-25 17:08:17 +08:00
sxyazi
f7f1e34649
refactor: use as_encoded_bytes instead of as_bytes 2023-11-25 12:38:54 +08:00
三咲雅 · Misaki Masa
47af821f48
fix: stepwise renaming causes uncertain sorting order (#398) 2023-11-25 10:10:34 +08:00
sxyazi
56b0611f7c
fix: peek down directories 2023-11-24 06:21:13 +08:00
三咲雅 · Misaki Masa
63b7491ad7
fix: popup components (Input, Select, etc.) being covered by previewed images (#360) 2023-11-23 21:36:35 +08:00
Hanaasagi
c643afd6e6
feat: include commit hash in yazi --version (#393) 2023-11-23 19:21:25 +08:00
Martin Wimpress
5439c80a03
feat: add more mime-types, file extensions and icons to the preset theme (#387) 2023-11-22 11:55:44 +08:00
Martin Wimpress
3e6dfcaceb
feat: cursor and page key navigation parity with Vim bindings (#386) 2023-11-22 09:42:31 +08:00
三咲雅 · Misaki Masa
d57a9642db
feat: make emacs readline keybindings configurable (#382) 2023-11-21 09:35:25 +08:00
三咲雅 · Misaki Masa
ac039c628e
fix: directories are recreated after deletion did not update the watcher tracking properly (#381) 2023-11-21 00:50:26 +08:00
sxyazi
a6f76400f8
fix: disable .djvu temporarily to prevent Überzug++ from freezing, close #379 2023-11-20 12:02:44 +08:00
sxyazi
d2963b23a9
refactor: eliminate the old kitty graphics protocol 2023-11-18 13:05:16 +08:00
Linus Walker
31ee5ab546
feat: add more optimization options (#377) 2023-11-18 11:44:43 +08:00
sxyazi
27255b22de
fix: avoid expanding paths for non-regular URLs 2023-11-18 11:28:54 +08:00
三咲雅 · Misaki Masa
f3e45d4a47
feat: expose image max alloc and bound to allow for more control (#376) 2023-11-18 10:01:05 +08:00
Hanaasagi
bb2353c7b9
feat: make Input and Select positions customizable (#361) 2023-11-18 01:40:20 +08:00
三咲雅 · Misaki Masa
6a64b162be
perf: reduce peak memory footprint during decoding large images (#375) 2023-11-17 12:06:07 +08:00
sxyazi
ab7acfec5c
refactor: remove unnecessary code 2023-11-17 09:17:30 +08:00
sxyazi
027c7a79c1
fix: panic caused by incorrect offset reset 2023-11-15 23:38:04 +08:00
sxyazi
0ea9bcda5f
feat: reduce the minimum number of workers to 1 2023-11-15 12:31:13 +08:00
三咲雅 · Misaki Masa
24e92d09e5
perf: clear only limited cells when hiding images (#369) 2023-11-15 08:52:56 +08:00
三咲雅 · Misaki Masa
f038391ef5
refactor: use more reasonable numeric field types for configs (#368) 2023-11-15 08:51:11 +08:00
三咲雅 · Misaki Masa
ff30b244b1
perf: precache small images to avoid cache misses; use symlink_metadata instead of metadata (#367) 2023-11-15 08:47:55 +08:00
Francis Chua
5968b82b0e
feat: emacs readline keybindings for Input component (#345) 2023-11-15 07:36:03 +08:00
sxyazi
3caf3ccda5
fix: Windows directory separator 2023-11-14 12:05:31 +08:00
三咲雅 · Misaki Masa
c3446cd941
feat: new kitty graphics protocol implementation for better compatibility with tmux through Unicode placeholders (#365) 2023-11-14 08:46:58 +08:00
三咲雅 · Misaki Masa
0931bc2bc6
feat: add support for opening a file on startup (#358) 2023-11-14 08:28:56 +08:00
sxyazi
5336f005ce
fix: find_do command missing 2023-11-13 02:14:11 +08:00
sxyazi
a0da57a293
fix: unable to clear preview image on can't get mimetype 2023-11-12 11:31:22 +08:00
sxyazi
c49bf02ca4
fix: cd doesn't expand the path automatically 2023-11-12 06:54:18 +08:00
三咲雅 · Misaki Masa
1a0753367e
fix: Rust panics instead of returning an error when file times are invalid (#357) 2023-11-12 03:31:21 +08:00
三咲雅 · Misaki Masa
49919cc5f4
feat: display the number of deleted files in the prompt (#359) 2023-11-11 08:58:34 +08:00
XOR-op
521c8b6bfe
fix: prefix matching should have higher priority in completion (#352) 2023-11-11 01:48:34 +08:00
三咲雅 · Misaki Masa
34d4be4071
feat: raise open file descriptors limit at startup (#342) 2023-11-10 23:03:47 +08:00
XOR-op
7512b2c63e
feat: make width of completion relative to input (#353) 2023-11-10 09:34:25 +08:00
三咲雅 · Misaki Masa
c41397957d
refactor: extracting commands into separate files to make them easier to maintain (#338) 2023-11-10 09:25:23 +08:00
三咲雅 · Misaki Masa
1bbb323509
feat: new reveal command (#341) 2023-11-09 09:07:12 +08:00
Hanaasagi
a0ba853718
fix: precache n-1 and n+1 pages (#349) 2023-11-08 20:44:31 +08:00
sxyazi
7c49d9c57a
fix: use <Tab> for completion confirming to avoid conflicts with the Input component 2023-11-07 20:24:53 +08:00
三咲雅 · Misaki Masa
1f744810f4
feat: better Zellij support with multi-factor detection involving emulator types (#336) 2023-11-06 08:10:57 +08:00
三咲雅 · Misaki Masa
dcb4944974
fix: the parent does not hover properly on switching the hidden state (#339) 2023-11-06 00:22:32 +08:00
sxyazi
847c475d8c
fix: completion won't closing when there are no candidates 2023-11-05 00:37:43 +08:00
sxyazi
539374fd14
feat: add new QuadrantInside and QuadrantOutside border type 2023-11-04 23:34:22 +08:00
三咲雅 · Misaki Masa
8ff62c80ca
perf: fallback to plain highlighter for long text (#329) 2023-11-04 06:33:20 +08:00
XOR-op
5b66f6fcf5
feat: auto-completion for input component (#324) 2023-11-04 06:30:52 +08:00
Simone Fidanza
73941c2291
feat: use USERPROFILE to retrieve readable path on Windows (#331) 2023-11-02 19:22:05 +08:00
uncenter
2d6a95ff5a
docs: update readme links to website (#332) 2023-11-02 19:19:45 +08:00
musjj
f9fbe7225a
feat: add overlays to flake.nix (#218) 2023-11-01 21:40:36 +08:00
Nicolai Fröhlich
396f60d9e0
ci: add Rust target "aarch64-unknown-linux-gnu" to release workflow (#326) 2023-10-27 20:58:34 +08:00
Rick Yao
aceec545ae
feat: add an identifier before the extension to prevent file conflicts rather than after (#316) 2023-10-27 14:51:16 +08:00
XOR-op
2b731748e4
chore: ignore configuration of editor (#322) 2023-10-26 23:02:37 +08:00
sxyazi
ce0c38ced5
feat: add lock and no-response workflow 2023-10-26 11:35:45 +08:00
三咲雅 · Misaki Masa
fc0057617e
fix: jq previews empty when the user sets tab_size=8 (#320) 2023-10-26 01:33:07 +08:00
三咲雅 · Misaki Masa
5c3c100d5d
fix: channel blockage caused by fuse permissions under the root user (#321) 2023-10-26 00:20:32 +08:00
三咲雅 · Misaki Masa
24fd587431
fix: use WAYLAND_DISPLAY and DISPLAY to detect Wayland/X11 when XDG_SESSION_TYPE is not set (#312) 2023-10-24 23:16:19 +08:00
三咲雅 · Misaki Masa
8aeef55b6f
feat: support image preview on WSL (#315) 2023-10-24 19:34:06 +08:00
Sinkerine
b46e71a6bb
fix: change the rust tool chain in shell.nix from stable to nightly (#314) 2023-10-24 16:16:24 +08:00
sxyazi
6a651f4e7f
chore: add issue templates 2023-10-24 07:36:17 +08:00
三咲雅 · Misaki Masa
93d8c30783
fix: nix flakes (#306) 2023-10-23 17:25:16 +08:00
linsui
55187496fa
fix: clear Sixel image with empty characters instead of \x2B[K to be compatible with GNOME VTE (#309) 2023-10-23 16:20:21 +08:00
sxyazi
bfc1dcb4f6
refactor: format and adjust log levels 2023-10-23 16:07:08 +08:00
sxyazi
52e0746f30
refactor: remove the warning of unused variable, fix #300 2023-10-23 15:58:22 +08:00
Sinkerine
2df1dae5af
feat: add config support for coordinate and size adjustment for ueberzugpp image preview (#304) 2023-10-23 14:46:03 +08:00
三咲雅 · Misaki Masa
c9178d4ab3
feat: add a new Folder:icon() API to make it easier for users to extend icons (#301) 2023-10-23 12:36:54 +08:00
sxyazi
6d3457dde0
fix: releasing CI 2023-10-22 18:54:24 +08:00
三咲雅 · Misaki Masa
671b480ab1
refactor: publish to crates.io (#298) 2023-10-22 16:34:20 +08:00
sxyazi
df4b502808
fix: typo of the deprecated version and roll it over to the next version 2023-10-22 10:19:33 +08:00
XYenon
dbd36b0d23
refactor(nix): add shell completion and avoid impure (#293) 2023-10-22 08:10:53 +08:00
1538 changed files with 85437 additions and 15866 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" ]

1
.envrc Normal file
View file

@ -0,0 +1 @@
use flake

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

70
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View file

@ -0,0 +1,70 @@
name: 🐞 Bug Report
description: Create a report to help us improve
labels: [bug]
assignees: []
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 bug
description: A clear and concise description of what the bug is
placeholder: Tell us what happened
validations:
required: true
- type: textarea
id: reproducer
attributes:
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: 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 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`)

14
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- 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

49
.github/ISSUE_TEMPLATE/feature.yml vendored Normal file
View file

@ -0,0 +1,49 @@
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:
label: Please describe the problem you're trying to solve
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
validations:
required: true
- type: checkboxes
id: contribute
attributes:
label: Would you be willing to contribute this feature?
description: The feature has a much higher chance of completion if you are willing to get involved!
options:
- label: Yes, I'll give it a shot
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: context
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. -->

30
.github/workflows/cachix.yml vendored Normal file
View file

@ -0,0 +1,30 @@
name: Cachix
on:
push:
branches: [main]
permissions:
contents: read
jobs:
publish:
name: Publish Flake
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Install Nix
uses: cachix/install-nix-action@v31
- name: Authenticate with Cachix
uses: cachix/cachix-action@v17
with:
name: yazi
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Build Flake
run: nix build -L

58
.github/workflows/check.yml vendored Normal file
View file

@ -0,0 +1,58 @@
name: Check
on:
push:
branches: [main]
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@v7
- name: Setup Rust toolchain
run: |
rustup toolchain install stable --profile minimal
rustup component add clippy
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Clippy
run: cargo clippy --all
rustfmt:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Rust toolchain
run: |
rustup toolchain install nightly --profile minimal
rustup component add rustfmt --toolchain nightly
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Rustfmt
run: find . -name '*.rs' -not -path './target/*' -exec rustfmt +nightly --check {} +
stylua:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- uses: JohnnyMorganz/stylua-action@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest
args: --color always --check .

260
.github/workflows/draft.yml vendored Normal file
View file

@ -0,0 +1,260 @@
name: Draft
on:
push:
branches: [main]
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
workflow_dispatch:
env:
SCCACHE_GHA_ENABLED: true
permissions:
contents: read
jobs:
build-unix:
strategy:
matrix:
include:
- os: ubuntu-latest
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@v7
- 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@v7
with:
name: ${{ matrix.target }}
path: |
yazi-${{ matrix.target }}.zip
yazi-${{ matrix.target }}.deb
build-windows:
strategy:
matrix:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
- 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@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Build
run: cargo build --profile release-windows --locked --target ${{ matrix.target }}
- name: Pack artifact
env:
TARGET_NAME: yazi-${{ matrix.target }}
run: |
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@v7
with:
name: ${{ matrix.target }}
path: yazi-${{ matrix.target }}.zip
build-musl:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- target: x86_64-unknown-linux-musl
- target: aarch64-unknown-linux-musl
container:
image: docker://ghcr.io/cross-rs/${{ matrix.target }}:edge
steps:
- 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@v7
with:
name: ${{ matrix.target }}
path: |
yazi-${{ matrix.target }}.zip
yazi-${{ matrix.target }}.deb
build-snap:
strategy:
matrix:
include:
- os: ubuntu-latest
arch: amd64
- os: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- 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
run: snapcraft --verbose
- name: Rename snap
run: mv yazi_*.snap yazi-${{ matrix.arch }}.snap
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
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@v8
with:
merge-multiple: true
- name: Draft
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 }}

31
.github/workflows/lock.yml vendored Normal file
View file

@ -0,0 +1,31 @@
name: Lock Threads
on:
schedule:
- cron: "5 3 * * *"
workflow_dispatch:
concurrency:
group: lock
jobs:
lock:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
discussions: write
steps:
- 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 file a new
issue and complete the issue template so we can capture all the details
necessary to investigate further.
pr-inactive-days: "30"
discussion-inactive-days: "30"
process-only: "issues,prs,discussions"

19
.github/workflows/no-response.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: No Response
on:
issue_comment:
types: [created]
schedule:
- cron: "10 * * * *"
jobs:
no-response:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: lee-dohm/no-response@v0.5.0
with:
token: ${{ github.token }}
daysUntilClose: 7
responseRequiredLabel: waiting on op

37
.github/workflows/publish.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: Publish
on:
release:
types: [published]
permissions:
contents: read
jobs:
winget:
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v8
with:
merge-multiple: true
- name: Publish to Winget
uses: vedantmgoyal9/winget-releaser@main
with:
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

@ -1,68 +0,0 @@
name: Release
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
jobs:
release:
permissions:
contents: write
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: macos-latest
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Add aarch64 target
if: matrix.target == 'aarch64-apple-darwin'
run: rustup target add aarch64-apple-darwin
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Build
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Pack artifacts [Linux & macOS]
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
env:
TARGET_NAME: yazi-${{ matrix.target }}
run: |
mkdir $TARGET_NAME
cp target/${{ matrix.target }}/release/yazi $TARGET_NAME
cp -r config/completions $TARGET_NAME
cp README.md LICENSE $TARGET_NAME
zip -r $TARGET_NAME.zip $TARGET_NAME
- name: Pack artifacts [Windows]
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\yazi.exe" -Destination ${env:TARGET_NAME}
Copy-Item -Path "config\completions" -Destination ${env:TARGET_NAME} -Recurse
Copy-Item -Path "README.md", "LICENSE" -Destination ${env:TARGET_NAME}
Compress-Archive -Path ${env:TARGET_NAME} -DestinationPath "${env:TARGET_NAME}.zip"
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
draft: true
files: yazi-${{ matrix.target }}.zip
generate_release_notes: true

View file

@ -2,29 +2,35 @@ name: Test
on:
push:
branches: [ "main" ]
branches: [main]
pull_request:
branches: [ "main" ]
branches: [main]
env:
SCCACHE_GHA_ENABLED: true
RUSTC_WRAPPER: sccache
CARGO_TERM_COLOR: always
permissions:
contents: read
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v7
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Setup Rust toolchain
run: rustup toolchain install stable --profile minimal
- name: Setup sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- name: Test
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 }}

10
.gitignore vendored
View file

@ -1,8 +1,14 @@
target/
config/completions
yazi-*/completions
node_modules/
.DS_Store
result
result-*
.devenv*
.direnv
.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"]
}

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

174
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,174 @@
# Contributing to Yazi
Thank you for your interest in contributing to Yazi! We welcome contributions in the form of bug reports, feature requests, documentation improvements, and code changes.
This guide will help you understand how to contribute to the project.
## Table of Contents
1. [Getting Started](#getting-started)
2. [Project Structure](#project-structure)
3. [Development Setup](#development-setup)
4. [How to Contribute](#how-to-contribute)
5. [Pull Requests](#pull-requests)
6. [AI Policy](#ai-policy)
## Getting Started
### Prerequisites
Before you begin, ensure you have met the following requirements:
- Rust installed on your machine. You can download it from [rustup.rs](https://rustup.rs).
- Familiarity with Git and GitHub.
### Fork the Repository
1. Fork the [Yazi repository](https://github.com/sxyazi/yazi) to your GitHub account.
2. Clone your fork to your local machine:
```sh
git clone https://github.com/<your-username>/yazi.git
```
3. Set up the upstream remote:
```sh
git remote add upstream https://github.com/sxyazi/yazi.git
```
## Project Structure
A brief overview of the project's structure:
```sh
.
├── assets/ # Assets like images and fonts
├── nix/ # Nix-related configurations
├── 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
```
## Development Setup
1. Ensure the latest stable Rust is installed:
```sh
rustc --version
cargo --version
```
2. Build the project:
```sh
cargo build
```
3. Run the tests:
```sh
cargo test --workspace --verbose
```
4. Format the code (requires `rustfmt` nightly):
```sh
rustup component add rustfmt --toolchain nightly
rustfmt +nightly **/*.rs
```
## How to Contribute
### Reporting Bugs
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 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 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
1. Create a new branch for your changes:
```sh
git checkout -b your-branch-name
```
2. Make your changes. Ensure that your code follows the project's [coding style](https://github.com/sxyazi/yazi/blob/main/rustfmt.toml) and passes all tests.
3. Commit your changes with a descriptive commit message:
```sh
git commit -m "feat: an awesome feature"
```
4. Push your changes to your fork:
```sh
git push origin your-branch-name
```
## 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:
```sh
git fetch upstream
git checkout main
git merge upstream/main
```
2. Rebase your feature branch onto the `main` branch:
```sh
git checkout your-branch-name
git rebase main
```
3. Create a pull request to the `main` branch of the upstream repository. Follow the pull request template and ensure that:
- 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.

4920
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,97 @@
[workspace]
resolver = "2"
members = [
"adaptor",
"app",
"config",
"core",
"plugin",
"shared",
]
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]
lto = true
strip = true
panic = "abort"
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"

21
LICENSE-ICONS Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 nvim-tree
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,28 +1,44 @@
<div align="center">
<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
Yazi ("duck" in Chinese) is a terminal file manager written in Rust, based on non-blocking async I/O. It aims to provide an efficient, user-friendly, and customizable file management experience.
Yazi (means "duck") is a terminal file manager written in Rust, based on non-blocking async I/O. It aims to provide an efficient, user-friendly, and customizable file management experience.
💫 A new article explaining its internal workings: [Why is Yazi Fast?](https://github.com/sxyazi/yazi/issues/143)
💡 A new article explaining its internal workings: [Why is Yazi Fast?](https://yazi-rs.github.io/blog/why-is-yazi-fast)
- 🚀 **Full Asynchronous Support**: All I/O operations are asynchronous, CPU tasks are spread across multiple threads, making the most of available resources.
- 💪 **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++, covering almost all terminals.
- 🌟 **Built-in Code Highlighting and Image Encoding**: Combined with the pre-caching mechanism, greatly accelerates image and normal file loading.
- 🧰 Integration with fd, rg, fzf, zoxide
- 💫 Vim-like Input component, and Select component
- 🏷️ Multi-Tab Support, Scrollable Preview (for videos, PDFs, archives, directories, code, etc.)
- 🔄 Batch Renaming, Visual Mode, File Chooser
- 🎨 Theme System, Custom Layouts, Trash Bin, CSI u
- 🖼️ **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/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.
- 🧰 Integration with ripgrep, fd, fzf, zoxide
- 💫 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 active 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
- Usage: https://yazi-rs.github.io/usage/installation
- Showcase: https://yazi-rs.github.io/showcase
- Usage: https://yazi-rs.github.io/docs/installation
- Features: https://yazi-rs.github.io/features
## Discussion
@ -31,31 +47,48 @@ https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265
## Image Preview
| Platform | Protocol | Support |
| ----------------- | -------------------------------------------------------------------------------- | --------------------- |
| Kitty | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in |
| WezTerm | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in |
| Konsole | [Terminal graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) | ✅ Built-in |
| iTerm2 | [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 |
| Hyper | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
| foot | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
| Black Box | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
| X11 / Wayland | Window system protocol | ☑️ Überzug++ required |
| Fallback | [Chafa](https://hpjansson.org/chafa/) | ☑️ Überzug++ 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) |
Yazi automatically selects the appropriate preview method for you, based on the priority from top to bottom.
That's relying on the `$TERM`, `$TERM_PROGRAM`, and `$XDG_SESSION_TYPE` variables, make sure you don't overwrite them by mistake!
See https://yazi-rs.github.io/docs/image-preview for details.
For instance, if your terminal is Alacritty, which doesn't support displaying images itself, but you are running on an X11/Wayland environment,
it will automatically use the "Window system protocol" to display images -- this requires you to have [Überzug++](https://github.com/jstkdng/ueberzugpp) installed.
<!-- Protocols -->
Here is a guide for tmux users: [Image preview within tmux](https://github.com/sxyazi/yazi/wiki/Image-preview-within-tmux)
[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
## TODO
<!-- Dependencies -->
See [Feature requests](https://github.com/sxyazi/yazi/issues/51) for more details.
[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.
Yazi is MIT-licensed. For more information check the [LICENSE](LICENSE) file.

View file

@ -1,19 +0,0 @@
[package]
name = "adaptor"
version = "0.1.5"
edition = "2021"
[dependencies]
config = { path = "../config" }
shared = { path = "../shared" }
# External dependencies
anyhow = "^1"
base64 = "^0"
color_quant = "^1"
image = "^0"
ratatui = "^0"
tokio = { version = "^1", features = [ "parking_lot" ] }
# Logging
tracing = "^0"

View file

@ -1,145 +0,0 @@
use std::{env, path::{Path, PathBuf}, sync::atomic::{AtomicBool, Ordering}};
use anyhow::{anyhow, Result};
use config::PREVIEW;
use ratatui::prelude::Rect;
use shared::RoCell;
use tokio::{fs, sync::mpsc::UnboundedSender};
use super::{Iterm2, Kitty};
use crate::{ueberzug::Ueberzug, Sixel, TMUX};
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
#[allow(clippy::type_complexity)]
static UEBERZUG: RoCell<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> = RoCell::new();
#[derive(Clone, Copy)]
pub enum Adaptor {
Kitty,
Iterm2,
Sixel,
// Supported by Überzug++
X11,
Wayland,
Chafa,
}
impl Adaptor {
pub(super) fn detect() -> Self {
let vars = [
("ZELLIJ_SESSION_NAME", Self::Sixel),
("KITTY_WINDOW_ID", Self::Kitty),
("KONSOLE_VERSION", Self::Kitty),
("ITERM_SESSION_ID", Self::Iterm2),
("WEZTERM_EXECUTABLE", cfg!(windows).then_some(Self::Iterm2).unwrap_or(Self::Kitty)),
("VSCODE_INJECTION", Self::Sixel),
];
if let Some(var) = vars.iter().find(|v| env::var_os(v.0).is_some()) {
return var.1;
}
let (term, program) = Self::term_program();
match program.as_str() {
"iTerm.app" => return Self::Iterm2,
"WezTerm" => return cfg!(windows).then_some(Self::Iterm2).unwrap_or(Self::Kitty),
"BlackBox" => return Self::Sixel,
"vscode" => return Self::Sixel,
"Hyper" => return Self::Sixel,
"mintty" => return Self::Iterm2,
_ => {}
}
match term.as_str() {
"xterm-kitty" => return Self::Kitty,
"foot" => return Self::Sixel,
"foot-extra" => return Self::Sixel,
_ => {}
}
match env::var("XDG_SESSION_TYPE").unwrap_or_default().as_str() {
"x11" => Self::X11,
"wayland" => Self::Wayland,
_ => Self::Chafa,
}
}
pub(super) fn term_program() -> (String, String) {
fn tmux_env(name: &str) -> Result<String> {
let output = std::process::Command::new("tmux").args(["show-environment", name]).output()?;
String::from_utf8(output.stdout)?
.trim()
.strip_prefix(&format!("{}=", name))
.map_or_else(|| Err(anyhow!("")), |s| Ok(s.to_string()))
}
let mut term = env::var("TERM").unwrap_or_default();
let mut program = env::var("TERM_PROGRAM").unwrap_or_default();
if *TMUX {
term = tmux_env("TERM").unwrap_or(term);
program = tmux_env("TERM_PROGRAM").unwrap_or(program);
}
(term, program)
}
}
impl ToString for Adaptor {
fn to_string(&self) -> String {
match self {
Self::Kitty => "kitty",
Self::Iterm2 => "iterm2",
Self::Sixel => "sixel",
Self::X11 => "x11",
Self::Wayland => "wayland",
Self::Chafa => "chafa",
}
.to_string()
}
}
impl Adaptor {
pub(super) fn start(self) {
UEBERZUG.init(if self.needs_ueberzug() { Ueberzug::start(self).ok() } else { None });
}
pub async fn image_show(self, mut path: &Path, rect: Rect) -> Result<()> {
let cache = PREVIEW.cache(path, 0);
if fs::metadata(&cache).await.is_ok() {
path = cache.as_path();
}
self.image_hide(rect).ok();
IMAGE_SHOWN.store(true, Ordering::Relaxed);
match self {
Self::Kitty => Kitty::image_show(path, rect).await,
Self::Iterm2 => Iterm2::image_show(path, rect).await,
Self::Sixel => Sixel::image_show(path, rect).await,
_ => Ok(if let Some(tx) = &*UEBERZUG {
tx.send(Some((path.to_path_buf(), rect)))?;
}),
}
}
pub fn image_hide(self, rect: Rect) -> Result<()> {
if !IMAGE_SHOWN.swap(false, Ordering::Relaxed) {
return Ok(());
}
match self {
Self::Kitty => Kitty::image_hide(),
Self::Iterm2 => Iterm2::image_hide(rect),
Self::Sixel => Sixel::image_hide(rect),
_ => Ok(if let Some(tx) = &*UEBERZUG {
tx.send(None)?;
}),
}
}
#[inline]
pub(super) fn needs_ueberzug(self) -> bool {
!matches!(self, Self::Kitty | Self::Iterm2 | Self::Sixel)
}
}

View file

@ -1,62 +0,0 @@
use std::{path::Path, sync::Arc};
use anyhow::Result;
use config::PREVIEW;
use image::{imageops::FilterType, DynamicImage, ImageFormat};
use shared::Term;
use tokio::fs;
pub struct Image;
impl Image {
pub(super) async fn crop(path: &Path, size: (u16, u16)) -> Result<DynamicImage> {
let (w, h) = Term::ratio()
.map(|(w, h)| {
let (w, h) = ((size.0 as f64 * w) as u32, (size.1 as f64 * h) as u32);
(w.min(PREVIEW.max_width), h.min(PREVIEW.max_height))
})
.unwrap_or((PREVIEW.max_width, PREVIEW.max_height));
let img = fs::read(path).await?;
let img = tokio::task::spawn_blocking(move || -> Result<DynamicImage> {
let img = image::load_from_memory(&img)?;
Ok(if img.width() > w || img.height() > h {
img.resize(w, h, FilterType::Triangle)
} else {
img
})
});
img.await?
}
pub async fn precache(img: Arc<Vec<u8>>, cache: impl AsRef<Path>) -> Result<bool> {
let cache = cache.as_ref().to_owned();
let result = tokio::task::spawn_blocking(move || {
let img = image::load_from_memory(&img)?;
let (w, h) = (PREVIEW.max_width, PREVIEW.max_height);
if img.width() <= w && img.height() <= h {
return Ok(false);
}
match img.resize(w, h, FilterType::Triangle) {
DynamicImage::ImageRgb8(buf) => buf.save_with_format(cache, ImageFormat::Jpeg),
DynamicImage::ImageRgba8(buf) => buf.save_with_format(cache, ImageFormat::Jpeg),
buf => buf.to_rgb8().save_with_format(cache, ImageFormat::Jpeg),
}?;
Ok(true)
});
result.await?
}
#[inline]
pub async fn precache_anyway(img: Arc<Vec<u8>>, cache: impl AsRef<Path>) -> Result<()> {
Ok(match Self::precache(img.clone(), &cache).await {
Ok(true) => (),
_ => fs::write(cache, &*img).await?,
})
}
}

View file

@ -1,56 +0,0 @@
use std::{io::{stdout, BufWriter, Write}, path::Path};
use anyhow::Result;
use base64::{engine::general_purpose, Engine};
use image::{codecs::jpeg::JpegEncoder, DynamicImage};
use ratatui::prelude::Rect;
use shared::Term;
use super::image::Image;
use crate::{CLOSE, START};
pub(super) struct Iterm2;
impl Iterm2 {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;
Self::image_hide(rect)?;
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
}
pub(super) fn image_hide(rect: Rect) -> Result<()> {
let stdout = BufWriter::new(stdout().lock());
Term::move_lock(stdout, (0, 0), |stdout| {
for y in rect.top()..rect.bottom() {
Term::move_to(stdout, rect.x, y)?;
Term::kill_to_end(stdout)?;
}
Ok(())
})
}
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
tokio::task::spawn_blocking(move || {
let size = (img.width(), img.height());
let mut jpg = vec![];
JpegEncoder::new_with_quality(&mut jpg, 75).encode_image(&img)?;
let mut buf = vec![];
write!(
buf,
"{}]1337;File=inline=1;size={};width={}px;height={}px;doNotMoveCursor=1:{}\x07{}",
START,
jpg.len(),
size.0,
size.1,
general_purpose::STANDARD.encode(&jpg),
CLOSE
)?;
Ok(buf)
})
.await?
}
}

View file

@ -1,76 +0,0 @@
use std::{io::{stdout, Write}, path::Path};
use anyhow::Result;
use base64::{engine::general_purpose, Engine};
use image::DynamicImage;
use ratatui::prelude::Rect;
use shared::Term;
use super::image::Image;
use crate::{CLOSE, ESCAPE, START};
pub(super) struct Kitty;
impl Kitty {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;
Self::image_hide()?;
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
}
#[inline]
pub(super) fn image_hide() -> Result<()> {
let mut stdout = stdout().lock();
stdout.write_all(format!("{}_Ga=d,d=A{}\\{}", START, ESCAPE, CLOSE).as_bytes())?;
stdout.flush()?;
Ok(())
}
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> {
let b64 = general_purpose::STANDARD.encode(raw).chars().collect::<Vec<_>>();
let mut it = b64.chunks(4096).peekable();
let mut buf = Vec::with_capacity(b64.len() + it.len() * 50);
if let Some(first) = it.next() {
write!(
buf,
"{}_Ga=T,f={},s={},v={},m={};{}{}\\{}",
START,
format,
size.0,
size.1,
it.peek().is_some() as u8,
first.iter().collect::<String>(),
ESCAPE,
CLOSE
)?;
}
while let Some(chunk) = it.next() {
write!(
buf,
"{}_Gm={};{}{}\\{}",
START,
it.peek().is_some() as u8,
chunk.iter().collect::<String>(),
ESCAPE,
CLOSE
)?;
}
buf.write_all(CLOSE.as_bytes())?;
Ok(buf)
}
let size = (img.width(), img.height());
tokio::task::spawn_blocking(move || match img {
DynamicImage::ImageRgb8(v) => output(v.as_raw(), 24, size),
DynamicImage::ImageRgba8(v) => output(v.as_raw(), 32, size),
v => output(v.to_rgb8().as_raw(), 24, size),
})
.await?
}
}

View file

@ -1,34 +0,0 @@
#![allow(clippy::unit_arg)]
mod adaptor;
mod image;
mod iterm2;
mod kitty;
mod sixel;
mod ueberzug;
use adaptor::*;
use iterm2::*;
use kitty::*;
use shared::RoCell;
use sixel::*;
pub use crate::image::*;
pub static ADAPTOR: RoCell<Adaptor> = RoCell::new();
// Tmux support
static TMUX: RoCell<bool> = RoCell::new();
static ESCAPE: RoCell<&'static str> = RoCell::new();
static START: RoCell<&'static str> = RoCell::new();
static CLOSE: RoCell<&'static str> = RoCell::new();
pub fn init() {
TMUX.init(std::env::var_os("TMUX").is_some());
START.init(if *TMUX { "\x1bPtmux;\x1b\x1b" } else { "\x1b" });
CLOSE.init(if *TMUX { "\x1b\\" } else { "" });
ESCAPE.init(if *TMUX { "\x1b\x1b" } else { "\x1b" });
ADAPTOR.init(Adaptor::detect());
ADAPTOR.start();
}

View file

@ -1,98 +0,0 @@
use std::{io::{stdout, BufWriter, Write}, path::Path};
use anyhow::{bail, Result};
use color_quant::NeuQuant;
use image::DynamicImage;
use ratatui::prelude::Rect;
use shared::Term;
use crate::{Image, CLOSE, ESCAPE, START};
pub(super) struct Sixel;
impl Sixel {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;
Self::image_hide(rect)?;
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
}
pub(super) fn image_hide(rect: Rect) -> Result<()> {
let stdout = BufWriter::new(stdout().lock());
Term::move_lock(stdout, (0, 0), |stdout| {
for y in rect.top()..rect.bottom() {
Term::move_to(stdout, rect.x, y)?;
Term::kill_to_end(stdout)?;
}
Ok(())
})
}
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
let alpha = img.color().has_alpha();
if img.width() == 0 || img.height() == 0 {
bail!("image is empty");
}
tokio::task::spawn_blocking(move || {
let img = img.into_rgba8();
let nq = NeuQuant::new(10, 256 - alpha as usize, &img);
let mut buf: Vec<u8> = Vec::with_capacity(1 << 16);
write!(buf, "{}P0;1;8q\"1;1;{};{}", START, img.width(), img.height())?;
// Palette
for (i, c) in nq.color_map_rgba().chunks(4).enumerate() {
write!(
buf,
"#{};2;{};{};{}",
i + alpha as usize,
c[0] as u16 * 100 / 255,
c[1] as u16 * 100 / 255,
c[2] as u16 * 100 / 255
)?;
}
for y in 0..img.height() {
let c = (b'?' + (1 << (y % 6))) as char;
let mut last = 0;
let mut repeat = 0usize;
for x in 0..img.width() {
let pixel = img.get_pixel(x, y).0;
let idx = if pixel[3] == 0 { 0 } else { nq.index_of(&pixel) as u8 + alpha as u8 };
if idx == last || repeat == 0 {
(last, repeat) = (idx, repeat + 1);
continue;
}
if repeat > 1 {
write!(buf, "#{last}!{repeat}{c}")?;
} else {
write!(buf, "#{last}{c}")?;
}
(last, repeat) = (idx, 1);
}
if repeat > 1 {
write!(buf, "#{last}!{repeat}{c}")?;
} else {
write!(buf, "#{last}{c}")?;
}
write!(buf, "$")?;
if y % 6 == 5 {
write!(buf, "-")?;
}
}
write!(buf, "{}\\{}", ESCAPE, CLOSE)?;
Ok(buf)
})
.await?
}
}

View file

@ -1,65 +0,0 @@
use std::{path::PathBuf, process::Stdio};
use anyhow::Result;
use ratatui::prelude::Rect;
use tokio::{io::AsyncWriteExt, process::{Child, Command}, sync::mpsc::{self, UnboundedSender}};
use crate::Adaptor;
pub(super) struct Ueberzug;
impl Ueberzug {
pub(super) fn start(adaptor: Adaptor) -> Result<UnboundedSender<Option<(PathBuf, Rect)>>> {
let mut child = Self::create_demon(adaptor).ok();
let (tx, mut rx) = mpsc::unbounded_channel();
tokio::spawn(async move {
while let Some(cmd) = rx.recv().await {
let exit = child.as_mut().and_then(|c| c.try_wait().ok());
if exit != Some(None) {
child = None;
}
if child.is_none() {
child = Self::create_demon(adaptor).ok();
}
if let Some(c) = &mut child {
Self::send_command(c, cmd).await.ok();
}
}
});
Ok(tx)
}
fn create_demon(adaptor: Adaptor) -> Result<Child> {
Ok(
Command::new("ueberzug")
.args(["layer", "-so", &adaptor.to_string()])
.kill_on_drop(true)
.stdin(Stdio::piped())
.stderr(Stdio::null())
.spawn()?,
)
}
async fn send_command(child: &mut Child, cmd: Option<(PathBuf, Rect)>) -> Result<()> {
let stdin = child.stdin.as_mut().unwrap();
if let Some((path, rect)) = cmd {
let s = format!(
r#"{{"action":"add","identifier":"yazi","x":{},"y":{},"max_width":{},"max_height":{},"path":"{}"}}{}"#,
rect.x,
rect.y,
rect.width,
rect.height,
path.to_string_lossy(),
"\n"
);
stdin.write_all(s.as_bytes()).await?;
} else {
stdin
.write_all(format!(r#"{{"action":"remove","identifier":"yazi"}}{}"#, "\n").as_bytes())
.await?;
}
Ok(())
}
}

View file

@ -1,33 +0,0 @@
[package]
name = "app"
version = "0.1.5"
edition = "2021"
[dependencies]
adaptor = { path = "../adaptor" }
config = { path = "../config" }
core = { path = "../core" }
plugin = { path = "../plugin" }
shared = { path = "../shared" }
# External dependencies
ansi-to-tui = "^3"
anyhow = "^1"
crossterm = { version = "^0", features = [ "event-stream" ] }
futures = "^0"
ratatui = "^0"
tokio = { version = "^1", features = [ "parking_lot" ] }
unicode-width = "^0"
# Logging
tracing = "^0"
tracing-appender = "^0"
tracing-subscriber = "^0"
[target."cfg(unix)".dependencies]
libc = "^0"
signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] }
[[bin]]
name = "yazi"
path = "src/main.rs"

View file

@ -1,220 +0,0 @@
use core::{emit, files::FilesOp, input::InputMode, Ctx, Event};
use std::ffi::OsString;
use anyhow::{Ok, Result};
use config::{keymap::{Exec, Key, KeymapLayer}, BOOT};
use crossterm::event::KeyEvent;
use shared::{expand_url, Term};
use tokio::sync::oneshot;
use crate::{Executor, Logs, Root, Signals};
pub(super) struct App {
cx: Ctx,
term: Option<Term>,
signals: Signals,
}
impl App {
pub(super) async fn run() -> Result<()> {
let _log = Logs::init()?;
let term = Term::start()?;
let signals = Signals::start()?;
let mut app = Self { cx: Ctx::make(), term: Some(term), signals };
while let Some(event) = app.signals.recv().await {
match event {
Event::Quit(no_cwd_file) => {
app.dispatch_quit(no_cwd_file);
break;
}
Event::Key(key) => app.dispatch_key(key),
Event::Paste(str) => app.dispatch_paste(str),
Event::Render(_) => app.dispatch_render(),
Event::Resize(..) => app.dispatch_resize(),
Event::Stop(state, tx) => app.dispatch_stop(state, tx),
Event::Call(exec, layer) => app.dispatch_call(exec, layer),
event => app.dispatch_module(event),
}
}
Ok(())
}
fn dispatch_quit(&mut self, no_cwd_file: bool) {
if let Some(p) = BOOT.cwd_file.as_ref().filter(|_| !no_cwd_file) {
let cwd = self.cx.manager.cwd().as_os_str();
#[cfg(windows)]
{
std::fs::write(p, cwd.to_string_lossy().as_bytes()).ok();
}
#[cfg(unix)]
{
use std::os::unix::ffi::OsStrExt;
std::fs::write(p, cwd.as_bytes()).ok();
}
}
}
fn dispatch_key(&mut self, key: KeyEvent) {
let key = Key::from(key);
if Executor::handle(&mut self.cx, key) {
emit!(Render);
}
}
fn dispatch_paste(&mut self, str: String) {
if self.cx.layer() == KeymapLayer::Input {
let input = &mut self.cx.input;
if input.mode() == InputMode::Insert && input.type_str(&str) {
emit!(Render);
}
}
}
fn dispatch_render(&mut self) {
if let Some(term) = &mut self.term {
_ = term.draw(|f| {
plugin::scope(&self.cx, |_| {
f.render_widget(Root::new(&self.cx), f.size());
});
if let Some((x, y)) = self.cx.cursor() {
f.set_cursor(x, y);
}
});
}
}
fn dispatch_resize(&mut self) {
self.cx.manager.current_mut().set_page(true);
self.cx.manager.active_mut().preview.reset(|_| true);
self.cx.manager.peek(true, self.cx.image_layer());
emit!(Render);
}
fn dispatch_stop(&mut self, state: bool, tx: Option<oneshot::Sender<()>>) {
self.cx.manager.active_mut().preview.reset(|l| l.is_image());
if state {
self.signals.stop_term(true);
self.term = None;
} else {
self.term = Some(Term::start().unwrap());
self.signals.stop_term(false);
emit!(Render);
emit!(Hover);
}
if let Some(tx) = tx {
tx.send(()).ok();
}
}
#[inline]
fn dispatch_call(&mut self, exec: Vec<Exec>, layer: KeymapLayer) {
if Executor::dispatch(&mut self.cx, &exec, layer) {
emit!(Render);
}
}
fn dispatch_module(&mut self, event: Event) {
let manager = &mut self.cx.manager;
let tasks = &mut self.cx.tasks;
match event {
Event::Cd(url) => {
futures::executor::block_on(async {
manager.active_mut().cd(expand_url(url)).await;
});
}
Event::Refresh => {
manager.refresh();
}
Event::Files(op) => {
let calc = !matches!(op, FilesOp::Size(..) | FilesOp::IOErr(_));
let b = match op {
FilesOp::IOErr(..) => manager.update_ioerr(op),
_ => manager.update_read(op),
};
if b {
emit!(Render);
}
if calc {
tasks.precache_size(&manager.current().files);
}
}
Event::Pages(page) => {
if manager.current().page == page {
let targets = self.cx.manager.current().paginate();
tasks.precache_mime(targets, &self.cx.manager.mimetype);
}
}
Event::Mimetype(mimes) => {
if manager.update_mimetype(mimes, tasks) {
emit!(Render);
emit!(Peek);
}
}
Event::Hover(url) => {
if manager.current_mut().repos(url) {
emit!(Render);
}
emit!(Peek);
}
Event::Peek(sequent) => {
if let Some((max, url)) = sequent {
manager.active_mut().update_peek(max, url);
self.cx.manager.peek(true, self.cx.image_layer());
} else {
self.cx.manager.peek(false, self.cx.image_layer());
}
}
Event::Preview(lock) => {
if manager.active_mut().update_preview(lock) {
emit!(Render);
}
}
Event::Select(opt, tx) => {
self.cx.select.show(opt, tx);
emit!(Render);
}
Event::Input(opt, tx) => {
self.cx.input.show(opt, tx);
emit!(Render);
}
Event::Open(targets, opener) => {
if let Some(p) = &BOOT.chooser_file {
let paths = targets.into_iter().fold(OsString::new(), |mut s, (p, _)| {
s.push(p);
s.push("\n");
s
});
#[cfg(windows)]
{
std::fs::write(p, paths.to_string_lossy().as_bytes()).ok();
}
#[cfg(unix)]
{
use std::os::unix::ffi::OsStrExt;
std::fs::write(p, paths.as_bytes()).ok();
}
return emit!(Quit(false));
}
if let Some(opener) = opener {
tasks.file_open_with(&opener, &targets.into_iter().map(|(f, _)| f).collect::<Vec<_>>());
} else {
tasks.file_open(&targets);
}
}
Event::Progress(progress) => {
tasks.progress = progress;
emit!(Render);
}
_ => unreachable!(),
}
}
}

View file

@ -1,279 +0,0 @@
use core::{emit, input::InputMode, tab::FinderCase, Ctx};
use config::{keymap::{Control, Exec, Key, KeymapLayer}, KEYMAP};
use shared::{optional_bool, Url};
pub(super) struct Executor;
impl Executor {
pub(super) fn handle(cx: &mut Ctx, key: Key) -> bool {
let layer = cx.layer();
if layer == KeymapLayer::Which {
return cx.which.press(key);
}
if layer == KeymapLayer::Input && cx.input.type_(&key) {
return true;
}
if layer == KeymapLayer::Help && cx.help.type_(&key) {
return true;
}
for Control { on, exec, .. } in KEYMAP.get(layer) {
if on.is_empty() || on[0] != key {
continue;
}
return if on.len() > 1 {
cx.which.show(&key, layer)
} else {
Self::dispatch(cx, exec, layer)
};
}
false
}
#[inline]
pub(super) fn dispatch(cx: &mut Ctx, exec: &[Exec], layer: KeymapLayer) -> bool {
let mut render = false;
for e in exec {
render |= match layer {
KeymapLayer::Manager => Self::manager(cx, e),
KeymapLayer::Tasks => Self::tasks(cx, e),
KeymapLayer::Select => Self::select(cx, e),
KeymapLayer::Input => Self::input(cx, e),
KeymapLayer::Help => Self::help(cx, e),
KeymapLayer::Which => unreachable!(),
};
}
render
}
fn manager(cx: &mut Ctx, exec: &Exec) -> bool {
match exec.cmd.as_str() {
"escape" => cx.manager.active_mut().escape(exec),
"quit" => cx.manager.quit(&cx.tasks, exec.named.contains_key("no-cwd-file")),
"close" => cx.manager.close(&cx.tasks),
"suspend" => cx.manager.suspend(),
// Navigation
"arrow" => {
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or_default();
cx.manager.active_mut().arrow(step)
}
"peek" => {
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
cx.manager.active_mut().preview.arrow(step);
cx.manager.peek(true, cx.image_layer())
}
"leave" => cx.manager.active_mut().leave(),
"enter" => cx.manager.active_mut().enter(),
"back" => cx.manager.active_mut().back(),
"forward" => cx.manager.active_mut().forward(),
"cd" => {
let url = exec.args.get(0).map(Url::from).unwrap_or_default();
if exec.named.contains_key("interactive") {
cx.manager.active_mut().cd_interactive(url)
} else {
emit!(Cd(url));
false
}
}
// Selection
"select" => {
let state = exec.named.get("state").cloned().unwrap_or("none".to_string());
cx.manager.active_mut().select(optional_bool(&state))
}
"select_all" => {
let state = exec.named.get("state").cloned().unwrap_or("none".to_string());
cx.manager.active_mut().select_all(optional_bool(&state))
}
"visual_mode" => cx.manager.active_mut().visual_mode(exec.named.contains_key("unset")),
// Operation
"open" => cx.manager.open(exec.named.contains_key("interactive")),
"yank" => cx.manager.yank(exec.named.contains_key("cut")),
"paste" => {
let dest = cx.manager.cwd();
let (cut, ref src) = cx.manager.yanked;
let force = exec.named.contains_key("force");
if cut { cx.tasks.file_cut(src, dest, force) } else { cx.tasks.file_copy(src, dest, force) }
}
"link" => {
let (cut, ref src) = cx.manager.yanked;
!cut
&& cx.tasks.file_link(
src,
cx.manager.cwd(),
exec.named.contains_key("relative"),
exec.named.contains_key("force"),
)
}
"remove" => {
let targets = cx.manager.selected().into_iter().map(|f| f.url()).collect();
let force = exec.named.contains_key("force");
let permanently = exec.named.contains_key("permanently");
cx.tasks.file_remove(targets, force, permanently)
}
"create" => cx.manager.create(exec.named.contains_key("force")),
"rename" => cx.manager.rename(exec.named.contains_key("force")),
"copy" => cx.manager.active().copy(exec.args.get(0).map(|s| s.as_str()).unwrap_or("")),
"shell" => cx.manager.active().shell(
exec.args.get(0).map(|e| e.as_str()).unwrap_or(""),
exec.named.contains_key("block"),
exec.named.contains_key("confirm"),
),
"hidden" => cx.manager.active_mut().hidden(exec),
"linemode" => cx.manager.active_mut().linemode(exec),
"search" => match exec.args.get(0).map(|s| s.as_str()).unwrap_or("") {
"rg" => cx.manager.active_mut().search(true),
"fd" => cx.manager.active_mut().search(false),
_ => cx.manager.active_mut().search_stop(),
},
"jump" => match exec.args.get(0).map(|s| s.as_str()).unwrap_or("") {
"fzf" => cx.manager.active_mut().jump(true),
"zoxide" => cx.manager.active_mut().jump(false),
_ => false,
},
// Find
"find" => {
let query = exec.args.get(0).map(|s| s.as_str());
let prev = exec.named.contains_key("previous");
let case = match (exec.named.contains_key("smart"), exec.named.contains_key("insensitive"))
{
(true, _) => FinderCase::Smart,
(_, false) => FinderCase::Sensitive,
(_, true) => FinderCase::Insensitive,
};
cx.manager.active_mut().find(query, prev, case)
}
"find_arrow" => cx.manager.active_mut().find_arrow(exec.named.contains_key("previous")),
// Sorting
"sort" => {
let b = cx.manager.active_mut().sort(exec);
cx.tasks.precache_size(&cx.manager.current().files);
b
}
// Tabs
"tab_create" => {
let path = if exec.named.contains_key("current") {
cx.manager.cwd().to_owned()
} else {
exec.args.get(0).map(Url::from).unwrap_or_else(|| Url::from("/"))
};
cx.manager.tabs.create(&path)
}
"tab_close" => {
let idx = exec.args.get(0).and_then(|i| i.parse().ok()).unwrap_or(0);
cx.manager.tabs.close(idx)
}
"tab_switch" => {
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
let rel = exec.named.contains_key("relative");
cx.manager.tabs.switch(step, rel)
}
"tab_swap" => {
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
cx.manager.tabs.swap(step)
}
// Tasks
"tasks_show" => cx.tasks.toggle(),
// Help
"help" => cx.help.toggle(cx.layer()),
_ => false,
}
}
fn tasks(cx: &mut Ctx, exec: &Exec) -> bool {
match exec.cmd.as_str() {
"close" => cx.tasks.toggle(),
"arrow" => {
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
if step > 0 { cx.tasks.next() } else { cx.tasks.prev() }
}
"inspect" => cx.tasks.inspect(),
"cancel" => cx.tasks.cancel(),
"help" => cx.help.toggle(cx.layer()),
_ => false,
}
}
fn select(cx: &mut Ctx, exec: &Exec) -> bool {
match exec.cmd.as_str() {
"close" => cx.select.close(exec.named.contains_key("submit")),
"arrow" => {
let step: isize = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
if step > 0 { cx.select.next(step as usize) } else { cx.select.prev(step.unsigned_abs()) }
}
"help" => cx.help.toggle(cx.layer()),
_ => false,
}
}
fn input(cx: &mut Ctx, exec: &Exec) -> bool {
match exec.cmd.as_str() {
"close" => return cx.input.close(exec.named.contains_key("submit")),
"escape" => return cx.input.escape(),
"move" => {
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
let in_operating = exec.named.contains_key("in-operating");
return if in_operating { cx.input.move_in_operating(step) } else { cx.input.move_(step) };
}
_ => {}
}
match cx.input.mode() {
InputMode::Normal => match exec.cmd.as_str() {
"insert" => cx.input.insert(exec.named.contains_key("append")),
"visual" => cx.input.visual(),
"backward" => cx.input.backward(),
"forward" => cx.input.forward(exec.named.contains_key("end-of-word")),
"delete" => {
cx.input.delete(exec.named.contains_key("cut"), exec.named.contains_key("insert"))
}
"yank" => cx.input.yank(),
"paste" => cx.input.paste(exec.named.contains_key("before")),
"undo" => cx.input.undo(),
"redo" => cx.input.redo(),
"help" => cx.help.toggle(cx.layer()),
_ => false,
},
InputMode::Insert => false,
}
}
fn help(cx: &mut Ctx, exec: &Exec) -> bool {
match exec.cmd.as_str() {
"close" => cx.help.toggle(cx.layer()),
"escape" => cx.help.escape(),
"arrow" => {
let step = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
cx.help.arrow(step)
}
"filter" => cx.help.filter(),
_ => false,
}
}
}

View file

@ -1,54 +0,0 @@
use core::Ctx;
use config::THEME;
use ratatui::{layout::{self, Constraint}, prelude::{Buffer, Direction, Rect}, widgets::{List, ListItem, Widget}};
pub(super) struct Bindings<'a> {
cx: &'a Ctx,
}
impl<'a> Bindings<'a> {
pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } }
}
impl Widget for Bindings<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
let bindings = &self.cx.help.window();
if bindings.is_empty() {
return;
}
// On
let col1 = bindings
.iter()
.map(|c| ListItem::new(c.on()).style(THEME.help.on.into()))
.collect::<Vec<_>>();
// Exec
let col2 = bindings
.iter()
.map(|c| ListItem::new(c.exec()).style(THEME.help.exec.into()))
.collect::<Vec<_>>();
// Desc
let col3 = bindings
.iter()
.map(|c| ListItem::new(c.desc.as_deref().unwrap_or("-")).style(THEME.help.desc.into()))
.collect::<Vec<_>>();
let chunks = layout::Layout::new()
.direction(Direction::Horizontal)
.constraints([Constraint::Ratio(2, 10), Constraint::Ratio(3, 10), Constraint::Ratio(5, 10)])
.split(area);
let cursor = self.cx.help.rel_cursor() as u16;
buf.set_style(
Rect { x: area.x, y: area.y + cursor, width: area.width, height: 1 },
THEME.help.hovered.into(),
);
List::new(col1).render(chunks[0], buf);
List::new(col2).render(chunks[1], buf);
List::new(col3).render(chunks[2], buf);
}
}

View file

@ -1,32 +0,0 @@
use core::Ctx;
use config::THEME;
use ratatui::{buffer::Buffer, layout::{self, Rect}, prelude::{Constraint, Direction}, widgets::{Clear, Paragraph, Widget}};
use super::Bindings;
pub(crate) struct Layout<'a> {
cx: &'a Ctx,
}
impl<'a> Layout<'a> {
pub fn new(cx: &'a Ctx) -> Self { Self { cx } }
}
impl<'a> Widget for Layout<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
let chunks = layout::Layout::new()
.direction(Direction::Vertical)
.constraints([Constraint::Min(0), Constraint::Length(1)])
.split(area);
Clear.render(area, buf);
let help = &self.cx.help;
Paragraph::new(help.keyword().unwrap_or_else(|| format!("{}.help", help.layer)))
.style(THEME.help.footer.into())
.render(chunks[1], buf);
Bindings::new(self.cx).render(chunks[0], buf);
}
}

View file

@ -1,5 +0,0 @@
mod bindings;
mod layout;
use bindings::*;
pub(super) use layout::*;

View file

@ -1,59 +0,0 @@
use core::{input::InputMode, Ctx};
use std::ops::Range;
use ansi_to_tui::IntoText;
use config::THEME;
use ratatui::{buffer::Buffer, layout::Rect, text::{Line, Text}, widgets::{Block, BorderType, Borders, Clear, Paragraph, Widget}};
use shared::Term;
pub(crate) struct Input<'a> {
cx: &'a Ctx,
}
impl<'a> Input<'a> {
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } }
}
impl<'a> Widget for Input<'a> {
fn render(self, win: Rect, buf: &mut Buffer) {
let input = &self.cx.input;
let area = self.cx.area(&input.position);
let value = if let Ok(v) = input.value_pretty() {
v.into_text().unwrap()
} else {
Text::from(input.value())
};
Clear.render(area, buf);
Paragraph::new(value)
.block(
Block::new()
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(THEME.input.border.into())
.title({
let mut line = Line::from(input.title());
line.patch_style(THEME.input.title.into());
line
}),
)
.style(THEME.input.value.into())
.render(area, buf);
if let Some(Range { start, end }) = input.selected() {
let x = win.width.min(area.x + 1 + start);
let y = win.height.min(area.y + 1);
buf.set_style(
Rect { x, y, width: (end - start).min(win.width - x), height: 1.min(win.height - y) },
THEME.input.selected.into(),
)
}
_ = match input.mode() {
InputMode::Insert => Term::set_cursor_bar(),
_ => Term::set_cursor_block(),
};
}
}

View file

@ -1,3 +0,0 @@
mod input;
pub(super) use input::*;

View file

@ -1,21 +0,0 @@
use anyhow::{Context, Result};
use config::BOOT;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{fmt, prelude::__tracing_subscriber_SubscriberExt, Registry};
pub(super) struct Logs;
impl Logs {
pub(super) fn init() -> Result<WorkerGuard> {
let appender = tracing_appender::rolling::never(&BOOT.state_dir, "yazi.log");
let (handle, guard) = tracing_appender::non_blocking(appender);
// let filter = EnvFilter::from_default_env();
let subscriber = Registry::default().with(fmt::layer().pretty().with_writer(handle));
tracing::subscriber::set_global_default(subscriber)
.context("setting default subscriber failed")?;
Ok(guard)
}
}

View file

@ -1,33 +0,0 @@
#![allow(clippy::module_inception)]
mod app;
mod executor;
mod help;
mod input;
mod logs;
mod root;
mod select;
mod signals;
mod tasks;
mod which;
use app::*;
use executor::*;
use logs::*;
use root::*;
use signals::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// console_subscriber::init();
config::init();
core::init();
plugin::init();
adaptor::init();
App::run().await
}

View file

@ -1,48 +0,0 @@
use core::Ctx;
use plugin::components;
use ratatui::{buffer::Buffer, layout::{Constraint, Direction, Layout, Rect}, widgets::Widget};
use super::{input, select, tasks, which};
use crate::help;
pub(super) struct Root<'a> {
cx: &'a Ctx,
}
impl<'a> Root<'a> {
pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } }
}
impl<'a> Widget for Root<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
let chunks = Layout::new()
.direction(Direction::Vertical)
.constraints([Constraint::Length(1), Constraint::Min(0), Constraint::Length(1)])
.split(area);
components::Header::new(self.cx).render(chunks[0], buf);
components::Manager::new(self.cx).render(chunks[1], buf);
components::Status::new(self.cx).render(chunks[2], buf);
if self.cx.tasks.visible {
tasks::Layout::new(self.cx).render(area, buf);
}
if self.cx.select.visible {
select::Select::new(self.cx).render(area, buf);
}
if self.cx.input.visible {
input::Input::new(self.cx).render(area, buf);
}
if self.cx.help.visible {
help::Layout::new(self.cx).render(area, buf);
}
if self.cx.which.visible {
which::Which::new(self.cx).render(area, buf);
}
}
}

View file

@ -1,3 +0,0 @@
mod select;
pub(super) use select::*;

View file

@ -1,43 +0,0 @@
use core::Ctx;
use config::THEME;
use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, Borders, Clear, List, ListItem, Widget}};
pub(crate) struct Select<'a> {
cx: &'a Ctx,
}
impl<'a> Select<'a> {
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } }
}
impl<'a> Widget for Select<'a> {
fn render(self, _: Rect, buf: &mut Buffer) {
let select = &self.cx.select;
let area = self.cx.area(&select.position);
let items = select
.window()
.iter()
.enumerate()
.map(|(i, v)| {
if i != select.rel_cursor() {
return ListItem::new(format!(" {v}")).style(THEME.select.inactive.into());
}
ListItem::new(format!("{v}")).style(THEME.select.active.into())
})
.collect::<Vec<_>>();
Clear.render(area, buf);
List::new(items)
.block(
Block::new()
.title(select.title())
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(THEME.select.border.into()),
)
.render(area, buf);
}
}

View file

@ -1,107 +0,0 @@
use core::Event;
use anyhow::Result;
use crossterm::event::{Event as CrosstermEvent, EventStream, KeyEvent, KeyEventKind};
use futures::StreamExt;
use tokio::{select, sync::{mpsc::{self, UnboundedReceiver, UnboundedSender}, oneshot}, task::JoinHandle};
pub(super) struct Signals {
tx: UnboundedSender<Event>,
rx: UnboundedReceiver<Event>,
term_stop_tx: Option<oneshot::Sender<()>>,
term_stop_rx: Option<oneshot::Receiver<()>>,
}
impl Signals {
pub(super) fn start() -> Result<Self> {
let (tx, rx) = mpsc::unbounded_channel();
let (term_tx, term_rx) = oneshot::channel();
let mut signals =
Self { tx: tx.clone(), rx, term_stop_tx: Some(term_tx), term_stop_rx: Some(term_rx) };
signals.spawn_system_task()?;
signals.spawn_crossterm_task();
Event::init(tx);
Ok(signals)
}
#[inline]
pub(super) async fn recv(&mut self) -> Option<Event> { self.rx.recv().await }
pub(super) fn stop_term(&mut self, state: bool) {
if state == self.term_stop_tx.is_none() {
return;
}
if let Some(tx) = self.term_stop_tx.take() {
tx.send(()).ok();
} else {
let (tx, rx) = oneshot::channel();
(self.term_stop_tx, self.term_stop_rx) = (Some(tx), Some(rx));
self.spawn_crossterm_task();
}
}
#[cfg(windows)]
fn spawn_system_task(&self) -> Result<()> { Ok(()) }
#[cfg(unix)]
fn spawn_system_task(&self) -> Result<JoinHandle<()>> {
use libc::{SIGCONT, SIGHUP, SIGINT, SIGQUIT, SIGTERM};
let tx = self.tx.clone();
let mut signals = signal_hook_tokio::Signals::new([
// Terminating signals
SIGHUP, SIGTERM, SIGQUIT, SIGINT, //
// Job control signals
SIGCONT,
])?;
Ok(tokio::spawn(async move {
while let Some(signal) = signals.next().await {
match signal {
SIGHUP | SIGTERM | SIGQUIT | SIGINT => {
if tx.send(Event::Quit(false)).is_err() {
break;
}
}
SIGCONT => {
tx.send(Event::Stop(false, None)).ok();
}
_ => {}
}
}
}))
}
fn spawn_crossterm_task(&mut self) -> JoinHandle<()> {
let tx = self.tx.clone();
let mut stop_rx = self.term_stop_rx.take().unwrap();
tokio::spawn(async move {
let mut reader = EventStream::new();
loop {
select! {
_ = &mut stop_rx => break,
Some(Ok(event)) = reader.next() => {
let event = match event {
// We need to check key event kind;
// otherwise event will be dispatched twice.
CrosstermEvent::Key(key @ KeyEvent { kind: KeyEventKind::Press, .. }) => Event::Key(key),
CrosstermEvent::Paste(str) => Event::Paste(str),
CrosstermEvent::Resize(cols, rows) => Event::Resize(cols, rows),
_ => continue,
};
if tx.send(event).is_err() {
break;
}
}
}
}
})
}
}

View file

@ -1,19 +0,0 @@
use ratatui::{buffer::Buffer, layout::Rect, widgets::{self, Widget}};
pub(super) struct Clear;
impl Widget for Clear {
fn render(self, mut area: Rect, buf: &mut Buffer) {
if area.x > 0 {
area.x -= 1;
area.width += 2;
}
if area.y > 0 {
area.y -= 1;
area.height += 2;
}
widgets::Clear.render(area, buf)
}
}

View file

@ -1,70 +0,0 @@
use core::{tasks::TASKS_PERCENT, Ctx};
use config::THEME;
use ratatui::{buffer::Buffer, layout::{self, Alignment, Constraint, Direction, Rect}, text::Line, widgets::{Block, BorderType, Borders, List, ListItem, Padding, Widget}};
use super::Clear;
pub(crate) struct Layout<'a> {
cx: &'a Ctx,
}
impl<'a> Layout<'a> {
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } }
pub(super) fn area(area: Rect) -> Rect {
let chunk = layout::Layout::new()
.direction(Direction::Vertical)
.constraints([
Constraint::Percentage((100 - TASKS_PERCENT) / 2),
Constraint::Percentage(TASKS_PERCENT),
Constraint::Percentage((100 - TASKS_PERCENT) / 2),
])
.split(area)[1];
layout::Layout::new()
.direction(Direction::Horizontal)
.constraints([
Constraint::Percentage((100 - TASKS_PERCENT) / 2),
Constraint::Percentage(TASKS_PERCENT),
Constraint::Percentage((100 - TASKS_PERCENT) / 2),
])
.split(chunk)[1]
}
}
impl<'a> Widget for Layout<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
let area = Self::area(area);
Clear.render(area, buf);
let block = Block::new()
.title({
let mut line = Line::from("Tasks");
line.patch_style(THEME.tasks.title.into());
line
})
.title_alignment(Alignment::Center)
.padding(Padding::new(0, 0, 1, 1))
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(THEME.tasks.border.into());
block.clone().render(area, buf);
let tasks = &self.cx.tasks;
let items = tasks
.paginate()
.iter()
.enumerate()
.map(|(i, v)| {
let mut item = ListItem::new(v.name.clone());
if i == tasks.cursor {
item = item.style(THEME.tasks.hovered.into());
}
item
})
.collect::<Vec<_>>();
List::new(items).render(block.inner(area), buf);
}
}

View file

@ -1,5 +0,0 @@
mod clear;
mod layout;
use clear::*;
pub(super) use layout::*;

View file

@ -1,48 +0,0 @@
use core::Ctx;
use config::THEME;
use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, widgets::{Block, Clear, Widget}};
use super::Side;
pub(crate) struct Which<'a> {
cx: &'a Ctx,
}
impl<'a> Which<'a> {
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } }
}
impl Widget for Which<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
let which = &self.cx.which;
let mut cands: (Vec<_>, Vec<_>, Vec<_>) = Default::default();
for (i, c) in which.cands.iter().enumerate() {
match i % 3 {
0 => cands.0.push(c),
1 => cands.1.push(c),
2 => cands.2.push(c),
_ => unreachable!(),
}
}
let height = cands.0.len() as u16 + 2;
let area = Rect {
x: 1,
y: area.height.saturating_sub(height + 2),
width: area.width.saturating_sub(2),
height,
};
let chunks = layout::Layout::new()
.direction(Direction::Horizontal)
.constraints([Constraint::Ratio(1, 3), Constraint::Ratio(1, 3), Constraint::Ratio(1, 3)])
.split(area);
Clear.render(area, buf);
Block::new().style(THEME.which.mask.into()).render(area, buf);
Side::new(which.times, cands.0).render(chunks[0], buf);
Side::new(which.times, cands.1).render(chunks[1], buf);
Side::new(which.times, cands.2).render(chunks[2], buf);
}
}

View file

@ -1,5 +0,0 @@
mod layout;
mod side;
pub(super) use layout::*;
use side::*;

View file

@ -1,44 +0,0 @@
use config::{keymap::Control, THEME};
use ratatui::{prelude::{Buffer, Rect}, text::{Line, Span}, widgets::{Block, List, ListItem, Padding, Widget}};
pub(super) struct Side<'a> {
times: usize,
cands: Vec<&'a Control>,
}
impl<'a> Side<'a> {
pub(super) fn new(times: usize, cands: Vec<&'a Control>) -> Self { Self { times, cands } }
}
impl Widget for Side<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
let items = self
.cands
.into_iter()
.map(|c| {
let mut spans = Vec::with_capacity(10);
// Keys
let keys = c.on[self.times..].iter().map(ToString::to_string).collect::<Vec<_>>();
spans.push(Span::raw(" ".repeat(10usize.saturating_sub(keys.join("").len()))));
spans.push(Span::styled(keys[0].clone(), THEME.which.cand.into()));
spans.extend(
keys.iter().skip(1).map(|k| Span::styled(k.to_string(), THEME.which.rest.into())),
);
// Separator
spans.push(Span::styled(
THEME.which.separator.to_string(),
THEME.which.separator_style.into(),
));
// Desc / Exec
spans.push(Span::styled(c.desc_or_exec(), THEME.which.desc.into()));
ListItem::new(Line::from(spans))
})
.collect::<Vec<_>>();
List::new(items).block(Block::new().padding(Padding::new(0, 1, 1, 1))).render(area, buf);
}
}

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

11
assets/yazi.desktop Normal file
View file

@ -0,0 +1,11 @@
[Desktop Entry]
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 %f
Type=Application
MimeType=inode/directory
Categories=System;FileManager;FileTools;ConsoleOnly
Keywords=File;Manager;Explorer;Browser;Launcher

View file

@ -1,28 +0,0 @@
[package]
name = "config"
version = "0.1.5"
edition = "2021"
[dependencies]
shared = { path = "../shared" }
# External dependencies
anyhow = "^1"
clap = { version = "^4", features = [ "derive" ] }
crossterm = "^0"
dirs = "^5"
futures = "^0"
glob = "^0"
indexmap = "^2"
md-5 = "^0"
ratatui = "^0"
serde = { version = "^1", features = [ "derive" ] }
shell-words = "^1"
toml = { version = "^0", features = [ "preserve_order" ] }
validator = { version = "^0", features = [ "derive" ] }
[build-dependencies]
clap = { version = "^4", features = [ "derive" ] }
clap_complete = "^4"
clap_complete_nushell = "^4"
clap_complete_fig = "^4"

View file

@ -1,24 +0,0 @@
#[path = "src/boot/cli.rs"]
mod cli;
use std::{fs, io};
use clap::CommandFactory;
use clap_complete::{generate_to, Shell};
fn main() -> io::Result<()> {
let cmd = &mut cli::Args::command();
let bin = "yazi";
let out = "completions";
fs::create_dir_all(out)?;
generate_to(Shell::Bash, cmd, bin, out)?;
generate_to(Shell::Fish, cmd, bin, out)?;
generate_to(Shell::Zsh, cmd, bin, out)?;
generate_to(Shell::Elvish, cmd, bin, out)?;
generate_to(Shell::PowerShell, cmd, bin, out)?;
generate_to(clap_complete_nushell::Nushell, cmd, bin, out)?;
generate_to(clap_complete_fig::Fig, cmd, bin, out)?;
Ok(())
}

View file

@ -1,239 +0,0 @@
[manager]
keymap = [
{ on = [ "<Esc>" ], exec = "escape", desc = "Exit visual mode, clear selected, or cancel search" },
{ on = [ "q" ], exec = "quit", desc = "Exit the process" },
{ on = [ "Q" ], exec = "quit --no-cwd-file", desc = "Exit the process without writing cwd-file" },
{ on = [ "<C-q>" ], exec = "close", desc = "Close the current tab, or quit if it is last tab" },
{ on = [ "<C-z>" ], exec = "suspend", desc = "Suspend the process" },
# Navigation
{ on = [ "k" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "j" ], exec = "arrow 1", desc = "Move cursor down" },
{ on = [ "K" ], exec = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [ "J" ], exec = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "<C-u>" ], exec = "arrow -50%", desc = "Move cursor up half page" },
{ on = [ "<C-d>" ], exec = "arrow 50%", desc = "Move cursor down half page" },
{ on = [ "<C-b>" ], exec = "arrow -100%", desc = "Move cursor up one page" },
{ on = [ "<C-f>" ], exec = "arrow 100%", desc = "Move cursor down one page" },
{ on = [ "h" ], exec = [ "leave", "escape --visual --select" ], desc = "Go back to the parent directory" },
{ on = [ "l" ], exec = [ "enter", "escape --visual --select" ], desc = "Enter the child directory" },
{ on = [ "H" ], exec = "back", desc = "Go back to the previous directory" },
{ on = [ "L" ], exec = "forward", desc = "Go forward to the next directory" },
{ on = [ "<A-k>" ], exec = "peek -5", desc = "Peek up 5 units in the preview" },
{ on = [ "<A-j>" ], exec = "peek 5", desc = "Peek down 5 units in the preview" },
{ on = [ "<Up>" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "<Down>" ], exec = "arrow 1", desc = "Move cursor down" },
{ on = [ "<Left>" ], exec = "leave", desc = "Go back to the parent directory" },
{ on = [ "<Right>" ], exec = "enter", desc = "Enter the child directory" },
{ on = [ "g", "g" ], exec = "arrow -99999999", desc = "Move cursor to the top" },
{ on = [ "G" ], exec = "arrow 99999999", desc = "Move cursor to the bottom" },
# Selection
{ on = [ "<Space>" ], exec = [ "select --state=none", "arrow 1" ], desc = "Toggle the current selection state" },
{ on = [ "v" ], exec = "visual_mode", desc = "Enter visual mode (selection mode)" },
{ on = [ "V" ], exec = "visual_mode --unset", desc = "Enter visual mode (unset mode)" },
{ on = [ "<C-a>" ], exec = "select_all --state=true", desc = "Select all files" },
{ on = [ "<C-r>" ], exec = "select_all --state=none", desc = "Inverse selection of all files" },
# Operation
{ on = [ "o" ], exec = "open", desc = "Open the selected files" },
{ on = [ "O" ], exec = "open --interactive", desc = "Open the selected files interactively" },
{ on = [ "<Enter>" ], exec = "open", desc = "Open the selected files" },
{ on = [ "<C-Enter>" ], exec = "open --interactive", desc = "Open the selected files interactively" },
{ on = [ "y" ], exec = [ "yank", "escape --visual --select" ], desc = "Copy the selected files" },
{ on = [ "x" ], exec = [ "yank --cut", "escape --visual --select" ], desc = "Cut the selected files" },
{ on = [ "p" ], exec = "paste", desc = "Paste the files" },
{ on = [ "P" ], exec = "paste --force", desc = "Paste the files (overwrite if the destination exists)" },
{ on = [ "-" ], exec = "link", desc = "Symlink the absolute path of files" },
{ on = [ "_" ], exec = "link --relative", desc = "Symlink the relative path of files" },
{ on = [ "d" ], exec = [ "remove", "escape --visual --select" ], desc = "Move the files to the trash" },
{ on = [ "D" ], exec = [ "remove --permanently", "escape --visual --select" ], desc = "Permanently delete the files" },
{ on = [ "a" ], exec = "create", desc = "Create a file or directory (ends with / for directories)" },
{ on = [ "r" ], exec = "rename", desc = "Rename a file or directory" },
{ on = [ ";" ], exec = "shell", desc = "Run a shell command" },
{ on = [ ":" ], exec = "shell --block", desc = "Run a shell command (block the UI until the command finishes)" },
{ on = [ "." ], exec = "hidden toggle", desc = "Toggle the visibility of hidden files" },
{ on = [ "s" ], exec = "search fd", desc = "Search files by name using fd" },
{ on = [ "S" ], exec = "search rg", desc = "Search files by content using ripgrep" },
{ on = [ "<C-s>" ], exec = "search none", desc = "Cancel the ongoing search" },
{ on = [ "z" ], exec = "jump zoxide", desc = "Jump to a directory using zoxide" },
{ on = [ "Z" ], exec = "jump fzf", desc = "Jump to a directory, or reveal a file using fzf" },
# Linemode
{ on = [ "m", "s" ], exec = "linemode size", desc = "Set linemode to size" },
{ on = [ "m", "p" ], exec = "linemode permissions", desc = "Set linemode to permissions" },
{ on = [ "m", "m" ], exec = "linemode mtime", desc = "Set linemode to mtime" },
{ on = [ "m", "n" ], exec = "linemode none", desc = "Set linemode to none" },
# Copy
{ on = [ "c", "c" ], exec = "copy path", desc = "Copy the absolute path" },
{ on = [ "c", "d" ], exec = "copy dirname", desc = "Copy the path of the parent directory" },
{ on = [ "c", "f" ], exec = "copy filename", desc = "Copy the name of the file" },
{ on = [ "c", "n" ], exec = "copy name_without_ext", desc = "Copy the name of the file without the extension" },
# Find
{ on = [ "/" ], exec = "find --smart" },
{ on = [ "?" ], exec = "find --previous --smart" },
{ on = [ "n" ], exec = "find_arrow" },
{ on = [ "N" ], exec = "find_arrow --previous" },
# Sorting
{ on = [ ",", "a" ], exec = "sort alphabetical --dir_first", desc = "Sort alphabetically" },
{ on = [ ",", "A" ], exec = "sort alphabetical --reverse --dir_first", desc = "Sort alphabetically (reverse)" },
{ on = [ ",", "c" ], exec = "sort created --dir_first", desc = "Sort by creation time" },
{ on = [ ",", "C" ], exec = "sort created --reverse --dir_first", desc = "Sort by creation time (reverse)" },
{ on = [ ",", "m" ], exec = "sort modified --dir_first", desc = "Sort by modified time" },
{ on = [ ",", "M" ], exec = "sort modified --reverse --dir_first", desc = "Sort by modified time (reverse)" },
{ on = [ ",", "n" ], exec = "sort natural --dir_first", desc = "Sort naturally" },
{ on = [ ",", "N" ], exec = "sort natural --reverse --dir_first", desc = "Sort naturally (reverse)" },
{ on = [ ",", "s" ], exec = "sort size --dir_first", desc = "Sort by size" },
{ on = [ ",", "S" ], exec = "sort size --reverse --dir_first", desc = "Sort by size (reverse)" },
# Tabs
{ on = [ "t" ], exec = "tab_create --current", desc = "Create a new tab using the current path" },
{ on = [ "1" ], exec = "tab_switch 0", desc = "Switch to the first tab" },
{ on = [ "2" ], exec = "tab_switch 1", desc = "Switch to the second tab" },
{ on = [ "3" ], exec = "tab_switch 2", desc = "Switch to the third tab" },
{ on = [ "4" ], exec = "tab_switch 3", desc = "Switch to the fourth tab" },
{ on = [ "5" ], exec = "tab_switch 4", desc = "Switch to the fifth tab" },
{ on = [ "6" ], exec = "tab_switch 5", desc = "Switch to the sixth tab" },
{ on = [ "7" ], exec = "tab_switch 6", desc = "Switch to the seventh tab" },
{ on = [ "8" ], exec = "tab_switch 7", desc = "Switch to the eighth tab" },
{ on = [ "9" ], exec = "tab_switch 8", desc = "Switch to the ninth tab" },
{ on = [ "[" ], exec = "tab_switch -1 --relative", desc = "Switch to the previous tab" },
{ on = [ "]" ], exec = "tab_switch 1 --relative", desc = "Switch to the next tab" },
{ on = [ "{" ], exec = "tab_swap -1", desc = "Swap the current tab with the previous tab" },
{ on = [ "}" ], exec = "tab_swap 1", desc = "Swap the current tab with the next tab" },
# Tasks
{ on = [ "w" ], exec = "tasks_show", desc = "Show the tasks manager" },
# Goto
{ on = [ "g", "h" ], exec = "cd ~", desc = "Go to the home directory" },
{ on = [ "g", "c" ], exec = "cd ~/.config", desc = "Go to the config directory" },
{ on = [ "g", "d" ], exec = "cd ~/Downloads", desc = "Go to the downloads directory" },
{ on = [ "g", "t" ], exec = "cd /tmp", desc = "Go to the temporary directory" },
{ on = [ "g", "<Space>" ], exec = "cd --interactive", desc = "Go to a directory interactively" },
# Help
{ on = [ "~" ], exec = "help", desc = "Open help" },
]
[tasks]
keymap = [
{ on = [ "<Esc>" ], exec = "close", desc = "Hide the task manager" },
{ on = [ "<C-q>" ], exec = "close", desc = "Hide the task manager" },
{ on = [ "w" ], exec = "close", desc = "Hide the task manager" },
{ on = [ "k" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "j" ], exec = "arrow 1", desc = "Move cursor down" },
{ on = [ "<Up>" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "<Down>" ], exec = "arrow 1", desc = "Move cursor down" },
{ on = [ "<Enter>" ], exec = "inspect", desc = "Inspect the task" },
{ on = [ "x" ], exec = "cancel", desc = "Cancel the task" },
{ on = [ "~" ], exec = "help", desc = "Open help" }
]
[select]
keymap = [
{ on = [ "<C-q>" ], exec = "close", desc = "Cancel selection" },
{ on = [ "<Esc>" ], exec = "close", desc = "Cancel selection" },
{ on = [ "<Enter>" ], exec = "close --submit", desc = "Submit the selection" },
{ on = [ "k" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "j" ], exec = "arrow 1", desc = "Move cursor down" },
{ on = [ "K" ], exec = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [ "J" ], exec = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "<Up>" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "<Down>" ], exec = "arrow 1", desc = "Move cursor down" },
{ on = [ "~" ], exec = "help", desc = "Open help" }
]
[input]
keymap = [
{ on = [ "<C-q>" ], exec = "close", desc = "Cancel input" },
{ on = [ "<Enter>" ], exec = "close --submit", desc = "Submit the input" },
{ on = [ "<Esc>" ], exec = "escape", desc = "Go back the normal mode, or cancel input" },
# Mode
{ on = [ "i" ], exec = "insert", desc = "Enter insert mode" },
{ on = [ "a" ], exec = "insert --append", desc = "Enter append mode" },
{ on = [ "v" ], exec = "visual", desc = "Enter visual mode" },
{ on = [ "V" ], exec = [ "move -999", "visual", "move 999" ], desc = "Enter visual mode and select all" },
# Navigation
{ on = [ "h" ], exec = "move -1", desc = "Move cursor left" },
{ on = [ "l" ], exec = "move 1", desc = "Move cursor right" },
{ on = [ "0" ], exec = "move -999", desc = "Move to the BOL" },
{ on = [ "$" ], exec = "move 999", desc = "Move to the EOL" },
{ on = [ "I" ], exec = [ "move -999", "insert" ], desc = "Move to the BOL, and enter insert mode" },
{ on = [ "A" ], exec = [ "move 999", "insert --append" ], desc = "Move to the EOL, and enter append mode" },
{ on = [ "<Left>" ], exec = "move -1", desc = "Move cursor left" },
{ on = [ "<Right>" ], exec = "move 1", desc = "Move cursor right" },
{ on = [ "b" ], exec = "backward", desc = "Move to the beginning of the previous word" },
{ on = [ "w" ], exec = "forward", desc = "Move to the beginning of the next word" },
{ on = [ "e" ], exec = "forward --end-of-word", desc = "Move to the end of the next word" },
# Deletion
{ on = [ "d" ], exec = "delete --cut", desc = "Cut the selected characters" },
{ on = [ "D" ], exec = [ "delete --cut", "move 999" ], desc = "Cut until the EOL" },
{ on = [ "c" ], exec = "delete --cut --insert", desc = "Cut the selected characters, and enter insert mode" },
{ on = [ "C" ], exec = [ "delete --cut --insert", "move 999" ], desc = "Cut until the EOL, and enter insert mode" },
{ on = [ "x" ], exec = [ "delete --cut", "move 1 --in-operating" ], desc = "Cut the current character" },
# Yank/Paste
{ on = [ "y" ], exec = "yank", desc = "Copy the selected characters" },
{ on = [ "p" ], exec = "paste", desc = "Paste the copied characters after the cursor" },
{ on = [ "P" ], exec = "paste --before", desc = "Paste the copied characters before the cursor" },
# Undo/Redo
{ on = [ "u" ], exec = "undo", desc = "Undo the last operation" },
{ on = [ "<C-r>" ], exec = "redo", desc = "Redo the last operation" },
# Help
{ on = [ "~" ], exec = "help", desc = "Open help" }
]
[help]
keymap = [
{ on = [ "<Esc>" ], exec = "escape", desc = "Clear the filter, or hide the help" },
{ on = [ "q" ], exec = "close", desc = "Exit the process" },
{ on = [ "<C-q>" ], exec = "close", desc = "Hide the help" },
# Navigation
{ on = [ "k" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "j" ], exec = "arrow 1", desc = "Move cursor down" },
{ on = [ "K" ], exec = "arrow -5", desc = "Move cursor up 5 lines" },
{ on = [ "J" ], exec = "arrow 5", desc = "Move cursor down 5 lines" },
{ on = [ "<Up>" ], exec = "arrow -1", desc = "Move cursor up" },
{ on = [ "<Down>" ], exec = "arrow 1", desc = "Move cursor down" },
# Filtering
{ on = [ "/" ], exec = "filter", desc = "Apply a filter for the help items" },
]

View file

@ -1,244 +0,0 @@
# vim:fileencoding=utf-8:foldmethod=marker
# : Manager {{{
[manager]
cwd = { fg = "cyan" }
# Hovered
hovered = { fg = "black", bg = "lightblue" }
preview_hovered = { underline = true }
# Find
find_keyword = { fg = "yellow", italic = true }
find_position = { fg = "magenta", bg = "reset", italic = true }
# Marker
marker_selected = { fg = "lightgreen", bg = "lightgreen" }
marker_copied = { fg = "lightyellow", bg = "lightyellow" }
marker_cut = { fg = "lightred", bg = "lightred" }
# Tab
tab_active = { fg = "black", bg = "lightblue" }
tab_inactive = { fg = "white", bg = "darkgray" }
tab_width = 1
# Border
border_symbol = "│"
border_style = { fg = "gray" }
# Offset
folder_offset = [ 1, 0, 1, 0 ]
preview_offset = [ 1, 1, 1, 1 ]
# Highlighting
syntect_theme = ""
# : }}}
# : Status {{{
[status]
separator_open = ""
separator_close = ""
separator_style = { fg = "darkgray", bg = "darkgray" }
# Mode
mode_normal = { fg = "black", bg = "lightblue", bold = true }
mode_select = { fg = "black", bg = "lightgreen", bold = true }
mode_unset = { fg = "black", bg = "lightmagenta", bold = true }
# Progress
progress_label = { bold = true }
progress_normal = { fg = "blue", bg = "black" }
progress_error = { fg = "red", bg = "black" }
# Permissions
permissions_t = { fg = "lightgreen" }
permissions_r = { fg = "lightyellow" }
permissions_w = { fg = "lightred" }
permissions_x = { fg = "lightcyan" }
permissions_s = { fg = "darkgray" }
# : }}}
# : Input {{{
[input]
border = { fg = "blue" }
title = {}
value = {}
selected = { reversed = true }
# : }}}
# : Select {{{
[select]
border = { fg = "blue" }
active = { fg = "magenta" }
inactive = {}
# : }}}
# : Tasks {{{
[tasks]
border = { fg = "blue" }
title = {}
hovered = { underline = true }
# : }}}
# : Which {{{
[which]
mask = { bg = "black" }
cand = { fg = "lightcyan" }
rest = { fg = "darkgray" }
desc = { fg = "magenta" }
separator = "  "
separator_style = { fg = "darkgray" }
# : }}}
# : Help {{{
[help]
on = { fg = "magenta" }
exec = { fg = "cyan" }
desc = { fg = "gray" }
hovered = { bg = "darkgray", bold = true }
footer = { fg = "black", bg = "white" }
# : }}}
# : File-specific styles {{{
[filetype]
rules = [
# Images
{ mime = "image/*", fg = "cyan" },
# Videos
{ mime = "video/*", fg = "yellow" },
{ mime = "audio/*", fg = "yellow" },
# Archives
{ mime = "application/zip", fg = "magenta" },
{ mime = "application/gzip", fg = "magenta" },
{ mime = "application/x-tar", fg = "magenta" },
{ mime = "application/x-bzip", fg = "magenta" },
{ mime = "application/x-bzip2", fg = "magenta" },
{ mime = "application/x-7z-compressed", fg = "magenta" },
{ mime = "application/x-rar", fg = "magenta" },
# Fallback
# { name = "*", fg = "white" },
{ name = "*/", fg = "blue" }
]
[icons]
"Desktop/" = ""
"Documents/" = ""
"Downloads/" = ""
"Pictures/" = ""
"Music/" = ""
"Movies/" = ""
"Videos/" = ""
"Public/" = ""
"Library/" = ""
"Development/" = ""
".config/" = ""
# Git
".git/" = ""
".gitignore" = ""
".gitmodules" = ""
".gitattributes" = ""
# Dotfiles
".DS_Store" = ""
".bashrc" = ""
".bashprofile" = ""
".zshrc" = ""
".zshenv" = ""
".zprofile" = ""
".vimrc" = ""
# Text
"*.txt" = ""
"*.md" = ""
# Archives
"*.zip" = ""
"*.tar" = ""
"*.gz" = ""
"*.7z" = ""
# Audio
"*.mp3" = ""
"*.flac" = ""
"*.wav" = ""
# Movies
"*.mp4" = ""
"*.mkv" = ""
"*.avi" = ""
"*.mov" = ""
# Images
"*.jpg" = ""
"*.jpeg" = ""
"*.png" = ""
"*.gif" = ""
"*.webp" = ""
"*.avif" = ""
"*.bmp" = ""
"*.ico" = ""
"*.svg" = ""
# Programming
"*.c" = ""
"*.cpp" = ""
"*.h" = ""
"*.hpp" = ""
"*.rs" = ""
"*.go" = ""
"*.py" = ""
"*.js" = ""
"*.ts" = ""
"*.tsx" = ""
"*.jsx" = ""
"*.rb" = ""
"*.php" = ""
"*.java" = ""
"*.sh" = ""
"*.fish" = ""
"*.swift" = ""
"*.vim" = ""
"*.lua" = ""
"*.html" = ""
"*.css" = ""
"*.scss" = ""
"*.json" = ""
"*.toml" = ""
"*.yml" = ""
"*.yaml" = ""
"*.ini" = ""
"*.conf" = ""
# Default
"*" = ""
"*/" = ""
# : }}}

View file

@ -1,75 +0,0 @@
[manager]
layout = [ 1, 4, 3 ]
sort_by = "modified"
sort_sensitive = true
sort_reverse = true
sort_dir_first = true
linemode = "none"
show_hidden = false
show_symlink = true
[preview]
tab_size = 2
max_width = 600
max_height = 900
cache_dir = ""
[opener]
edit = [
{ exec = '$EDITOR "$@"', block = true, for = "unix" },
{ exec = 'code "%*"', orphan = true, for = "windows" },
]
open = [
{ exec = 'xdg-open "$@"', desc = "Open", for = "linux" },
{ exec = 'open "$@"', desc = "Open", for = "macos" },
{ exec = 'start "%1"', orphan = true, desc = "Open", for = "windows" }
]
reveal = [
{ exec = 'open -R "$1"', desc = "Reveal", for = "macos" },
{ exec = 'explorer /select,%1', orphan = true, desc = "Reveal", for = "windows" },
{ exec = '''exiftool "$1"; echo "Press enter to exit"; read''', block = true, desc = "Show EXIF", for = "unix" },
]
extract = [
{ exec = 'unar "$1"', desc = "Extract here", for = "unix" },
{ exec = 'unar "%1"', desc = "Extract here", for = "windows" },
]
play = [
{ exec = 'mpv "$@"', orphan = true, for = "unix" },
{ exec = 'mpv "%1"', orphan = true, for = "windows" },
{ exec = '''mediainfo "$1"; echo "Press enter to exit"; read''', block = true, desc = "Show media info", for = "unix" },
]
[open]
rules = [
{ name = "*/", use = [ "edit", "open", "reveal" ] },
{ mime = "text/*", use = [ "edit", "reveal" ] },
{ mime = "image/*", use = [ "open", "reveal" ] },
{ mime = "video/*", use = [ "play", "reveal" ] },
{ mime = "audio/*", use = [ "play", "reveal" ] },
{ mime = "inode/x-empty", use = [ "edit", "reveal" ] },
{ mime = "application/json", use = [ "edit", "reveal" ] },
{ mime = "*/javascript", use = [ "edit", "reveal" ] },
{ mime = "application/zip", use = [ "extract", "reveal" ] },
{ mime = "application/gzip", use = [ "extract", "reveal" ] },
{ mime = "application/x-tar", use = [ "extract", "reveal" ] },
{ mime = "application/x-bzip", use = [ "extract", "reveal" ] },
{ mime = "application/x-bzip2", use = [ "extract", "reveal" ] },
{ mime = "application/x-7z-compressed", use = [ "extract", "reveal" ] },
{ mime = "application/x-rar", use = [ "extract", "reveal" ] },
{ mime = "*", use = [ "open", "reveal" ] },
]
[tasks]
micro_workers = 5
macro_workers = 10
bizarre_retry = 5
[plugins]
preload = []
[log]
enabled = false

View file

@ -1,54 +0,0 @@
use std::{env, fs, path::PathBuf, process};
use clap::Parser;
use shared::expand_path;
use super::cli::Args;
use crate::{Xdg, PREVIEW};
#[derive(Debug)]
pub struct Boot {
pub cwd: PathBuf,
pub state_dir: PathBuf,
pub cwd_file: Option<PathBuf>,
pub chooser_file: Option<PathBuf>,
}
impl Default for Boot {
fn default() -> Self {
let args = Args::parse();
let cwd = args.cwd.map(expand_path).filter(|p| p.is_dir()).or_else(|| env::current_dir().ok());
let boot = Self {
cwd: cwd.unwrap_or("/".into()),
state_dir: Xdg::state_dir().unwrap(),
cwd_file: args.cwd_file,
chooser_file: args.chooser_file,
};
if !boot.state_dir.is_dir() {
fs::create_dir_all(&boot.state_dir).unwrap();
}
if !PREVIEW.cache_dir.is_dir() {
fs::create_dir(&PREVIEW.cache_dir).unwrap();
}
if args.clear_cache {
if PREVIEW.cache_dir == Xdg::cache_dir() {
println!("Clearing cache directory: \n{:?}", PREVIEW.cache_dir);
fs::remove_dir_all(&PREVIEW.cache_dir).unwrap();
} else {
println!(
"You've changed the default cache directory, for your data's safety, please clear it manually: \n{:?}",
PREVIEW.cache_dir
);
}
process::exit(0);
}
boot
}
}

View file

@ -1,22 +0,0 @@
use std::path::PathBuf;
use clap::{command, Parser};
#[derive(Debug, Parser)]
#[command(name = "yazi", version)]
pub(super) struct Args {
/// Set the current working directory
#[arg(index = 1)]
pub cwd: Option<PathBuf>,
/// Write the cwd on exit to this file
#[arg(long)]
pub cwd_file: Option<PathBuf>,
/// Write the selected files on open emitted by the chooser mode
#[arg(long)]
pub chooser_file: Option<PathBuf>,
/// Clear the cache directory
#[arg(long, action)]
pub clear_cache: bool,
}

View file

@ -1,4 +0,0 @@
mod boot;
mod cli;
pub use boot::*;

View file

@ -1,41 +0,0 @@
use std::borrow::Cow;
use serde::Deserialize;
use super::{Exec, Key};
#[derive(Clone, Debug, Deserialize)]
pub struct Control {
pub on: Vec<Key>,
#[serde(deserialize_with = "Exec::deserialize")]
pub exec: Vec<Exec>,
pub desc: Option<String>,
}
impl Control {
#[inline]
pub fn to_call(&self) -> Vec<Exec> { self.exec.clone() }
}
impl Control {
#[inline]
pub fn on(&self) -> String { self.on.iter().map(ToString::to_string).collect() }
#[inline]
pub fn exec(&self) -> String {
self.exec.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("; ")
}
#[inline]
pub fn desc_or_exec(&self) -> Cow<str> {
if let Some(ref s) = self.desc { Cow::Borrowed(s) } else { self.exec().into() }
}
#[inline]
pub fn contains(&self, s: &str) -> bool {
let s = s.to_lowercase();
self.desc.as_ref().map(|d| d.to_lowercase().contains(&s)) == Some(true)
|| self.exec().to_lowercase().contains(&s)
|| self.on().to_lowercase().contains(&s)
}
}

View file

@ -1,111 +0,0 @@
use std::{collections::BTreeMap, fmt::{self, Debug, Display}};
use anyhow::bail;
use serde::{de::{self, Visitor}, Deserializer};
#[derive(Clone, Debug)]
pub struct Exec {
pub cmd: String,
pub args: Vec<String>,
pub named: BTreeMap<String, String>,
}
impl TryFrom<&str> for Exec {
type Error = anyhow::Error;
fn try_from(s: &str) -> Result<Self, Self::Error> {
let s = shell_words::split(s)?;
if s.is_empty() {
bail!("`exec` cannot be empty");
}
let mut exec = Self { cmd: s[0].clone(), args: Vec::new(), named: BTreeMap::new() };
for arg in s.into_iter().skip(1) {
if arg.starts_with("--") {
let mut arg = arg.splitn(2, '=');
let key = arg.next().unwrap().trim_start_matches('-');
let val = arg.next().unwrap_or("").to_string();
exec.named.insert(key.to_string(), val);
} else {
exec.args.push(arg);
}
}
Ok(exec)
}
}
impl Display for Exec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.cmd)?;
if !self.args.is_empty() {
write!(f, " {}", self.args.join(" "))?;
}
for (k, v) in &self.named {
write!(f, " --{k}")?;
if !v.is_empty() {
write!(f, "={v}")?;
}
}
Ok(())
}
}
impl Exec {
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Exec>, D::Error>
where
D: Deserializer<'de>,
{
struct ExecVisitor;
impl<'de> Visitor<'de> for ExecVisitor {
type Value = Vec<Exec>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a exec string, e.g. tab_switch 0")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut execs = Vec::new();
while let Some(value) = &seq.next_element::<String>()? {
execs.push(Exec::try_from(value.as_str()).map_err(de::Error::custom)?);
}
Ok(execs)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![Exec::try_from(value).map_err(de::Error::custom)?])
}
}
deserializer.deserialize_any(ExecVisitor)
}
}
impl Exec {
#[inline]
pub fn call(cwd: &str, args: Vec<String>) -> Self {
Exec { cmd: cwd.to_owned(), args, named: Default::default() }
}
#[inline]
pub fn call_named(cwd: &str, named: BTreeMap<String, String>) -> Self {
Exec { cmd: cwd.to_owned(), args: Default::default(), named }
}
#[inline]
pub fn vec(self) -> Vec<Self> { vec![self] }
#[inline]
pub fn with_bool(mut self, name: &str, state: bool) -> Self {
if state {
self.named.insert(name.to_string(), "".to_string());
}
self
}
}

View file

@ -1,184 +0,0 @@
use anyhow::bail;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use serde::Deserialize;
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(try_from = "String")]
pub struct Key {
pub code: KeyCode,
pub shift: bool,
pub ctrl: bool,
pub alt: bool,
}
impl Key {
#[inline]
pub fn plain(&self) -> Option<char> {
match self.code {
KeyCode::Char(c) if !self.ctrl && !self.alt => Some(c),
_ => None,
}
}
#[inline]
pub fn is_enter(&self) -> bool {
matches!(self, Key { code: KeyCode::Enter, shift: false, ctrl: false, alt: false })
}
}
impl Default for Key {
fn default() -> Self { Self { code: KeyCode::Null, shift: false, ctrl: false, alt: false } }
}
impl From<KeyEvent> for Key {
fn from(value: KeyEvent) -> Self {
// For alphabet:
// Unix : <S-a> => Char("A") + SHIFT
// Windows : <S-a> => Char("A") + SHIFT
//
// For non-alphabet:
// Unix : <S-`> => Char("~") + NULL
// Windows : <S-`> => Char("~") + SHIFT
//
// So we detect `Char("~") + SHIFT`, and change it to `Char("~") + NULL`
// for consistent behavior between OSs.
let shift = match (value.code, value.modifiers) {
(KeyCode::Char(c), _) => c.is_ascii_uppercase(),
(KeyCode::BackTab, _) => false,
(_, m) => m.contains(KeyModifiers::SHIFT),
};
Self {
code: value.code,
shift,
ctrl: value.modifiers.contains(KeyModifiers::CONTROL),
alt: value.modifiers.contains(KeyModifiers::ALT),
}
}
}
impl TryFrom<String> for Key {
type Error = anyhow::Error;
fn try_from(s: String) -> Result<Self, Self::Error> {
if s.is_empty() {
bail!("empty key")
}
let mut key = Self::default();
if !s.starts_with('<') || !s.ends_with('>') {
let c = s.chars().next().unwrap();
key.code = KeyCode::Char(c);
key.shift = c.is_ascii_uppercase();
return Ok(key);
}
let mut it = s[1..s.len() - 1].split_inclusive('-').peekable();
while let Some(x) = it.next() {
match x {
"S-" => key.shift = true,
"C-" => key.ctrl = true,
"A-" => key.alt = true,
"Space" => key.code = KeyCode::Char(' '),
"Backspace" => key.code = KeyCode::Backspace,
"Enter" => key.code = KeyCode::Enter,
"Left" => key.code = KeyCode::Left,
"Right" => key.code = KeyCode::Right,
"Up" => key.code = KeyCode::Up,
"Down" => key.code = KeyCode::Down,
"Home" => key.code = KeyCode::Home,
"End" => key.code = KeyCode::End,
"PageUp" => key.code = KeyCode::PageUp,
"PageDown" => key.code = KeyCode::PageDown,
"Tab" => key.code = KeyCode::Tab,
"BackTab" => key.code = KeyCode::BackTab,
"Delete" => key.code = KeyCode::Delete,
"Insert" => key.code = KeyCode::Insert,
"F1" => key.code = KeyCode::F(1),
"F2" => key.code = KeyCode::F(2),
"F3" => key.code = KeyCode::F(3),
"F4" => key.code = KeyCode::F(4),
"F5" => key.code = KeyCode::F(5),
"F6" => key.code = KeyCode::F(6),
"F7" => key.code = KeyCode::F(7),
"F8" => key.code = KeyCode::F(8),
"F9" => key.code = KeyCode::F(9),
"F10" => key.code = KeyCode::F(10),
"F11" => key.code = KeyCode::F(11),
"F12" => key.code = KeyCode::F(12),
"Esc" => key.code = KeyCode::Esc,
c if it.peek().is_none() => {
key.code = KeyCode::Char(c.chars().next().unwrap());
}
k => bail!("unknown key: {k}"),
}
}
if key.code == KeyCode::Null {
bail!("empty key")
}
Ok(key)
}
}
impl ToString for Key {
fn to_string(&self) -> String {
if let Some(c) = self.plain() {
let c = if self.shift { c.to_ascii_uppercase() } else { c };
return if c == ' ' { "<Space>".to_string() } else { c.to_string() };
}
let mut s = "<".to_string();
if self.ctrl {
s += "C-";
}
if self.alt {
s += "A-";
}
if self.shift && !matches!(self.code, KeyCode::Char(_)) {
s += "S-";
}
let code = match self.code {
KeyCode::Backspace => "Backspace",
KeyCode::Enter => "Enter",
KeyCode::Left => "Left",
KeyCode::Right => "Right",
KeyCode::Up => "Up",
KeyCode::Down => "Down",
KeyCode::Home => "Home",
KeyCode::End => "End",
KeyCode::PageUp => "PageUp",
KeyCode::PageDown => "PageDown",
KeyCode::Tab => "Tab",
KeyCode::BackTab => "BackTab",
KeyCode::Delete => "Delete",
KeyCode::Insert => "Insert",
KeyCode::F(1) => "F1",
KeyCode::F(2) => "F2",
KeyCode::F(3) => "F3",
KeyCode::F(4) => "F4",
KeyCode::F(5) => "F5",
KeyCode::F(6) => "F6",
KeyCode::F(7) => "F7",
KeyCode::F(8) => "F8",
KeyCode::F(9) => "F9",
KeyCode::F(10) => "F10",
KeyCode::F(11) => "F11",
KeyCode::F(12) => "F12",
KeyCode::Esc => "Esc",
KeyCode::Char(' ') => "Space",
KeyCode::Char(c) => {
s.push(if self.shift { c.to_ascii_uppercase() } else { c });
""
}
_ => "Unknown",
};
s + code + ">"
}
}

View file

@ -1,86 +0,0 @@
use std::fmt::{self, Display};
use serde::{Deserialize, Deserializer};
use super::Control;
use crate::MERGED_KEYMAP;
#[derive(Debug)]
pub struct Keymap {
pub manager: Vec<Control>,
pub tasks: Vec<Control>,
pub select: Vec<Control>,
pub input: Vec<Control>,
pub help: Vec<Control>,
}
impl<'de> Deserialize<'de> for Keymap {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Shadow {
manager: Inner,
tasks: Inner,
select: Inner,
input: Inner,
help: Inner,
}
#[derive(Deserialize)]
struct Inner {
keymap: Vec<Control>,
}
let shadow = Shadow::deserialize(deserializer)?;
Ok(Self {
manager: shadow.manager.keymap,
tasks: shadow.tasks.keymap,
select: shadow.select.keymap,
input: shadow.input.keymap,
help: shadow.help.keymap,
})
}
}
impl Default for Keymap {
fn default() -> Self { toml::from_str(&MERGED_KEYMAP).unwrap() }
}
impl Keymap {
#[inline]
pub fn get(&self, layer: KeymapLayer) -> &Vec<Control> {
match layer {
KeymapLayer::Manager => &self.manager,
KeymapLayer::Tasks => &self.tasks,
KeymapLayer::Select => &self.select,
KeymapLayer::Input => &self.input,
KeymapLayer::Help => &self.help,
KeymapLayer::Which => unreachable!(),
}
}
}
#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
pub enum KeymapLayer {
#[default]
Manager,
Tasks,
Select,
Input,
Help,
Which,
}
impl Display for KeymapLayer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
KeymapLayer::Manager => write!(f, "manager"),
KeymapLayer::Tasks => write!(f, "tasks"),
KeymapLayer::Select => write!(f, "select"),
KeymapLayer::Input => write!(f, "input"),
KeymapLayer::Help => write!(f, "help"),
KeymapLayer::Which => write!(f, "which"),
}
}
}

View file

@ -1,9 +0,0 @@
mod control;
mod exec;
mod key;
mod keymap;
pub use control::*;
pub use exec::*;
pub use key::*;
pub use keymap::*;

View file

@ -1,53 +0,0 @@
#![allow(clippy::module_inception)]
use shared::RoCell;
mod boot;
pub mod keymap;
mod log;
pub mod manager;
pub mod open;
mod pattern;
pub mod plugins;
mod preset;
pub mod preview;
mod tasks;
pub mod theme;
mod validation;
mod xdg;
pub(crate) use pattern::*;
pub(crate) use preset::*;
pub(crate) use xdg::*;
static MERGED_KEYMAP: RoCell<String> = RoCell::new();
static MERGED_THEME: RoCell<String> = RoCell::new();
static MERGED_YAZI: RoCell<String> = RoCell::new();
pub static KEYMAP: RoCell<keymap::Keymap> = RoCell::new();
pub static LOG: RoCell<log::Log> = RoCell::new();
pub static MANAGER: RoCell<manager::Manager> = RoCell::new();
pub static OPEN: RoCell<open::Open> = RoCell::new();
pub static PLUGINS: RoCell<plugins::Plugins> = RoCell::new();
pub static PREVIEW: RoCell<preview::Preview> = RoCell::new();
pub static TASKS: RoCell<tasks::Tasks> = RoCell::new();
pub static THEME: RoCell<theme::Theme> = RoCell::new();
pub static BOOT: RoCell<boot::Boot> = RoCell::new();
pub fn init() {
MERGED_KEYMAP.with(Preset::keymap);
MERGED_THEME.with(Preset::theme);
MERGED_YAZI.with(Preset::yazi);
KEYMAP.with(Default::default);
LOG.with(Default::default);
MANAGER.with(Default::default);
OPEN.with(Default::default);
PLUGINS.with(Default::default);
PREVIEW.with(Default::default);
TASKS.with(Default::default);
THEME.with(Default::default);
BOOT.with(Default::default);
}

View file

@ -1,32 +0,0 @@
use serde::{Deserialize, Deserializer};
use crate::MERGED_YAZI;
#[derive(Debug)]
pub struct Log {
pub enabled: bool,
}
impl Default for Log {
fn default() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
}
impl<'de> Deserialize<'de> for Log {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Outer {
log: Shadow,
}
#[derive(Deserialize)]
struct Shadow {
enabled: bool,
}
let outer = Outer::deserialize(deserializer)?;
Ok(Self { enabled: outer.log.enabled })
}
}

View file

@ -1,3 +0,0 @@
mod log;
pub use log::*;

View file

@ -1,71 +0,0 @@
use anyhow::bail;
use crossterm::terminal::WindowSize;
use ratatui::{prelude::Rect, widgets::{Block, Padding}};
use serde::{Deserialize, Serialize};
use shared::Term;
use crate::THEME;
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(try_from = "Vec<u32>")]
pub struct ManagerLayout {
pub parent: u32,
pub current: u32,
pub preview: u32,
pub all: u32,
}
impl TryFrom<Vec<u32>> for ManagerLayout {
type Error = anyhow::Error;
fn try_from(ratio: Vec<u32>) -> Result<Self, Self::Error> {
if ratio.len() != 3 {
bail!("invalid layout ratio: {:?}", ratio);
}
if ratio.iter().all(|&r| r == 0) {
bail!("at least one layout ratio must be non-zero: {:?}", ratio);
}
Ok(Self {
parent: ratio[0],
current: ratio[1],
preview: ratio[2],
all: ratio[0] + ratio[1] + ratio[2],
})
}
}
impl ManagerLayout {
pub fn preview_rect(&self) -> Rect {
let WindowSize { columns, rows, .. } = Term::size();
let width = (columns as u32 * self.preview) as f64 / self.all as f64;
let width = if width.fract() > 0.5 { width.ceil() as u16 } else { width.floor() as u16 };
let offset = THEME.manager.preview_offset;
Block::default().padding(Padding::new(offset.3, offset.1, offset.0, offset.2)).inner(Rect {
x: columns.saturating_sub(width),
y: 0,
width,
height: rows,
})
}
#[inline]
pub fn preview_height(&self) -> usize { self.preview_rect().height as usize }
pub fn folder_rect(&self) -> Rect {
let WindowSize { columns, rows, .. } = Term::size();
let offset = THEME.manager.folder_offset;
Block::default().padding(Padding::new(offset.3, offset.1, offset.0, offset.2)).inner(Rect {
x: (columns as u32 * self.parent / self.all) as u16,
y: 0,
width: (columns as u32 * self.current / self.all) as u16,
height: rows,
})
}
#[inline]
pub fn folder_height(&self) -> usize { self.folder_rect().height as usize }
}

View file

@ -1,36 +0,0 @@
use serde::{Deserialize, Serialize};
use validator::Validate;
use super::{ManagerLayout, SortBy};
use crate::{validation::check_validation, MERGED_YAZI};
#[derive(Debug, Deserialize, Serialize, Validate)]
pub struct Manager {
pub layout: ManagerLayout,
// Sorting
pub sort_by: SortBy,
pub sort_sensitive: bool,
pub sort_reverse: bool,
pub sort_dir_first: bool,
// Display
#[validate(length(min = 1, max = 20, message = "must be between 1 and 20 characters"))]
pub linemode: String,
pub show_hidden: bool,
pub show_symlink: bool,
}
impl Default for Manager {
fn default() -> Self {
#[derive(Deserialize)]
struct Outer {
manager: Manager,
}
let manager = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().manager;
check_validation(manager.validate());
manager
}
}

View file

@ -1,7 +0,0 @@
mod layout;
mod manager;
mod sorting;
pub use layout::*;
pub use manager::*;
pub use sorting::*;

View file

@ -1,52 +0,0 @@
use std::str::FromStr;
use anyhow::bail;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(try_from = "String")]
pub enum SortBy {
#[default]
None,
Alphabetical,
Created,
Modified,
Natural,
Size,
}
impl FromStr for SortBy {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"none" => Self::None,
"alphabetical" => Self::Alphabetical,
"created" => Self::Created,
"modified" => Self::Modified,
"natural" => Self::Natural,
"size" => Self::Size,
_ => bail!("invalid sort_by value: {s}"),
})
}
}
impl TryFrom<String> for SortBy {
type Error = anyhow::Error;
fn try_from(s: String) -> Result<Self, Self::Error> { Self::from_str(&s) }
}
impl ToString for SortBy {
fn to_string(&self) -> String {
match self {
Self::None => "none",
Self::Alphabetical => "alphabetical",
Self::Created => "created",
Self::Modified => "modified",
Self::Natural => "natural",
Self::Size => "size",
}
.to_string()
}
}

View file

@ -1,7 +0,0 @@
mod open;
mod opener;
mod rule;
pub use open::*;
pub use opener::*;
use rule::*;

View file

@ -1,84 +0,0 @@
use std::{collections::BTreeMap, path::Path};
use indexmap::IndexSet;
use serde::{Deserialize, Deserializer};
use shared::MIME_DIR;
use super::Opener;
use crate::{open::OpenRule, MERGED_YAZI};
#[derive(Debug)]
pub struct Open {
rules: Vec<OpenRule>,
openers: BTreeMap<String, IndexSet<Opener>>,
}
impl Default for Open {
fn default() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
}
impl Open {
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<IndexSet<&Opener>>
where
P: AsRef<Path>,
M: AsRef<str>,
{
let is_folder = Some(mime.as_ref() == MIME_DIR);
self.rules.iter().find_map(|rule| {
if rule.mime.as_ref().is_some_and(|m| m.matches(&mime))
|| rule.name.as_ref().is_some_and(|n| n.match_path(&path, is_folder))
{
let openers = rule
.use_
.iter()
.filter_map(|use_| self.openers.get(use_))
.flatten()
.collect::<IndexSet<_>>();
if openers.is_empty() { None } else { Some(openers) }
} else {
None
}
})
}
#[inline]
pub fn block_opener<P, M>(&self, path: P, mime: M) -> Option<&Opener>
where
P: AsRef<Path>,
M: AsRef<str>,
{
self.openers(path, mime).and_then(|o| o.into_iter().find(|o| o.block))
}
pub fn common_openers(&self, targets: &[(impl AsRef<Path>, impl AsRef<str>)]) -> Vec<&Opener> {
let grouped: Vec<_> = targets.iter().filter_map(|(p, m)| self.openers(p, m)).collect();
let flat: IndexSet<_> = grouped.iter().flatten().copied().collect();
flat.into_iter().filter(|&o| grouped.iter().all(|g| g.contains(o))).collect()
}
}
impl<'de> Deserialize<'de> for Open {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Outer {
opener: BTreeMap<String, Vec<Opener>>,
open: OuterOpen,
}
#[derive(Deserialize)]
struct OuterOpen {
rules: Vec<OpenRule>,
}
let outer = Outer::deserialize(deserializer)?;
let openers = outer
.opener
.into_iter()
.map(|(k, v)| (k, v.into_iter().filter_map(|o| o.take()).collect::<IndexSet<_>>()))
.collect();
Ok(Self { rules: outer.open.rules, openers })
}
}

View file

@ -1,80 +0,0 @@
use serde::{Deserialize, Deserializer};
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Opener {
pub exec: String,
pub block: bool,
pub orphan: bool,
pub desc: String,
pub for_: Option<String>,
pub spread: bool,
}
impl Opener {
pub fn take(mut self) -> Option<Self> {
if let Some(for_) = self.for_.take() {
match for_.as_bytes() {
b"unix" if cfg!(unix) => {}
b"windows" if cfg!(windows) => {}
b"linux" if cfg!(target_os = "linux") => {}
b"macos" if cfg!(target_os = "macos") => {}
_ => return None,
}
}
Some(self)
}
}
impl<'de> Deserialize<'de> for Opener {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
pub struct Shadow {
exec: String,
#[serde(default)]
block: bool,
#[serde(default)]
orphan: bool,
desc: Option<String>,
#[serde(rename = "for")]
for_: Option<String>,
// TODO: remove this when v1.0.5 is released --
display_name: Option<String>,
// TODO: -- remove this when v1.0.5 is released
}
let mut shadow = Shadow::deserialize(deserializer)?;
if shadow.exec.is_empty() {
return Err(serde::de::Error::custom("`exec` cannot be empty"));
}
// TODO: remove this when v1.0.5 is released --
if shadow.display_name.is_some() {
println!(
"WARNING: `display_name` is deprecated and will be removed in Yazi v1.0.6. Use `desc` instead.\ne.g. {}\n\n",
r#"{ exec = 'nvim "$@"', display_name = "Edit" } ==> { exec = 'nvim "$@"', desc = "Edit" }"#
);
}
if shadow.display_name.is_some() && shadow.desc.is_none() {
shadow.desc = shadow.display_name.clone();
}
// TODO: -- remove this when v1.0.5 is released
let desc =
shadow.desc.unwrap_or_else(|| shadow.exec.split_whitespace().next().unwrap().to_string());
let spread =
shadow.exec.contains("$@") || shadow.exec.contains("%*") || shadow.exec.contains("$*");
Ok(Self {
exec: shadow.exec,
block: shadow.block,
orphan: shadow.orphan,
desc,
for_: shadow.for_,
spread,
})
}
}

View file

@ -1,58 +0,0 @@
use std::fmt;
use serde::{de::{self, Visitor}, Deserialize, Deserializer};
use crate::pattern::Pattern;
#[derive(Debug, Deserialize)]
pub(super) struct OpenRule {
pub(super) name: Option<Pattern>,
pub(super) mime: Option<Pattern>,
#[serde(rename = "use")]
#[serde(deserialize_with = "OpenRule::deserialize")]
pub(super) use_: Vec<String>,
}
impl OpenRule {
fn deserialize<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
D: Deserializer<'de>,
{
struct UseVisitor;
impl<'de> Visitor<'de> for UseVisitor {
type Value = Vec<String>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string, or array of strings")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut uses = Vec::new();
while let Some(use_) = seq.next_element::<String>()? {
uses.push(use_);
}
Ok(uses)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![value.to_owned()])
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![v])
}
}
deserializer.deserialize_any(UseVisitor)
}
}

View file

@ -1,56 +0,0 @@
use std::path::Path;
use glob::MatchOptions;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
#[serde(try_from = "String")]
pub struct Pattern {
inner: glob::Pattern,
sensitive: bool,
is_folder: bool,
full_path: bool,
}
impl Pattern {
#[inline]
pub fn matches(&self, str: impl AsRef<str>) -> bool {
self.inner.matches_with(str.as_ref(), MatchOptions {
case_sensitive: self.sensitive,
require_literal_separator: self.full_path,
require_literal_leading_dot: false,
})
}
#[inline]
pub fn match_path(&self, path: impl AsRef<Path>, is_folder: Option<bool>) -> bool {
let path = path.as_ref();
let s = if self.full_path {
path.to_str()
} else {
path.file_name().and_then(|n| n.to_str()).or_else(|| path.to_str())
};
is_folder.map_or(true, |f| f == self.is_folder) && s.is_some_and(|s| self.matches(s))
}
}
impl TryFrom<&str> for Pattern {
type Error = anyhow::Error;
fn try_from(s: &str) -> Result<Self, Self::Error> {
let a = s.trim_start_matches("\\s");
let b = a.trim_end_matches('/');
Ok(Self {
inner: glob::Pattern::new(b)?,
sensitive: a.len() < s.len(),
is_folder: b.len() < a.len(),
full_path: b.contains('/'),
})
}
}
impl TryFrom<String> for Pattern {
type Error = anyhow::Error;
fn try_from(s: String) -> Result<Self, Self::Error> { Self::try_from(s.as_str()) }
}

View file

@ -1,3 +0,0 @@
mod plugins;
pub use plugins::*;

View file

@ -1,29 +0,0 @@
use std::path::PathBuf;
use serde::Deserialize;
use shared::expand_path;
use validator::Validate;
use crate::MERGED_YAZI;
#[derive(Debug, Deserialize, Validate)]
pub struct Plugins {
pub preload: Vec<PathBuf>,
}
impl Default for Plugins {
fn default() -> Self {
#[derive(Deserialize)]
struct Outer {
plugins: Plugins,
}
let mut plugins = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().plugins;
plugins.preload.iter_mut().for_each(|p| {
*p = expand_path(&p);
});
plugins
}
}

View file

@ -1,54 +0,0 @@
use std::fs;
use toml::Table;
use crate::xdg::Xdg;
pub(crate) struct Preset;
impl Preset {
fn merge(a: &mut Table, b: &Table, max: u8) {
for (k, v) in b {
let Some(a) = a.get_mut(k) else {
a.insert(k.clone(), v.clone());
continue;
};
if k == "icons" || max <= 1 {
continue;
}
if let Some(a) = a.as_table_mut() {
if let Some(b) = v.as_table() {
Self::merge(a, b, max - 1);
continue;
}
}
*a = v.clone();
}
}
fn merge_str(user: &str, base: &str) -> String {
let path = Xdg::config_dir().unwrap().join(user);
let mut user = fs::read_to_string(path).unwrap_or_default().parse::<Table>().unwrap();
let base = base.parse::<Table>().unwrap();
Self::merge(&mut user, &base, 2);
user.to_string()
}
#[inline]
pub(crate) fn keymap() -> String {
Self::merge_str("keymap.toml", include_str!("../preset/keymap.toml"))
}
#[inline]
pub(crate) fn theme() -> String {
Self::merge_str("theme.toml", include_str!("../preset/theme.toml"))
}
#[inline]
pub(crate) fn yazi() -> String {
Self::merge_str("yazi.toml", include_str!("../preset/yazi.toml"))
}
}

View file

@ -1,3 +0,0 @@
mod preview;
pub use preview::*;

View file

@ -1,61 +0,0 @@
use std::{path::{Path, PathBuf}, time::{self, SystemTime}};
use md5::{Digest, Md5};
use serde::Deserialize;
use shared::expand_path;
use crate::{xdg::Xdg, MERGED_YAZI};
#[derive(Debug)]
pub struct Preview {
pub tab_size: u32,
pub max_width: u32,
pub max_height: u32,
pub cache_dir: PathBuf,
}
impl Default for Preview {
fn default() -> Self {
#[derive(Deserialize)]
struct Outer {
preview: Shadow,
}
#[derive(Deserialize)]
struct Shadow {
tab_size: u32,
max_width: u32,
max_height: u32,
cache_dir: Option<String>,
}
let preview = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().preview;
let cache_dir =
preview.cache_dir.filter(|p| !p.is_empty()).map_or_else(Xdg::cache_dir, expand_path);
Preview {
tab_size: preview.tab_size,
max_width: preview.max_width,
max_height: preview.max_height,
cache_dir,
}
}
}
impl Preview {
#[inline]
pub fn cache(&self, path: &Path, skip: usize) -> PathBuf {
self
.cache_dir
.join(format!("{:x}", Md5::new_with_prefix(format!("{:?}///{}", path, skip)).finalize()))
}
#[inline]
pub fn tmpfile(&self, prefix: &str) -> PathBuf {
let nanos = SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_nanos();
self.cache_dir.join(format!("{prefix}-{}", nanos / 1000))
}
}

View file

@ -1,3 +0,0 @@
mod tasks;
pub use tasks::*;

View file

@ -1,28 +0,0 @@
use serde::Deserialize;
use validator::Validate;
use crate::{validation::check_validation, MERGED_YAZI};
#[derive(Debug, Deserialize, Validate)]
pub struct Tasks {
#[validate(range(min = 3, message = "Cannot be less than 3"))]
pub micro_workers: u8,
#[validate(range(min = 5, message = "Cannot be less than 5"))]
pub macro_workers: u8,
#[validate(range(min = 3, message = "Cannot be less than 3"))]
pub bizarre_retry: u8,
}
impl Default for Tasks {
fn default() -> Self {
#[derive(Deserialize)]
struct Outer {
tasks: Tasks,
}
let tasks = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().tasks;
check_validation(tasks.validate());
tasks
}
}

View file

@ -1,35 +0,0 @@
use std::str::FromStr;
use anyhow::Result;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Deserialize)]
#[serde(try_from = "String")]
pub struct Color(ratatui::style::Color);
impl FromStr for Color {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
ratatui::style::Color::from_str(s).map(Self).map_err(|_| anyhow::anyhow!("invalid color"))
}
}
impl TryFrom<String> for Color {
type Error = anyhow::Error;
fn try_from(s: String) -> Result<Self, Self::Error> { Self::from_str(&s) }
}
impl From<Color> for ratatui::style::Color {
fn from(value: Color) -> Self { value.0 }
}
impl Serialize for Color {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.to_string().serialize(serializer)
}
}

View file

@ -1,87 +0,0 @@
use std::path::Path;
use serde::{Deserialize, Deserializer};
use super::{Color, Style, StyleShadow};
use crate::Pattern;
pub struct Filetype {
pub name: Option<Pattern>,
pub mime: Option<Pattern>,
pub style: Style,
}
impl Filetype {
pub fn matches(&self, path: &Path, mime: Option<impl AsRef<str>>, is_dir: bool) -> bool {
if self.name.as_ref().is_some_and(|e| e.match_path(path, Some(is_dir))) {
return true;
}
if let Some(mime) = mime {
return self.mime.as_ref().is_some_and(|m| m.matches(mime));
}
false
}
}
impl Filetype {
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Filetype>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct FiletypeOuter {
rules: Vec<FiletypeRule>,
}
#[derive(Deserialize)]
struct FiletypeRule {
name: Option<Pattern>,
mime: Option<Pattern>,
fg: Option<Color>,
bg: Option<Color>,
#[serde(default)]
bold: bool,
#[serde(default)]
dim: bool,
#[serde(default)]
italic: bool,
#[serde(default)]
underline: bool,
#[serde(default)]
blink: bool,
#[serde(default)]
blink_rapid: bool,
#[serde(default)]
reversed: bool,
#[serde(default)]
hidden: bool,
#[serde(default)]
crossed: bool,
}
Ok(
FiletypeOuter::deserialize(deserializer)?
.rules
.into_iter()
.map(|r| Filetype {
name: r.name,
mime: r.mime,
style: StyleShadow {
fg: r.fg,
bg: r.bg,
bold: r.bold,
dim: r.dim,
italic: r.italic,
underline: r.underline,
blink: r.blink,
blink_rapid: r.blink_rapid,
reversed: r.reversed,
hidden: r.hidden,
crossed: r.crossed,
}
.into(),
})
.collect::<Vec<_>>(),
)
}
}

View file

@ -1,45 +0,0 @@
use std::fmt;
use serde::{de::{self, Visitor}, Deserializer};
use crate::Pattern;
#[derive(Debug)]
pub struct Icon {
pub name: Pattern,
pub display: String,
}
impl Icon {
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Icon>, D::Error>
where
D: Deserializer<'de>,
{
struct IconVisitor;
impl<'de> Visitor<'de> for IconVisitor {
type Value = Vec<Icon>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a icon rule, e.g. \"*.md\" = \"\"")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>,
{
let mut icons = Vec::new();
while let Some((key, value)) = &map.next_entry::<String, String>()? {
icons.push(Icon {
name: Pattern::try_from(key.clone())
.map_err(|e| de::Error::custom(e.to_string()))?,
display: value.clone(),
});
}
Ok(icons)
}
}
deserializer.deserialize_map(IconVisitor)
}
}

View file

@ -1,11 +0,0 @@
mod color;
mod filetype;
mod icon;
mod style;
mod theme;
pub use color::*;
pub use filetype::*;
pub use icon::*;
pub use style::*;
pub use theme::*;

View file

@ -1,98 +0,0 @@
use ratatui::style::Modifier;
use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
use super::Color;
#[derive(Clone, Copy, Deserialize)]
#[serde(from = "StyleShadow")]
pub struct Style {
pub fg: Option<Color>,
pub bg: Option<Color>,
pub modifier: Modifier,
}
impl Serialize for Style {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(3))?;
map.serialize_entry("fg", &self.fg)?;
map.serialize_entry("bg", &self.bg)?;
map.serialize_entry("modifier", &self.modifier.bits())?;
map.end()
}
}
impl From<Style> for ratatui::style::Style {
fn from(value: Style) -> Self {
ratatui::style::Style {
fg: value.fg.map(Into::into),
bg: value.bg.map(Into::into),
underline_color: None,
add_modifier: value.modifier,
sub_modifier: Modifier::empty(),
}
}
}
#[derive(Deserialize)]
pub(super) struct StyleShadow {
#[serde(default)]
pub(super) fg: Option<Color>,
#[serde(default)]
pub(super) bg: Option<Color>,
#[serde(default)]
pub(super) bold: bool,
#[serde(default)]
pub(super) dim: bool,
#[serde(default)]
pub(super) italic: bool,
#[serde(default)]
pub(super) underline: bool,
#[serde(default)]
pub(super) blink: bool,
#[serde(default)]
pub(super) blink_rapid: bool,
#[serde(default)]
pub(super) reversed: bool,
#[serde(default)]
pub(super) hidden: bool,
#[serde(default)]
pub(super) crossed: bool,
}
impl From<StyleShadow> for Style {
fn from(value: StyleShadow) -> Self {
let mut modifier = Modifier::empty();
if value.bold {
modifier |= Modifier::BOLD;
}
if value.dim {
modifier |= Modifier::DIM;
}
if value.italic {
modifier |= Modifier::ITALIC;
}
if value.underline {
modifier |= Modifier::UNDERLINED;
}
if value.blink {
modifier |= Modifier::SLOW_BLINK;
}
if value.blink_rapid {
modifier |= Modifier::RAPID_BLINK;
}
if value.reversed {
modifier |= Modifier::REVERSED;
}
if value.hidden {
modifier |= Modifier::HIDDEN;
}
if value.crossed {
modifier |= Modifier::CROSSED_OUT;
}
Self { fg: value.fg, bg: value.bg, modifier }
}
}

View file

@ -1,139 +0,0 @@
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use shared::expand_path;
use validator::Validate;
use super::{Filetype, Icon, Style};
use crate::{validation::check_validation, MERGED_THEME};
#[derive(Deserialize, Serialize, Validate)]
pub struct Manager {
cwd: Style,
// Hovered
hovered: Style,
preview_hovered: Style,
// Find
find_keyword: Style,
find_position: Style,
// Marker
marker_selected: Style,
marker_copied: Style,
marker_cut: Style,
// Tab
tab_active: Style,
tab_inactive: Style,
#[validate(range(min = 1, message = "Must be greater than 0"))]
tab_width: u8,
// Border
pub border_symbol: String,
pub border_style: Style,
// Offset
pub(crate) folder_offset: (u16, u16, u16, u16),
pub(crate) preview_offset: (u16, u16, u16, u16),
// Highlighting
pub syntect_theme: PathBuf,
}
#[derive(Deserialize, Serialize)]
struct Status {
pub separator_open: String,
pub separator_close: String,
pub separator_style: Style,
// Mode
pub mode_normal: Style,
pub mode_select: Style,
pub mode_unset: Style,
// Progress
pub progress_label: Style,
pub progress_normal: Style,
pub progress_error: Style,
// Permissions
pub permissions_t: Style,
pub permissions_r: Style,
pub permissions_w: Style,
pub permissions_x: Style,
pub permissions_s: Style,
}
#[derive(Deserialize, Serialize)]
pub struct Input {
pub border: Style,
pub title: Style,
pub value: Style,
pub selected: Style,
}
#[derive(Deserialize, Serialize)]
pub struct Select {
pub border: Style,
pub active: Style,
pub inactive: Style,
}
#[derive(Deserialize, Serialize)]
pub struct Tasks {
pub border: Style,
pub title: Style,
pub hovered: Style,
}
#[derive(Deserialize, Serialize)]
pub struct Which {
pub mask: Style,
pub cand: Style,
pub rest: Style,
pub desc: Style,
pub separator: String,
pub separator_style: Style,
}
#[derive(Deserialize, Serialize)]
pub struct Help {
pub on: Style,
pub exec: Style,
pub desc: Style,
pub hovered: Style,
pub footer: Style,
}
#[derive(Deserialize, Serialize)]
pub struct Theme {
pub manager: Manager,
status: Status,
pub input: Input,
pub select: Select,
pub tasks: Tasks,
pub which: Which,
pub help: Help,
// File-specific styles
#[serde(rename = "filetype", deserialize_with = "Filetype::deserialize", skip_serializing)]
pub filetypes: Vec<Filetype>,
#[serde(deserialize_with = "Icon::deserialize", skip_serializing)]
pub icons: Vec<Icon>,
}
impl Default for Theme {
fn default() -> Self {
let mut theme: Self = toml::from_str(&MERGED_THEME).unwrap();
check_validation(theme.manager.validate());
theme.manager.syntect_theme = expand_path(&theme.manager.syntect_theme);
theme
}
}

View file

@ -1,31 +0,0 @@
use std::{borrow::Cow, process};
use validator::{ValidationErrors, ValidationErrorsKind};
pub fn check_validation(res: Result<(), ValidationErrors>) {
let Err(errors) = res else {
return;
};
for (field, kind) in errors.into_errors() {
match kind {
ValidationErrorsKind::Struct(errors) => check_validation(Err(*errors)),
ValidationErrorsKind::List(errors) => {
for (i, errors) in errors {
print!("Config `{field}[{i}]` format error: ");
check_validation(Err(*errors));
println!();
}
}
ValidationErrorsKind::Field(error) => {
for e in error {
println!(
"Config `{field}` format error: {}\n",
e.message.unwrap_or(Cow::Borrowed("unknown error"))
);
}
}
}
}
process::exit(1);
}

View file

@ -1,44 +0,0 @@
use std::{env, path::PathBuf};
use shared::expand_path;
pub(super) struct Xdg;
impl Xdg {
pub(super) fn config_dir() -> Option<PathBuf> {
if let Some(s) = env::var_os("YAZI_CONFIG_HOME").filter(|s| !s.is_empty()) {
return Some(expand_path(s));
}
#[cfg(windows)]
{
dirs::config_dir().map(|p| p.join("yazi").join("config"))
}
#[cfg(unix)]
{
env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs::home_dir().map(|h| h.join(".config")))
.map(|p| p.join("yazi"))
}
}
pub(super) fn state_dir() -> Option<PathBuf> {
#[cfg(windows)]
{
dirs::data_dir().map(|p| p.join("yazi").join("state"))
}
#[cfg(unix)]
{
env::var_os("XDG_STATE_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs::home_dir().map(|h| h.join(".local/state")))
.map(|p| p.join("yazi"))
}
}
#[inline]
pub(super) fn cache_dir() -> PathBuf { env::temp_dir().join("yazi") }
}

View file

@ -1,35 +0,0 @@
[package]
name = "core"
version = "0.1.5"
edition = "2021"
[dependencies]
adaptor = { path = "../adaptor" }
config = { path = "../config" }
shared = { path = "../shared" }
# External dependencies
anyhow = "^1"
async-channel = "^1"
crossterm = "^0"
futures = "^0"
indexmap = "^2"
libc = "^0"
notify = { version = "^6", default-features = false, features = [ "macos_fsevent" ] }
parking_lot = "^0"
ratatui = "^0"
regex = "^1"
serde = "^1"
serde_json = "^1"
syntect = "^5"
tokio = { version = "^1", features = [ "parking_lot", "macros", "rt-multi-thread", "sync", "time", "fs", "process", "io-std", "io-util" ] }
tokio-stream = "^0"
trash = "^3"
unicode-width = "^0"
yazi-prebuild = "^0"
# Logging
tracing = "^0"
[target."cfg(windows)".dependencies]
clipboard-win = "^4"

View file

@ -1,6 +0,0 @@
use shared::RoCell;
use tokio::sync::Semaphore;
pub static BLOCKER: RoCell<Semaphore> = RoCell::new();
pub(super) fn init_blocker() { BLOCKER.init(Semaphore::new(1)) }

View file

@ -1,92 +0,0 @@
use config::keymap::KeymapLayer;
use crossterm::terminal::WindowSize;
use ratatui::prelude::Rect;
use shared::Term;
use crate::{help::Help, input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position};
pub struct Ctx {
pub manager: Manager,
pub which: Which,
pub help: Help,
pub input: Input,
pub select: Select,
pub tasks: Tasks,
}
impl Ctx {
pub fn make() -> Self {
Self {
manager: Manager::make(),
which: Default::default(),
help: Default::default(),
input: Default::default(),
select: Default::default(),
tasks: Tasks::start(),
}
}
pub fn area(&self, pos: &Position) -> Rect {
let WindowSize { columns, rows, .. } = Term::size();
let (x, y) = match pos {
Position::None => return Rect::default(),
Position::Top(Rect { mut x, mut y, width, height }) => {
x = x.min(columns.saturating_sub(*width));
y = y.min(rows.saturating_sub(*height));
((columns / 2).saturating_sub(width / 2) + x, y)
}
Position::Hovered(rect @ Rect { mut x, y, width, height }) => {
let Some(r) =
self.manager.hovered().and_then(|h| self.manager.current().rect_current(&h.url))
else {
return self.area(&Position::Top(*rect));
};
x = x.min(columns.saturating_sub(*width));
if y + height + r.y + r.height > rows {
(x + r.x, r.y.saturating_sub(height.saturating_sub(1)))
} else {
(x + r.x, y + r.y + r.height)
}
}
};
let (w, h) = pos.dimension().unwrap();
Rect { x, y, width: w.min(columns.saturating_sub(x)), height: h.min(rows.saturating_sub(y)) }
}
#[inline]
pub fn cursor(&self) -> Option<(u16, u16)> {
if self.input.visible {
let Rect { x, y, .. } = self.area(&self.input.position);
return Some((x + 1 + self.input.cursor(), y + 1));
}
if let Some((x, y)) = self.help.cursor() {
return Some((x, y));
}
None
}
#[inline]
pub fn layer(&self) -> KeymapLayer {
if self.which.visible {
KeymapLayer::Which
} else if self.help.visible {
KeymapLayer::Help
} else if self.input.visible {
KeymapLayer::Input
} else if self.select.visible {
KeymapLayer::Select
} else if self.tasks.visible {
KeymapLayer::Tasks
} else {
KeymapLayer::Manager
}
}
#[inline]
pub fn image_layer(&self) -> bool {
!matches!(self.layer(), KeymapLayer::Which | KeymapLayer::Help | KeymapLayer::Tasks)
}
}

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