Compare commits

...

1433 commits
v0.1.0 ... main

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

36
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,36 @@
name: Test
on:
push:
branches: [main]
pull_request:
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@v7
- 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: 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 }}

15
.gitignore vendored
View file

@ -1 +1,14 @@
/target
target/
yazi-*/completions
node_modules/
.DS_Store
result
result-*
.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.

5166
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,39 +1,97 @@
[package]
name = "yazi"
version = "0.1.0"
edition = "2021"
[workspace]
resolver = "3"
members = [ "yazi-*" ]
default-members = [ "yazi-fm", "yazi-cli" ]
[dependencies]
ansi-to-tui = "^3"
anyhow = "^1"
async-channel = "^1"
base64 = "^0"
console-subscriber = "^0"
crossterm = { version = "^0", features = [ "event-stream" ] }
futures = "^0"
glob = "^0"
image = "^0"
indexmap = "^2"
libc = "^0"
md5 = "^0"
notify = { version = "^6", default-features = false, features = [ "macos_fsevent" ] }
once_cell = "^1"
parking_lot = "^0"
ratatui = "^0"
serde = { version = "^1", features = [ "derive" ] }
serde_json = "^1"
signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] }
syntect = "^5"
tokio = { version = "^1", features = [ "parking_lot", "macros", "rt-multi-thread", "sync", "fs", "process", "io-std", "io-util" ] }
toml = { version = "^0", features = [ "preserve_order" ] }
tracing = "^0"
tracing-appender = "^0"
tracing-subscriber = "^0"
trash = "^3"
unicode-width = "^0"
xdg = "^2"
[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.release]
# strip = true
# lto = true
# panic = "abort"
[profile.dev]
debug = "line-tables-only"
[profile.release]
codegen-units = 1
lto = true
panic = "abort"
strip = true
[profile.release-windows]
inherits = "release"
panic = "unwind"
[profile.dev-opt]
inherits = "release"
codegen-units = 256
incremental = true
lto = false
[profile.dev.package."*"]
debug = false
[workspace.dependencies]
ansi-to-tui = "8.0.1"
anyhow = "1.0.104"
arc-swap = { version = "1.9.2", features = [ "serde" ] }
base64 = "0.22.1"
bitflags = { version = "2.13.1", features = [ "serde" ] }
chrono = "0.4.45"
clap = { version = "4.6.2", features = [ "derive" ] }
compact_str = { version = "0.10.0", features = [ "serde" ] }
core-foundation-sys = "0.8.7"
data-encoding = "2.11.0"
dirs = "6.0.0"
dyn-clone = "1.0.20"
either = { version = "1.16.0" }
foldhash = "0.2.0"
futures = "0.3.33"
globset = "0.4.19"
hashbrown = { version = "0.17.1", features = [ "serde" ] }
image = { version = "0.25.10", default-features = false, features = [ "avif", "bmp", "dds", "exr", "ff", "gif", "hdr", "ico", "jpeg", "png", "pnm", "qoi", "tga", "tiff", "webp" ] }
indexmap = { version = "2.14.0", features = [ "serde" ] }
inventory = "0.3.24"
libc = "0.2.186"
lru = "0.18.1"
mlua = { version = "0.12.0", features = [ "anyhow", "async", "error-send", "lua55", "macros", "serde" ] }
objc2 = "0.6.4"
ordered-float = { version = "5.3.0", features = [ "serde" ] }
parking_lot = "0.12.5"
paste = "1.0.15"
percent-encoding = "2.3.2"
rand = { version = "0.10.2", default-features = false, features = [ "std", "sys_rng" ] }
ratatui-core = { version = "0.1.2", default-features = false, features = [ "std", "layout-cache", "serde", "underline-color" ] }
ratatui-widgets = { version = "0.3.2", default-features = false, features = [ "std", "unstable-rendered-line-info" ] }
regex = "1.13.1"
russh = { version = "0.62.2", default-features = false, features = [ "ring", "rsa" ] }
scopeguard = "1.2.0"
serde = { version = "1.0.229", features = [ "derive" ] }
serde_json = "1.0.151"
serde_with = "3.21.0"
strum = { version = "0.28.0", features = [ "derive" ] }
syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
thiserror = "2.0.19"
tokio = { version = "1.53.0", features = [ "full" ] }
tokio-stream = "0.1.18"
tokio-util = "0.7.18"
toml = { version = "1.1.3" }
tracing = { version = "0.1.44", features = [ "max_level_debug", "release_max_level_debug" ] }
twox-hash = { version = "2.1.3", default-features = false, features = [ "std", "random", "xxhash3_128" ] }
typed-path = "0.12.3"
unicode-width = { version = "0.2.2", default-features = false }
uzers = "0.12.2"
[workspace.lints.clippy]
format_push_string = "warn"
if_same_then_else = "allow"
implicit_clone = "warn"
len_without_is_empty = "allow"
missing_safety_doc = "allow"
module_inception = "allow"
option_map_unit_fn = "allow"
unit_arg = "allow"
use_self = "warn"

View file

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.

113
README.md
View file

@ -1,55 +1,94 @@
<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 configurable 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.
https://github.com/sxyazi/yazi/assets/17523360/740a41f4-3d24-4287-952c-3aec51520a32
💡 A new article explaining its internal workings: [Why is Yazi Fast?](https://yazi-rs.github.io/blog/why-is-yazi-fast)
⚠️ Note: Yazi is currently in active development and may be unstable. The API is subject to change without prior notice.
- 🚀 **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++ 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!
## Installation
https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265cc7
Before getting started, ensure that the following dependencies are installed on your system:
## Project status
- nerd-fonts (required, for icons)
- jq (optional, for JSON preview)
- unar (optional, for archive preview)
- ffmpegthumbnailer (optional, for video thumbnails)
- fd (optional, for file searching)
- rg (optional, for file content searching)
- fzf (optional, for directory jumping)
- zoxide (optional, for directory jumping)
Public beta, can be used as a daily driver.
```bash
# Arch Linux
pacman -S ttf-nerd-fonts-symbols jq unarchiver ffmpegthumbnailer fd ripgrep fzf zoxide
Yazi is currently in heavy development, expect breaking changes.
# macOS
brew install jq unar ffmpegthumbnailer fd ripgrep fzf zoxide
brew tap homebrew/cask-fonts && brew install --cask font-symbols-only-nerd-font
```
## Documentation
Execute the following commands to clone the project and build Yazi:
- Usage: https://yazi-rs.github.io/docs/installation
- Features: https://yazi-rs.github.io/features
```bash
git clone https://github.com/sxyazi/yazi.git
cd yazi
cargo build --release
```
## Discussion
## Usage
- Discord Server (English mainly): https://discord.gg/qfADduSdJu
- Telegram Group (Chinese mainly): https://t.me/yazi_rs
```bash
./target/release/yazi
```
## Image Preview
## TODO
| 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) |
- [x] Add example config for general usage, currently please see my [another repo](https://github.com/sxyazi/dotfiles/tree/main/yazi) instead
- [x] Integration with fzf, zoxide for fast directory navigation
- [x] Integration with fd, rg for fuzzy file searching
- [ ] Support for Überzug++ for image previews with X11/wayland environment
- [ ] Batch renaming support
See https://yazi-rs.github.io/docs/image-preview for details.
<!-- Protocols -->
[kgp]: https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders
[kgp-old]: https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/drivers/kgp_old.rs
[iip]: https://iterm2.com/documentation-images.html
[sixel]: https://www.vt100.net/docs/vt3xx-gp/chapter14.html
[ascii-art]: https://en.wikipedia.org/wiki/ASCII_art
<!-- Dependencies -->
[ueberzug]: https://github.com/jstkdng/ueberzugpp
[chafa]: https://hpjansson.org/chafa/
## Special Thanks
<img alt="RustRover logo" align="right" width="200" src="https://resources.jetbrains.com/storage/products/company/brand/logos/RustRover.svg">
Thanks to RustRover team for providing open-source licenses to support the maintenance of Yazi.
Active code contributors can contact @sxyazi to get a license (if any are still available).
## License
Yazi is MIT licensed.
Yazi is MIT-licensed. For more information check the [LICENSE](LICENSE) file.

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,11 +0,0 @@
cargo build --release --target aarch64-apple-darwin
cargo build --release --target x86_64-apple-darwin
cargo build --release --target x86_64-unknown-linux-gnu
mv target/aarch64-apple-darwin/release/yazi target/yazi-aarch64-apple-darwin
mv target/x86_64-apple-darwin/release/yazi target/yazi-x86_64-apple-darwin
mv target/x86_64-unknown-linux-gnu/release/yazi target/yazi-x86_64-unknown-linux-gnu
zip -j yazi-aarch64-apple-darwin.zip target/yazi-aarch64-apple-darwin
zip -j yazi-x86_64-apple-darwin.zip target/yazi-x86_64-apple-darwin
zip -j yazi-x86_64-unknown-linux-gnu.zip target/yazi-x86_64-unknown-linux-gnu

View file

@ -1,120 +0,0 @@
[manager]
keymap = [
{ on = [ "<Esc>" ], exec = "escape" },
{ on = [ "q" ], exec = "quit" },
{ on = [ "<C-q>" ], exec = "close" },
# Navigation
{ on = [ "j" ], exec = "arrow 1" },
{ on = [ "k" ], exec = "arrow -1" },
{ on = [ "J" ], exec = "arrow 5" },
{ on = [ "K" ], exec = "arrow -5" },
{ on = [ "h" ], exec = "leave" },
{ on = [ "l" ], exec = "enter" },
{ on = [ "H" ], exec = "back" },
{ on = [ "L" ], exec = "forward" },
# Selection
{ on = [ "<Space>" ], exec = "select --state=none" },
{ on = [ "v" ], exec = "visual_mode" },
{ on = [ "V" ], exec = "visual_mode --unselect" },
{ on = [ "<C-a>" ], exec = "select_all --state=true" },
{ on = [ "<C-r>" ], exec = "select_all --state=none" },
# Operation
{ on = [ "o" ], exec = "open" },
{ on = [ "O" ], exec = "open --select" },
{ on = [ "y" ], exec = "yank" },
{ on = [ "x" ], exec = "yank --cut" },
{ on = [ "p" ], exec = "paste" },
{ on = [ "P" ], exec = "paste --force" },
{ on = [ "f" ], exec = "paste --follow" },
{ on = [ "F" ], exec = "paste --follow --force" },
{ on = [ "d" ], exec = "remove" },
{ on = [ "D" ], exec = "remove --permanently" },
{ on = [ "c" ], exec = "create" },
{ on = [ "r" ], exec = "rename" },
{ on = [ "." ], exec = "hidden toggle" },
{ on = [ "s" ], exec = "search fd" },
{ on = [ "S" ], exec = "search rg" },
{ on = [ "<C-s>" ], exec = "search none" },
{ on = [ "z" ], exec = "jump zoxide" },
{ on = [ "Z" ], exec = "jump fzf" },
# Tabs
{ on = [ "t" ], exec = "tab_create --current" },
{ on = [ "1" ], exec = "tab_switch 0" },
{ on = [ "2" ], exec = "tab_switch 1" },
{ on = [ "3" ], exec = "tab_switch 2" },
{ on = [ "4" ], exec = "tab_switch 3" },
{ on = [ "5" ], exec = "tab_switch 4" },
{ on = [ "[" ], exec = "tab_switch -1 --relative" },
{ on = [ "]" ], exec = "tab_switch 1 --relative" },
{ on = [ "{" ], exec = "tab_swap -1" },
{ on = [ "}" ], exec = "tab_swap 1" },
# Tasks
{ on = [ "w" ], exec = "tasks_show" },
]
[tasks]
keymap = [
{ on = [ "<C-q>" ], exec = "close" },
{ on = [ "<Esc>" ], exec = "close" },
{ on = [ "w" ], exec = "close" },
{ on = [ "j" ], exec = "arrow 1" },
{ on = [ "k" ], exec = "arrow -1" },
{ on = [ "x" ], exec = "cancel" },
]
[select]
keymap = [
{ on = [ "<C-q>" ], exec = "close" },
{ on = [ "<Esc>" ], exec = "close" },
{ on = [ "<Enter>" ], exec = "close --submit" },
{ on = [ "j" ], exec = "arrow 1" },
{ on = [ "k" ], exec = "arrow -1" },
{ on = [ "J" ], exec = "arrow 5" },
{ on = [ "K" ], exec = "arrow -5" },
]
[input]
keymap = [
{ on = [ "<C-q>" ], exec = "close" },
{ on = [ "<Enter>" ], exec = "close --submit" },
{ on = [ "<Esc>" ], exec = "escape" },
{ on = [ "<Backspace>" ], exec = "backspace" },
# Mode
{ on = [ "i" ], exec = "insert" },
{ on = [ "a" ], exec = "insert --append" },
{ on = [ "v" ], exec = "visual" },
{ on = [ "h" ], exec = "move -1" },
{ on = [ "l" ], exec = "move 1" },
{ on = [ "H" ], exec = "move -999" },
{ on = [ "L" ], exec = "move 999" },
{ on = [ "b" ], exec = "backward" },
{ on = [ "w" ], exec = "forward" },
{ on = [ "e" ], exec = "forward --end-of-word" },
{ on = [ "d" ], exec = "delete" },
{ on = [ "c" ], exec = "delete --insert" },
{ on = [ "x" ], exec = [ "delete", "move 1" ] }
]

View file

@ -1,145 +0,0 @@
[tab]
active = { fg = "#1E2031", bg = "#80AEFA" }
inactive = { fg = "#C8D3F8", bg = "#484D66" }
[status]
primary = { normal = "#80AEFA", select = "#CD9EFC", unselect = "#FFA577" }
secondary = { normal = "#1E2031", select = "#23273B", unselect = "#23273B" }
tertiary = { normal = "#6D738F", select = "#6D738F", unselect = "#6D738F" }
body = { normal = "#484D66", select = "#484D66", unselect = "#484D66" }
emphasis = { normal = "#C8D3F8", select = "#C8D3F8", unselect = "#C8D3F8" }
info = { normal = "#7AD9E5", select = "#7AD9E5", unselect = "#7AD9E5" }
success = { normal = "#97DC8D", select = "#97DC8D", unselect = "#97DC8D" }
warning = { normal = "#F3D398", select = "#F3D398", unselect = "#F3D398" }
danger = { normal = "#FA7F94", select = "#FA7F94", unselect = "#FA7F94" }
[progress]
gauge = { fg = "#FFA577", bg = "#484D66" }
label = { fg = "#FFFFFF", bold = true }
[selection]
hovered = { fg = "#1E2031", bg = "#80AEFA" }
[marker]
selecting = { fg = "#97DC8D", bg = "#97DC8D" }
selected = { fg = "#F3D398", bg = "#F3D398" }
[preview]
hovered = { underline = true }
syntect_theme = "~/.config/bat/themes/Catppuccin-macchiato.tmTheme"
[filetype]
rules = [
# Images
{ mime = "image/*", fg = "#7AD9E5" },
# Videos
{ mime = "video/*", fg = "#F3D398" },
{ mime = "audio/*", fg = "#F3D398" },
# Archives
{ mime = "application/x-bzip", fg = "#CD9EFC" },
{ mime = "application/x-bzip2", fg = "#CD9EFC" },
{ mime = "application/gzip", fg = "#CD9EFC" },
{ mime = "application/vnd.rar", fg = "#CD9EFC" },
{ mime = "application/x-tar", fg = "#CD9EFC" },
{ mime = "application/zip", fg = "#CD9EFC" },
{ mime = "application/x-7z-compressed", fg = "#CD9EFC" },
# Fallback
{ name = "*", fg = "#C8D3F8" },
{ name = "*/", fg = "#80AEFA" }
]
[icons]
"Desktop/" = ""
"Documents/" = ""
"Downloads/" = ""
"Music/" = ""
"Pictures/" = ""
"Public/" = ""
"Videos/" = ""
".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,50 +0,0 @@
[manager]
sort_by = "modified"
sort_reverse = true
show_hidden = false
[preview]
tab_size = 2
max_width = 600
max_height = 900
[opener]
archive = [
{ cmd = "unar", args = [ "$1" ] },
]
text = [
{ cmd = "vi", args = [ "$*" ], block = true },
]
image = [
{ cmd = "open", args = [ "$*" ] },
{ cmd = "exiftool", args = [ "$1" ], block = true },
]
video = [
{ cmd = "mpv", args = [ "$*" ] },
{ cmd = "mediainfo", args = [ "$1" ], block = true },
]
audio = [
{ cmd = "mpv", args = [ "$*" ] },
{ cmd = "mediainfo", args = [ "$1" ], block = true },
]
fallback = [
{ cmd = "open", args = [ "$*" ] },
]
[open]
rules = [
{ name = "*.html", use = "fallback" },
{ mime = "text/*", use = "text" },
{ mime = "image/*", use = "image" },
{ mime = "video/*", use = "video" },
{ mime = "audio/*", use = "audio" },
{ mime = "application/x-bzip", use = "archive" },
{ mime = "application/x-bzip2", use = "archive" },
{ mime = "application/gzip", use = "archive" },
{ mime = "application/vnd.rar", use = "archive" },
{ mime = "application/x-tar", use = "archive" },
{ mime = "application/zip", use = "archive" },
{ mime = "application/x-7z-compressed", use = "archive" },
]

1
cspell.json Normal file
View file

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

82
flake.lock generated Normal file
View file

@ -0,0 +1,82 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1783279667,
"narHash": "sha256-/NAkDSsve+GNM0Bt6tleJdCGfsTlK89nPjkVOzZMo0s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f205b5574fd0cb7da5b702a2da51507b7f4fdd1b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1783320166,
"narHash": "sha256-l7C/OsjcnWDOk2K3ssj+SBduwL67LashjBqis9+t468=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "20ee15370c9256669d66968b89ee20a4b0a4e673",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

72
flake.nix Normal file
View file

@ -0,0 +1,72 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
self,
nixpkgs,
rust-overlay,
flake-utils,
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ rust-overlay.overlays.default ];
};
toolchain = pkgs.rust-bin.stable.latest.default;
rustPlatform = pkgs.makeRustPlatform {
cargo = toolchain;
rustc = toolchain;
};
rev = self.shortRev or self.dirtyShortRev or "dirty";
date = self.lastModifiedDate or self.lastModified or "19700101";
version =
(builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version
+ "pre${builtins.substring 0 8 date}_${rev}";
in
{
packages = {
yazi-unwrapped = pkgs.callPackage ./nix/yazi-unwrapped.nix {
inherit
version
rev
date
rustPlatform
;
};
yazi = pkgs.callPackage ./nix/yazi.nix {
inherit (self.packages.${system}) yazi-unwrapped;
};
default = self.packages.${system}.yazi;
};
devShells = {
default = pkgs.callPackage ./nix/shell.nix {
inherit toolchain;
inherit (self.packages.${system}) yazi yazi-unwrapped;
};
};
formatter = pkgs.nixfmt-tree;
}
)
// {
overlays = {
default = self.overlays.yazi;
yazi = _: prev: {
inherit (self.packages.${prev.stdenv.system}) yazi yazi-unwrapped;
};
};
};
}

25
nix/shell.nix Normal file
View file

@ -0,0 +1,25 @@
{
mkShell,
yazi,
toolchain,
cspell,
yazi-unwrapped,
}:
mkShell {
packages = yazi.passthru.runtimePaths ++ [
(toolchain.override {
extensions = [
"rust-src"
"rustfmt"
"rust-analyzer"
"clippy"
];
})
cspell
];
inputsFrom = [ yazi-unwrapped ];
env.RUST_BACKTRACE = "1";
}

88
nix/yazi-unwrapped.nix Normal file
View file

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

109
nix/yazi.nix Normal file
View file

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

31
rustfmt.toml Normal file
View file

@ -0,0 +1,31 @@
color = "Never"
condense_wildcard_suffixes = true
edition = "2024"
enum_discrim_align_threshold = 99
fn_single_line = true
format_code_in_doc_comments = false
format_generated_files = false
format_macro_matchers = true
format_macro_bodies = true
format_strings = false
hard_tabs = true
hex_literal_case = "Lower"
show_parse_errors = false
imports_indent = "Visual"
imports_layout = "Horizontal"
imports_granularity = "Crate"
newline_style = "Unix"
normalize_comments = true
normalize_doc_attributes = false
overflow_delimited_expr = true
reorder_impl_items = true
group_imports = "StdExternalCrate"
reorder_modules = true
struct_field_align_threshold = 99
tab_spaces = 2
unstable_features = true
use_field_init_shorthand = true
use_small_heuristics = "Max"
use_try_shorthand = true
style_edition = "2024"
wrap_comments = true

34
scripts/build.sh Executable file
View file

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

20
scripts/bump.sh Executable file
View file

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

View file

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

View file

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

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

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

View file

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

165
snap/snapcraft.yaml Normal file
View file

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

View file

@ -1,66 +0,0 @@
use std::{collections::BTreeMap, fmt};
use serde::{de::{self, Visitor}, Deserializer};
#[derive(Debug, Default)]
pub struct Exec {
pub cmd: String,
pub args: Vec<String>,
pub named: BTreeMap<String, String>,
}
impl From<&str> for Exec {
fn from(value: &str) -> Self {
let mut exec = Self::default();
for x in value.split_whitespace() {
if x.starts_with("--") {
let mut it = x[2..].splitn(2, '=');
let name = it.next().unwrap();
let value = it.next().unwrap_or("");
exec.named.insert(name.to_string(), value.to_string());
} else if exec.cmd.is_empty() {
exec.cmd = x.to_string();
} else {
exec.args.push(x.to_string());
}
}
exec
}
}
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 command 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::from(value.as_str()));
}
Ok(execs)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(value.split(';').map(Exec::from).collect())
}
}
deserializer.deserialize_any(ExecVisitor)
}
}

View file

@ -1,94 +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 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 {
let shift = if let KeyCode::Char(c) = value.code { c.is_ascii_uppercase() } else { false };
Self {
code: value.code,
shift: shift || value.modifiers.contains(KeyModifiers::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,
"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)
}
}

View file

@ -1,50 +0,0 @@
use serde::{Deserialize, Deserializer};
use super::{Exec, Key};
use crate::config::MERGED_KEYMAP;
#[derive(Debug, Deserialize)]
pub struct Single {
pub on: Vec<Key>,
#[serde(deserialize_with = "Exec::deserialize")]
pub exec: Vec<Exec>,
}
#[derive(Debug)]
pub struct Keymap {
pub manager: Vec<Single>,
pub tasks: Vec<Single>,
pub select: Vec<Single>,
pub input: Vec<Single>,
}
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,
}
#[derive(Deserialize)]
struct Inner {
keymap: Vec<Single>,
}
let shadow = Shadow::deserialize(deserializer)?;
Ok(Self {
manager: shadow.manager.keymap,
tasks: shadow.tasks.keymap,
select: shadow.select.keymap,
input: shadow.input.keymap,
})
}
}
impl Keymap {
pub fn new() -> Self { toml::from_str(&MERGED_KEYMAP).unwrap() }
}

View file

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

View file

@ -1,40 +0,0 @@
use std::{env, fs, path::PathBuf};
use serde::Deserialize;
use super::SortBy;
use crate::config::MERGED_YAZI;
#[derive(Debug, Deserialize)]
pub struct Manager {
#[serde(skip)]
pub cwd: PathBuf,
#[serde(skip)]
pub cache: PathBuf,
// Sorting
pub sort_by: SortBy,
pub sort_reverse: bool,
// Display
pub show_hidden: bool,
}
impl Manager {
pub fn new() -> Self {
#[derive(Deserialize)]
struct Outer {
manager: Manager,
}
let mut manager = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().manager;
manager.cwd = env::current_dir().unwrap_or("/".into());
manager.cache = "/tmp/yazi".into();
if !manager.cache.is_dir() {
fs::create_dir(&manager.cache).unwrap();
}
manager
}
}

View file

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

View file

@ -1,25 +0,0 @@
use anyhow::bail;
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone, Copy)]
#[serde(try_from = "String")]
pub enum SortBy {
Alphabetical,
Created,
Modified,
Size,
}
impl TryFrom<String> for SortBy {
type Error = anyhow::Error;
fn try_from(s: String) -> Result<Self, Self::Error> {
Ok(match s.as_str() {
"created" => Self::Created,
"modified" => Self::Modified,
"size" => Self::Size,
"alphabetical" => Self::Alphabetical,
_ => bail!("invalid sort_by value: {}", s),
})
}
}

View file

@ -1,30 +0,0 @@
use once_cell::sync::Lazy;
pub mod keymap;
pub mod manager;
pub mod open;
mod pattern;
mod preset;
pub mod preview;
pub mod theme;
pub(crate) use pattern::*;
pub(crate) use preset::*;
static MERGED_KEYMAP: Lazy<String> = Lazy::new(|| Preset::keymap());
static MERGED_THEME: Lazy<String> = Lazy::new(|| Preset::theme());
static MERGED_YAZI: Lazy<String> = Lazy::new(|| Preset::yazi());
pub static KEYMAP: Lazy<keymap::Keymap> = Lazy::new(|| keymap::Keymap::new());
pub static MANAGER: Lazy<manager::Manager> = Lazy::new(|| manager::Manager::new());
pub static OPEN: Lazy<open::Open> = Lazy::new(|| open::Open::new());
pub static PREVIEW: Lazy<preview::Preview> = Lazy::new(|| preview::Preview::new());
pub static THEME: Lazy<theme::Theme> = Lazy::new(|| theme::Theme::new());
pub fn init() {
Lazy::force(&KEYMAP);
Lazy::force(&MANAGER);
Lazy::force(&OPEN);
Lazy::force(&PREVIEW);
Lazy::force(&THEME);
}

View file

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

View file

@ -1,65 +0,0 @@
use std::{collections::{BTreeMap, BTreeSet}, path::Path};
use serde::{Deserialize, Deserializer};
use super::Opener;
use crate::config::{Pattern, MERGED_YAZI};
#[derive(Debug)]
pub struct Open {
openers: BTreeMap<String, Vec<Opener>>,
rules: Vec<OpenRule>,
}
#[derive(Debug, Deserialize)]
struct OpenRule {
name: Option<Pattern>,
mime: Option<Pattern>,
#[serde(rename = "use")]
use_: String,
}
impl Open {
pub fn new() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
pub fn openers(&self, path: impl AsRef<Path>, mime: impl AsRef<str>) -> Option<Vec<&Opener>> {
self.rules.iter().find_map(|rule| {
if rule.name.as_ref().map_or(false, |e| e.match_path(&path, Some(false)))
|| rule.mime.as_ref().map_or(false, |m| m.matches(&mime))
{
self.openers.get(&rule.use_).map(|v| v.iter().collect())
} else {
None
}
})
}
pub fn common_openers<'a>(
&self,
targets: &[(impl AsRef<Path>, impl AsRef<str>)],
) -> Vec<&Opener> {
let grouped = targets.into_iter().filter_map(|(p, m)| self.openers(p, m)).collect::<Vec<_>>();
let flat = grouped.iter().flatten().cloned().collect::<BTreeSet<_>>();
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)?;
Ok(Self { openers: outer.opener, rules: outer.open.rules })
}
}

View file

@ -1,31 +0,0 @@
use serde::{Deserialize, Deserializer};
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Opener {
pub cmd: String,
pub args: Vec<String>,
pub block: bool,
pub spread: bool,
}
impl<'de> Deserialize<'de> for Opener {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
pub struct Shadow {
pub cmd: String,
pub args: Vec<String>,
#[serde(default)]
pub block: bool,
#[serde(skip)]
pub spread: bool,
}
let shadow = Shadow::deserialize(deserializer)?;
let spread = shadow.args.contains(&"$*".to_string());
Ok(Self { cmd: shadow.cmd, args: shadow.args, block: shadow.block, spread })
}
}

View file

@ -1,33 +0,0 @@
use std::path::Path;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
#[serde(try_from = "String")]
pub struct Pattern {
inner: glob::Pattern,
is_folder: bool,
}
impl Pattern {
pub fn matches(&self, str: impl AsRef<str>) -> bool { self.inner.matches(str.as_ref()) }
pub fn match_path(&self, path: impl AsRef<Path>, is_folder: Option<bool>) -> bool {
is_folder.map_or(true, |f| f == self.is_folder) && self.inner.matches_path(path.as_ref())
}
}
impl TryFrom<&str> for Pattern {
type Error = anyhow::Error;
fn try_from(s: &str) -> Result<Self, Self::Error> {
let is_folder = s.ends_with('/');
Ok(Self { inner: glob::Pattern::new(s.trim_end_matches('/'))?, is_folder })
}
}
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,55 +0,0 @@
use std::fs;
use toml::Table;
use xdg::BaseDirectories;
pub(crate) struct Preset;
impl Preset {
fn merge(a: &mut Table, b: &Table, max: u8) {
for (k, v) in b {
let a = if let Some(a) = a.get_mut(k) {
a
} 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 = BaseDirectories::new().unwrap().get_config_file(user);
let mut user = fs::read_to_string(path).unwrap_or("".to_string()).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("yazi/keymap.toml", include_str!("../../config/keymap.toml"))
}
#[inline]
pub(crate) fn theme() -> String {
Self::merge_str("yazi/theme.toml", include_str!("../../config/theme.toml"))
}
#[inline]
pub(crate) fn yazi() -> String {
Self::merge_str("yazi/yazi.toml", include_str!("../../config/yazi.toml"))
}
}

View file

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

View file

@ -1,23 +0,0 @@
use serde::Deserialize;
use crate::config::MERGED_YAZI;
#[derive(Debug, Deserialize)]
pub struct Preview {
pub tab_size: u32,
pub max_width: u32,
pub max_height: u32,
}
impl Preview {
pub fn new() -> Self {
#[derive(Deserialize)]
struct Outer {
preview: Preview,
}
let outer: Outer = toml::from_str(&MERGED_YAZI).unwrap();
outer.preview
}
}

View file

@ -1,47 +0,0 @@
use std::ops::Deref;
use anyhow::{bail, Result};
use ratatui::style;
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(try_from = "String")]
pub struct Color(pub(super) style::Color);
impl Default for Color {
fn default() -> Self { Self(style::Color::Reset) }
}
impl TryFrom<String> for Color {
type Error = anyhow::Error;
fn try_from(s: String) -> Result<Self, Self::Error> {
if s.len() < 7 {
bail!("Invalid color: {}", s);
}
Ok(Self(style::Color::Rgb(
u8::from_str_radix(&s[1..3], 16)?,
u8::from_str_radix(&s[3..5], 16)?,
u8::from_str_radix(&s[5..7], 16)?,
)))
}
}
impl Deref for Color {
type Target = style::Color;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl Color {
pub fn fg(&self) -> style::Style { style::Style::new().fg(self.0) }
pub fn bg(&self) -> style::Style { style::Style::new().bg(self.0) }
}
#[derive(Deserialize)]
pub struct ColorGroup {
pub normal: Color,
pub select: Color,
pub unselect: Color,
}

View file

@ -1,62 +0,0 @@
use std::path::Path;
use serde::{Deserialize, Deserializer};
use super::Style;
use crate::config::{theme::Color, 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<String>, is_dir: bool) -> bool {
if self.name.as_ref().map_or(false, |e| e.match_path(path, Some(is_dir))) {
return true;
}
if let Some(mime) = mime {
return self.mime.as_ref().map_or(false, |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<FiletypeOuterStyle>,
}
#[derive(Deserialize)]
struct FiletypeOuterStyle {
name: Option<Pattern>,
mime: Option<Pattern>,
fg: Option<Color>,
bg: Option<Color>,
bold: Option<bool>,
underline: Option<bool>,
}
Ok(
FiletypeOuter::deserialize(deserializer)?
.rules
.into_iter()
.map(|r| Filetype {
name: r.name,
mime: r.mime,
style: Style {
fg: r.fg,
bg: r.bg,
bold: r.bold,
underline: r.underline,
},
})
.collect::<Vec<_>>(),
)
}
}

View file

@ -1,45 +0,0 @@
use std::fmt;
use serde::{de::{self, Visitor}, Deserializer};
use crate::config::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,40 +0,0 @@
use ratatui::style::{self, Modifier};
use serde::Deserialize;
use super::Color;
#[derive(Deserialize)]
pub struct Style {
pub fg: Option<Color>,
pub bg: Option<Color>,
pub bold: Option<bool>,
pub underline: Option<bool>,
}
impl Style {
pub fn get(&self) -> style::Style {
let mut style = style::Style::new();
if let Some(fg) = &self.fg {
style = style.fg(fg.0);
}
if let Some(bg) = &self.bg {
style = style.bg(bg.0);
}
if let Some(bold) = self.bold {
if bold {
style = style.add_modifier(Modifier::BOLD);
} else {
style = style.remove_modifier(Modifier::BOLD);
}
}
if let Some(underline) = self.underline {
if underline {
style = style.add_modifier(Modifier::UNDERLINED);
} else {
style = style.remove_modifier(Modifier::UNDERLINED);
}
}
style
}
}

View file

@ -1,70 +0,0 @@
use std::path::PathBuf;
use serde::Deserialize;
use super::{ColorGroup, Filetype, Icon, Style};
use crate::{config::MERGED_THEME, misc::absolute_path};
#[derive(Deserialize)]
pub struct Tab {
pub active: Style,
pub inactive: Style,
}
#[derive(Deserialize)]
pub struct Status {
pub primary: ColorGroup,
pub secondary: ColorGroup,
pub tertiary: ColorGroup,
pub body: ColorGroup,
pub emphasis: ColorGroup,
pub info: ColorGroup,
pub success: ColorGroup,
pub warning: ColorGroup,
pub danger: ColorGroup,
}
#[derive(Deserialize)]
pub struct Progress {
pub gauge: Style,
pub label: Style,
}
#[derive(Deserialize)]
pub struct Selection {
pub hovered: Style,
}
#[derive(Deserialize)]
pub struct Marker {
pub selecting: Style,
pub selected: Style,
}
#[derive(Deserialize)]
pub struct Preview {
pub hovered: Style,
pub syntect_theme: PathBuf,
}
#[derive(Deserialize)]
pub struct Theme {
pub tab: Tab,
pub status: Status,
pub progress: Progress,
pub selection: Selection,
pub marker: Marker,
pub preview: Preview,
#[serde(rename = "filetype", deserialize_with = "Filetype::deserialize")]
pub filetypes: Vec<Filetype>,
#[serde(deserialize_with = "Icon::deserialize")]
pub icons: Vec<Icon>,
}
impl Theme {
pub fn new() -> Self {
let mut theme: Self = toml::from_str(&MERGED_THEME).unwrap();
theme.preview.syntect_theme = absolute_path(&theme.preview.syntect_theme);
theme
}
}

View file

@ -1,49 +0,0 @@
use std::io::Write;
use anyhow::Result;
use base64::{engine::general_purpose, Engine};
use image::DynamicImage;
pub struct Kitty;
impl Kitty {
pub fn image_show(img: DynamicImage) -> Result<Vec<u8>> {
fn output(raw: Vec<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,
"\x1b_Ga=d\x1b\\\x1b_Ga=T,f={},s={},v={},m={};{}\x1b\\",
format,
size.0,
size.1,
it.peek().is_some() as u8,
first.iter().collect::<String>(),
)?;
}
while let Some(chunk) = it.next() {
write!(
buf,
"\x1b_Gm={};{}\x1b\\",
it.peek().is_some() as u8,
chunk.iter().collect::<String>()
)?;
}
Ok(buf)
}
let size = (img.width(), img.height());
match img {
DynamicImage::ImageRgb8(v) => output(v.into_raw(), 24, size),
DynamicImage::ImageRgba8(v) => output(v.into_raw(), 32, size),
v => output(v.to_rgb8().into_raw(), 24, size),
}
}
#[inline]
pub fn image_hide() -> &'static [u8; 8] { b"\x1b_Ga=d\x1b\\" }
}

View file

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

View file

@ -1,4 +0,0 @@
use once_cell::sync::Lazy;
use tokio::sync::Semaphore;
pub static BLOCKER: Lazy<Semaphore> = Lazy::new(|| Semaphore::new(1));

View file

@ -1,111 +0,0 @@
use std::{collections::BTreeMap, path::PathBuf};
use anyhow::Result;
use crossterm::event::KeyEvent;
use tokio::sync::{mpsc::Sender, oneshot};
use super::{files::FilesOp, input::InputOpt, manager::PreviewData, select::SelectOpt};
use crate::config::open::Opener;
static mut TX: Option<Sender<Event>> = None;
pub enum Event {
Quit,
Stop(bool, Option<oneshot::Sender<()>>),
Key(KeyEvent),
Render(String),
Resize(u16, u16),
// Manager
Cd(PathBuf),
Refresh,
Files(FilesOp),
Pages(usize),
Mimetype(BTreeMap<PathBuf, String>),
Hover,
Preview(PathBuf, PreviewData),
// Input
Select(SelectOpt, oneshot::Sender<Result<usize>>),
Input(InputOpt, oneshot::Sender<Result<String>>),
// Tasks
Open(Vec<(PathBuf, String)>, Option<Opener>),
Progress(u8, u32),
}
impl Event {
#[inline]
pub fn init(tx: Sender<Event>) {
unsafe {
TX.replace(tx);
}
}
#[inline]
pub fn emit(self) {
let tx = unsafe { TX.as_ref().unwrap() };
tokio::spawn(async {
tx.send(self).await.ok();
});
}
pub async fn wait<T>(self, rx: oneshot::Receiver<T>) -> T {
let tx = unsafe { TX.as_ref().unwrap() };
tx.send(self).await.ok();
rx.await.unwrap()
}
}
#[macro_export]
macro_rules! emit {
(Stop($state:expr)) => {{
let (tx, rx) = tokio::sync::oneshot::channel();
$crate::core::Event::Stop($state, Some(tx)).wait(rx)
}};
(Key($key:expr)) => {
$crate::core::Event::Key($key).emit();
};
(Render) => {
$crate::core::Event::Render(format!("{}:{}", file!(), line!())).emit();
};
(Resize($cols:expr, $rows:expr)) => {
$crate::core::Event::Resize($cols, $rows).emit();
};
(Cd($op:expr)) => {
$crate::core::Event::Cd($op).emit();
};
(Files($op:expr)) => {
$crate::core::Event::Files($op).emit();
};
(Pages($page:expr)) => {
$crate::core::Event::Pages($page).emit();
};
(Mimetype($mimes:expr)) => {
$crate::core::Event::Mimetype($mimes).emit();
};
(Preview($path:expr, $data:expr)) => {
$crate::core::Event::Preview($path, $data).emit();
};
(Select($opt:expr)) => {{
let (tx, rx) = tokio::sync::oneshot::channel();
$crate::core::Event::Select($opt, tx).wait(rx)
}};
(Input($opt:expr)) => {{
let (tx, rx) = tokio::sync::oneshot::channel();
$crate::core::Event::Input($opt, tx).wait(rx)
}};
(Open($targets:expr, $opener:expr)) => {
$crate::core::Event::Open($targets, $opener).emit();
};
(Progress($percent:expr, $tasks:expr)) => {
$crate::core::Event::Progress($percent, $tasks).emit();
};
($event:ident) => {
$crate::core::Event::$event.emit();
};
}

View file

@ -1,39 +0,0 @@
use std::{path::PathBuf, process::Stdio, time::Duration};
use anyhow::Result;
use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::UnboundedReceiver};
use crate::misc::DelayedBuffer;
pub struct FdOpt {
pub cwd: PathBuf,
pub hidden: bool,
pub glob: bool,
pub subject: String,
}
pub fn fd(opt: FdOpt) -> Result<UnboundedReceiver<Vec<PathBuf>>> {
let mut child = Command::new("fd")
.arg("--base-directory")
.arg(&opt.cwd)
.arg(if opt.hidden { "--hidden" } else { "--no-hidden" })
.arg(if opt.glob { "--glob" } else { "--regex" })
.arg(&opt.subject)
.kill_on_drop(true)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
drop(child.stderr.take());
let mut it = BufReader::new(child.stdout.take().unwrap()).lines();
let (mut buf, rx) = DelayedBuffer::new(Duration::from_millis(100));
tokio::spawn(async move {
while let Ok(Some(line)) = it.next_line().await {
buf.push(opt.cwd.join(line));
}
child.wait().await.ok();
});
Ok(rx)
}

View file

@ -1,23 +0,0 @@
use std::path::Path;
use anyhow::{bail, Result};
use tokio::process::Command;
use crate::config::PREVIEW;
pub async fn ffmpegthumbnailer(path: &Path, dest: &Path) -> Result<()> {
let output = Command::new("ffmpegthumbnailer")
.arg("-i")
.arg(path)
.arg("-o")
.arg(dest)
.args(["-q", "6", "-c", "jpeg", "-s", &PREVIEW.max_width.to_string()])
.kill_on_drop(true)
.output()
.await?;
if !output.status.success() {
bail!("failed to generate video thumbnail: {}", String::from_utf8_lossy(&output.stderr));
}
Ok(())
}

View file

@ -1,33 +0,0 @@
use std::{collections::BTreeMap, ffi::OsStr, path::PathBuf};
use anyhow::{bail, Result};
use tokio::process::Command;
use crate::misc::MimeKind;
pub async fn file(files: &[impl AsRef<OsStr>]) -> Result<BTreeMap<PathBuf, String>> {
if files.is_empty() {
bail!("no files to get mime types for");
}
let output = Command::new("file")
.args(["-bL", "--mime-type"])
.args(files)
.kill_on_drop(true)
.output()
.await?;
let output = String::from_utf8_lossy(&output.stdout);
let mimes = BTreeMap::from_iter(
files
.into_iter()
.zip(output.trim().lines())
.filter(|(_, m)| MimeKind::valid(m))
.map(|(f, m)| (f.as_ref().into(), m.to_string())),
);
if mimes.len() == 0 {
bail!("failed to get mime types");
}
Ok(mimes)
}

View file

@ -1,26 +0,0 @@
use std::{path::PathBuf, process::Stdio};
use anyhow::Result;
use tokio::{process::Command, sync::oneshot::{self, Receiver}};
pub struct FzfOpt {
pub cwd: PathBuf,
}
pub fn fzf(opt: FzfOpt) -> Result<Receiver<Result<PathBuf>>> {
let child =
Command::new("fzf").current_dir(&opt.cwd).kill_on_drop(true).stdout(Stdio::piped()).spawn()?;
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Ok(output) = child.wait_with_output().await {
let selected = String::from_utf8_lossy(&output.stdout).trim().to_string();
if !selected.is_empty() {
tx.send(Ok(opt.cwd.join(selected))).ok();
return;
}
}
tx.send(Err(anyhow::anyhow!("No match"))).ok();
});
Ok(rx)
}

View file

@ -1,20 +0,0 @@
use std::path::Path;
use anyhow::{bail, Result};
use tokio::process::Command;
use crate::config::PREVIEW;
pub async fn jq(path: &Path) -> Result<String> {
let output = Command::new("jq")
.args(["-C", "--indent", &PREVIEW.tab_size.to_string(), "."])
.arg(path)
.kill_on_drop(true)
.output()
.await?;
if !output.status.success() {
bail!("failed to get json: {}", String::from_utf8_lossy(&output.stderr));
}
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
}

View file

@ -1,63 +0,0 @@
use std::path::Path;
use anyhow::{bail, Result};
use serde::Deserialize;
use serde_json::Value;
use tokio::process::Command;
#[derive(Debug)]
pub enum LsarAttr {
Posix(u16),
Windows(u16),
Dos(u8),
}
#[derive(Debug, Deserialize)]
pub struct LsarFile {
#[serde(rename = "XADFileName")]
pub name: String,
#[serde(rename = "XADLastModificationDate")]
pub last_modified: String,
#[serde(rename = "XADFileSize")]
pub size: Option<usize>,
#[serde(rename = "XADCompressedSize")]
pub compressed_size: Option<usize>,
#[serde(rename = "XADCompressionName")]
pub compression_name: Option<String>,
#[serde(skip)]
pub attributes: Option<LsarAttr>,
}
pub async fn lsar(path: &Path) -> Result<Vec<LsarFile>> {
let output =
Command::new("lsar").args(["-j", "-jss"]).arg(path).kill_on_drop(true).output().await?;
if !output.status.success() {
bail!("failed to get json: {}", String::from_utf8_lossy(&output.stderr));
}
#[derive(Deserialize)]
struct Outer {
#[serde(rename = "lsarContents")]
contents: Vec<Value>,
}
let output = String::from_utf8_lossy(&output.stdout);
let contents = serde_json::from_str::<Outer>(output.trim())?.contents;
let mut files = Vec::with_capacity(contents.len());
for content in contents {
let mut file = serde_json::from_value::<LsarFile>(content.clone())?;
if let Some(p) = content.get("XADPosixPermissions").and_then(|p| p.as_u64()) {
file.attributes = Some(LsarAttr::Posix(p as u16));
} else if let Some(a) = content.get("XADWindowsFileAttributes").and_then(|a| a.as_u64()) {
file.attributes = Some(LsarAttr::Windows(a as u16));
} else if let Some(a) = content.get("XADDOSFileAttributes").and_then(|a| a.as_u64()) {
file.attributes = Some(LsarAttr::Dos(a as u8));
}
files.push(file);
}
Ok(files)
}

View file

@ -1,19 +0,0 @@
mod fd;
mod ffmpegthumbnailer;
mod file;
mod fzf;
mod jq;
mod lsar;
mod rg;
mod unar;
mod zoxide;
pub use fd::*;
pub use ffmpegthumbnailer::*;
pub use file::*;
pub use fzf::*;
pub use jq::*;
pub use lsar::*;
pub use rg::*;
pub use unar::*;
pub use zoxide::*;

View file

@ -1,37 +0,0 @@
use std::{path::PathBuf, process::Stdio, time::Duration};
use anyhow::Result;
use tokio::{io::{AsyncBufReadExt, BufReader}, process::Command, sync::mpsc::UnboundedReceiver};
use crate::misc::DelayedBuffer;
pub struct RgOpt {
pub cwd: PathBuf,
pub hidden: bool,
pub subject: String,
}
pub fn rg(opt: RgOpt) -> Result<UnboundedReceiver<Vec<PathBuf>>> {
let mut child = Command::new("rg")
.current_dir(&opt.cwd)
.args(&["--color=never", "--files-with-matches", "--smart-case"])
.arg(if opt.hidden { "--hidden" } else { "--no-hidden" })
.arg(&opt.subject)
.kill_on_drop(true)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
drop(child.stderr.take());
let mut it = BufReader::new(child.stdout.take().unwrap()).lines();
let (mut buf, rx) = DelayedBuffer::new(Duration::from_millis(100));
tokio::spawn(async move {
while let Ok(Some(line)) = it.next_line().await {
buf.push(opt.cwd.join(line));
}
child.wait().await.ok();
});
Ok(rx)
}

View file

@ -1,25 +0,0 @@
use std::{path::Path, process::Stdio};
use anyhow::{bail, Result};
use tokio::{io::{AsyncReadExt, BufReader}, process::Command};
pub async fn unar_head(path: &Path, target: &Path) -> Result<Vec<u8>> {
let mut child = Command::new("unar")
.args(&[path, target])
.args(&["-o", "-"])
.stdout(Stdio::piped())
.stderr(Stdio::null())
.kill_on_drop(true)
.spawn()?;
let mut buf = vec![0; 1024];
let mut reader = BufReader::new(child.stdout.take().unwrap());
reader.read(&mut buf).await.ok();
child.kill().await.ok();
if buf.is_empty() {
bail!("failed to get head of unar");
}
Ok(buf)
}

View file

@ -1,30 +0,0 @@
use std::{path::PathBuf, process::Stdio};
use anyhow::Result;
use tokio::{process::Command, sync::oneshot::{self, Receiver}};
pub struct ZoxideOpt {
pub cwd: PathBuf,
}
pub fn zoxide(opt: ZoxideOpt) -> Result<Receiver<Result<PathBuf>>> {
let child = Command::new("zoxide")
.args(&["query", "-i", "--exclude"])
.arg(opt.cwd)
.kill_on_drop(true)
.stdout(Stdio::piped())
.spawn()?;
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Ok(output) = child.wait_with_output().await {
let selected = String::from_utf8_lossy(&output.stdout).trim().to_string();
if !selected.is_empty() {
tx.send(Ok(selected.into())).ok();
return;
}
}
tx.send(Err(anyhow::anyhow!("No match"))).ok();
});
Ok(rx)
}

View file

@ -1,49 +0,0 @@
use std::{fs::Metadata, path::{Path, PathBuf}};
use anyhow::Result;
use tokio::fs;
#[derive(Clone, Debug)]
pub struct File {
pub path: PathBuf,
pub meta: Metadata,
pub length: Option<u64>,
pub is_link: bool,
pub is_hidden: bool,
pub is_selected: bool,
}
impl File {
#[inline]
pub async fn from(path: &Path) -> Result<File> {
let meta = fs::metadata(path).await?;
Ok(Self::from_meta(path, meta).await)
}
pub async fn from_meta(path: &Path, mut meta: Metadata) -> File {
let is_link = meta.is_symlink();
if is_link {
meta = fs::metadata(&path).await.unwrap_or(meta);
}
let length = if meta.is_dir() { None } else { Some(meta.len()) };
let is_hidden = path.file_name().map(|s| s.to_string_lossy().starts_with('.')).unwrap_or(false);
File { path: path.to_path_buf(), meta, length, is_link, is_hidden, is_selected: false }
}
}
impl File {
#[inline]
pub fn path(&self) -> PathBuf { self.path.clone() }
#[inline]
pub fn set_path(mut self, path: &Path) -> Self {
self.path = path.to_path_buf();
self
}
#[inline]
pub fn name(&self) -> Option<String> {
self.path.file_name().map(|s| s.to_string_lossy().to_string())
}
}

View file

@ -1,147 +0,0 @@
use std::{ops::{Deref, DerefMut}, path::{Path, PathBuf}};
use anyhow::Result;
use indexmap::IndexMap;
use tokio::fs;
use super::File;
use crate::config::{manager::SortBy, MANAGER};
#[derive(Default)]
pub struct Files {
items: IndexMap<PathBuf, File>,
sort: FilesSort,
pub show_hidden: bool,
}
impl Files {
pub async fn read(paths: Vec<PathBuf>) -> IndexMap<PathBuf, File> {
let mut items = IndexMap::new();
for path in paths {
if let Ok(file) = File::from(&path).await {
items.insert(path, file);
}
}
items
}
pub async fn read_dir(path: &Path) -> Result<IndexMap<PathBuf, File>> {
let mut it = fs::read_dir(path).await?;
let mut items = IndexMap::new();
while let Ok(Some(item)) = it.next_entry().await {
if let Ok(meta) = item.metadata().await {
let path = item.path();
let file = File::from_meta(&path, meta).await;
items.insert(path, file);
}
}
Ok(items)
}
pub fn sort(&mut self) {
fn cmp<T: Ord>(a: T, b: T, reverse: bool) -> std::cmp::Ordering {
if reverse { b.cmp(&a) } else { a.cmp(&b) }
}
let reverse = self.sort.reverse;
match self.sort.by {
SortBy::Alphabetical => self.items.sort_by(|_, a, _, b| cmp(&a.path, &b.path, reverse)),
SortBy::Created => self.items.sort_by(|_, a, _, b| {
if let (Ok(a), Ok(b)) = (a.meta.created(), b.meta.created()) {
return cmp(a, b, reverse);
}
std::cmp::Ordering::Equal
}),
SortBy::Modified => self.items.sort_by(|_, a, _, b| {
if let (Ok(a), Ok(b)) = (a.meta.modified(), b.meta.modified()) {
return cmp(a, b, reverse);
}
std::cmp::Ordering::Equal
}),
SortBy::Size => {
self.items.sort_by(|_, a, _, b| cmp(a.length.unwrap_or(0), b.length.unwrap_or(0), reverse))
}
}
}
#[inline]
pub fn duplicate(&self, idx: usize) -> Option<File> {
self.items.get_index(idx).map(|(_, file)| file.clone())
}
pub fn update_read(&mut self, mut items: IndexMap<PathBuf, File>) -> bool {
if !self.show_hidden {
items.retain(|_, item| !item.is_hidden);
}
for (path, item) in &mut items {
if let Some(old) = self.items.get(path) {
item.length = old.length;
item.is_selected = old.is_selected;
}
}
self.items = items;
self.sort();
true
}
pub fn update_search(&mut self, items: IndexMap<PathBuf, File>) -> bool {
if !items.is_empty() {
self.items.extend(items);
self.sort();
return true;
}
if !self.items.is_empty() {
self.items.clear();
return true;
}
false
}
}
impl Deref for Files {
type Target = IndexMap<PathBuf, File>;
fn deref(&self) -> &Self::Target { &self.items }
}
impl DerefMut for Files {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.items }
}
struct FilesSort {
pub by: SortBy,
pub reverse: bool,
}
impl Default for FilesSort {
fn default() -> Self { Self { by: MANAGER.sort_by, reverse: MANAGER.sort_reverse } }
}
#[derive(Debug)]
pub enum FilesOp {
Read(PathBuf, IndexMap<PathBuf, File>),
IOErr(PathBuf),
Search(PathBuf, IndexMap<PathBuf, File>),
}
impl FilesOp {
#[inline]
pub fn path(&self) -> PathBuf {
match self {
Self::Read(path, _) => path,
Self::IOErr(path) => path,
Self::Search(path, _) => path,
}
.clone()
}
#[inline]
pub fn read_empty(path: &Path) -> Self { Self::Read(path.to_path_buf(), IndexMap::new()) }
#[inline]
pub fn search_empty(path: &Path) -> Self { Self::Search(path.to_path_buf(), IndexMap::new()) }
}

View file

@ -1,5 +0,0 @@
mod file;
mod files;
pub use file::*;
pub use files::*;

View file

@ -1,297 +0,0 @@
use anyhow::{anyhow, Result};
use ratatui::layout::Rect;
use tokio::sync::oneshot::Sender;
use unicode_width::UnicodeWidthStr;
use crate::{core::Position, misc::CharKind};
#[derive(Default)]
pub struct Input {
title: String,
value: String,
position: (u16, u16),
op: InputOp,
range: Option<(usize, usize)>,
mode: InputMode,
offset: usize,
cursor: usize,
callback: Option<Sender<Result<String>>>,
pub visible: bool,
}
pub struct InputOpt {
pub title: String,
pub value: String,
pub position: Position,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum InputMode {
Normal,
#[default]
Insert,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum InputOp {
#[default]
None,
Delete(bool),
Yank,
}
impl Input {
pub fn show(&mut self, opt: InputOpt, tx: Sender<Result<String>>) {
self.close(false);
self.title = opt.title;
self.value = opt.value;
self.position = match opt.position {
Position::Coords(x, y) => (x, y),
_ => unimplemented!(),
};
self.cursor = self.count();
self.offset = self.value.width().saturating_sub(50);
self.callback = Some(tx);
self.visible = true;
}
pub fn close(&mut self, submit: bool) -> bool {
if let Some(cb) = self.callback.take() {
let _ = cb.send(if submit { Ok(self.value.clone()) } else { Err(anyhow!("canceled")) });
}
self.mode = InputMode::Insert;
self.visible = false;
true
}
pub fn escape(&mut self) -> bool {
match self.mode {
InputMode::Normal => {
self.range = None;
}
InputMode::Insert => {
self.mode = InputMode::Normal;
self.move_(-1);
}
}
true
}
pub fn insert(&mut self, append: bool) -> bool {
if self.mode != InputMode::Normal {
return false;
}
self.mode = InputMode::Insert;
if append {
self.move_(1);
}
true
}
pub fn visual(&mut self) -> bool {
if self.mode != InputMode::Normal {
return false;
}
self.range = Some((self.cursor, self.cursor));
true
}
pub fn move_(&mut self, step: isize) -> bool {
let old = self.cursor;
let mut include = false;
if step <= 0 {
self.cursor = self.cursor.saturating_sub(step.abs() as usize);
} else {
let count = self.count();
self.cursor += step as usize;
if self.cursor >= count {
include = true;
self.cursor = if self.mode == InputMode::Insert { count } else { count.saturating_sub(1) };
}
}
if self.cursor != old {
if self.cursor < self.offset {
self.offset = self.cursor;
} else if self.cursor > self.offset + 50 {
self.offset = self.cursor.saturating_sub(50);
}
}
self.handle_op(include) || self.cursor != old
}
pub fn backward(&mut self) -> bool {
if self.cursor == 0 {
return self.handle_op(false);
}
let idx = self.idx(self.cursor).unwrap_or(self.value.len());
let mut it = self.value[..idx].chars().rev().enumerate();
let mut prev = CharKind::new(it.next().unwrap().1);
for (i, c) in it {
let c = CharKind::new(c);
if prev != CharKind::Space && prev != c {
return self.move_(-(i as isize));
}
prev = c;
}
if prev != CharKind::Space {
return self.move_(-(self.value.len() as isize));
}
false
}
pub fn forward(&mut self, end: bool) -> bool {
if self.value.is_empty() {
return self.handle_op(false);
}
let mut it = self.value.chars().skip(self.cursor).enumerate();
let mut prev = CharKind::new(it.next().unwrap().1);
for (i, c) in it {
let c = CharKind::new(c);
let b = if end {
prev != CharKind::Space && prev != c && i != 1
} else {
c != CharKind::Space && c != prev
};
if b {
return self.move_(if end { i - 1 } else { i } as isize);
}
prev = c;
}
self.move_(self.value.len() as isize)
}
pub fn type_(&mut self, c: char) -> bool {
if self.cursor < 1 {
self.value.insert(0, c);
} else if self.cursor == self.count() {
self.value.push(c);
} else {
self.value.insert(self.idx(self.cursor).unwrap(), c);
}
self.move_(1)
}
pub fn backspace(&mut self) -> bool {
if self.cursor < 1 {
return false;
} else if self.cursor == self.count() {
self.value.pop();
} else {
self.value.remove(self.idx(self.cursor - 1).unwrap());
}
self.move_(-1)
}
pub fn delete(&mut self, insert: bool) -> bool {
match self.op {
InputOp::None => {
self.op = InputOp::Delete(insert);
if self.range.is_some() {
return self.handle_op(true);
}
self.range = Some((self.cursor, self.cursor));
false
}
InputOp::Delete(_) => {
self.move_(-(self.value.len() as isize));
self.value.clear();
self.op = InputOp::None;
self.range = None;
self.mode = if insert { InputMode::Insert } else { InputMode::Normal };
true
}
_ => false,
}
}
fn handle_op(&mut self, include: bool) -> bool {
if let Some(ref mut range) = self.range {
*range = (range.0.min(self.cursor), range.0.max(self.cursor));
}
match self.op {
InputOp::None => return false,
InputOp::Delete(insert) => {
let range = self.range.take().unwrap();
if !self.value.is_empty() {
let (start, end) = (self.idx(range.0), self.idx(range.1 + include as usize));
self.value.drain(start.unwrap()..end.unwrap());
}
self.mode = if insert {
self.cursor = range.0.min(self.count());
InputMode::Insert
} else {
self.cursor = range.0.min(self.count().saturating_sub(1));
InputMode::Normal
};
}
InputOp::Yank => {}
}
self.op = InputOp::None;
true
}
}
impl Input {
#[inline]
pub fn title(&self) -> String { self.title.clone() }
#[inline]
pub fn value(&self) -> String { self.value.clone() }
#[inline]
pub fn area(&self) -> Rect {
Rect { x: self.position.0, y: self.position.1 + 2, width: 50, height: 3 }
}
#[inline]
pub fn mode(&self) -> InputMode { self.mode }
#[inline]
pub fn cursor(&self) -> (u16, u16) {
let width = self
.value
.chars()
.enumerate()
.take_while(|(i, _)| *i < self.cursor)
.map(|(_, c)| c)
.collect::<String>()
.width() as u16;
let area = self.area();
(area.x + width + 1, area.y + 1)
}
#[inline]
fn count(&self) -> usize { self.value.chars().count() }
#[inline]
fn idx(&self, n: usize) -> Option<usize> {
self
.value
.char_indices()
.nth(n)
.map(|(i, _)| i)
.or_else(|| if n == self.count() { Some(self.value.len()) } else { None })
}
}

View file

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

View file

@ -1,202 +0,0 @@
use std::path::{Path, PathBuf};
use indexmap::map::Slice;
use ratatui::layout::Rect;
use super::{ALL_RATIO, CURRENT_RATIO, DIR_PADDING, PARENT_RATIO};
use crate::{core::files::{File, Files, FilesOp}, emit, misc::tty_size};
#[derive(Default)]
pub struct Folder {
pub cwd: PathBuf,
pub files: Files,
offset: usize,
cursor: usize,
pub page: usize,
pub hovered: Option<File>,
pub in_search: bool,
}
impl Folder {
pub fn new(cwd: &Path) -> Self { Self { cwd: cwd.to_path_buf(), ..Default::default() } }
pub fn new_search(cwd: &Path) -> Self {
Self { cwd: cwd.to_path_buf(), in_search: true, ..Default::default() }
}
#[inline]
pub fn limit() -> usize { tty_size().ws_row.saturating_sub(DIR_PADDING) as usize }
pub fn update(&mut self, op: FilesOp) -> bool {
let b = match op {
FilesOp::Read(_, items) => self.files.update_read(items),
FilesOp::Search(_, items) => self.files.update_search(items),
_ => unreachable!(),
};
if !b {
return false;
}
let len = self.files.len();
self.offset = self.offset.min(len);
self.cursor = self.cursor.min(len.saturating_sub(1));
self.set_page(true);
if let Some(h) = self.hovered.as_ref().map(|h| h.path()) {
self.hover(&h);
}
self.hovered = self.files.duplicate(self.cursor);
true
}
pub fn set_page(&mut self, force: bool) -> bool {
let limit = Self::limit();
let new = if limit == 0 { 0 } else { self.cursor / limit };
if !force && self.page == new {
return false;
}
self.page = new;
emit!(Pages(new));
true
}
pub fn next(&mut self, step: usize) -> bool {
let len = self.files.len();
if len == 0 {
return false;
}
let old = self.cursor;
self.cursor = (self.cursor + step).min(len - 1);
self.hovered = self.files.duplicate(self.cursor);
self.set_page(false);
let limit = Self::limit();
if self.cursor >= (self.offset + limit).min(len).saturating_sub(5) {
self.offset = len.saturating_sub(limit).min(self.offset + self.cursor - old);
}
old != self.cursor
}
pub fn prev(&mut self, step: usize) -> bool {
let old = self.cursor;
self.cursor = self.cursor.saturating_sub(step);
self.hovered = self.files.duplicate(self.cursor);
self.set_page(false);
if self.cursor < self.offset + 5 {
self.offset = self.offset.saturating_sub(old - self.cursor);
}
old != self.cursor
}
pub fn hidden(&mut self, show: Option<bool>) -> bool {
if show.is_none() || self.files.show_hidden != show.unwrap() {
self.files.show_hidden = !self.files.show_hidden;
emit!(Refresh);
}
false
}
#[inline]
pub fn window(&self) -> &Slice<PathBuf, File> {
let end = (self.offset + Self::limit()).min(self.files.len());
self.files.get_range(self.offset..end).unwrap()
}
pub fn select(&mut self, idx: Option<usize>, state: Option<bool>) -> bool {
let len = self.files.len();
let mut apply = |idx: usize, state: Option<bool>| -> bool {
if state.is_none() {
self.files[idx].is_selected = !self.files[idx].is_selected;
return true;
}
let state = state.unwrap();
if state != self.files[idx].is_selected {
self.files[idx].is_selected = state;
return true;
}
false
};
if let Some(idx) = idx {
if idx < len {
return apply(idx, state);
}
} else {
let mut applied = false;
for i in 0..len {
if apply(i, state) {
applied = true;
}
}
return applied;
}
false
}
pub fn hover(&mut self, path: &Path) -> bool {
if matches!(self.hovered, Some(ref h) if h.path == path) {
return false;
}
let new = self.position(path).unwrap_or(self.cursor);
if new > self.cursor { self.next(new - self.cursor) } else { self.prev(self.cursor - new) }
}
pub fn hover_force(&mut self, file: File) -> bool {
if !self.hover(&file.path) && self.files.is_empty() {
self.hovered = Some(file);
return true;
}
false
}
}
impl Folder {
#[inline]
pub fn cursor(&self) -> usize { self.cursor }
#[inline]
pub fn position(&self, path: &Path) -> Option<usize> {
self.files.iter().position(|(p, _)| p == path)
}
pub fn paginate(&self) -> &Slice<PathBuf, File> {
let len = self.files.len();
let limit = Self::limit();
let start = (self.page * limit).min(len.saturating_sub(1));
let end = (start + limit).min(len);
self.files.get_range(start..end).unwrap()
}
#[inline]
pub fn has_selected(&self) -> bool { self.files.iter().any(|(_, item)| item.is_selected) }
pub fn selected(&self) -> Option<Vec<&File>> {
let v = self.files.iter().filter(|(_, f)| f.is_selected).map(|(_, f)| f).collect::<Vec<_>>();
if v.is_empty() { None } else { Some(v) }
}
pub fn rect_current(&self, path: &Path) -> Option<Rect> {
let pos = self.position(path)? - self.offset;
let s = tty_size();
Some(Rect {
x: (s.ws_col as u32 * PARENT_RATIO / ALL_RATIO) as u16,
y: pos as u16,
width: (s.ws_col as u32 * CURRENT_RATIO / ALL_RATIO) as u16,
height: 1,
})
}
}

View file

@ -1,334 +0,0 @@
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, mem, path::PathBuf};
use tokio::fs;
use super::{PreviewData, Tab, Tabs, Watcher};
use crate::{config::OPEN, core::{external, files::{File, FilesOp}, input::InputOpt, manager::Folder, select::SelectOpt, tasks::Tasks, Position}, emit};
pub struct Manager {
tabs: Tabs,
yanked: (bool, HashSet<PathBuf>),
watcher: Watcher,
pub mimetype: HashMap<PathBuf, String>,
}
impl Manager {
pub fn new() -> Self {
Self {
tabs: Tabs::new(),
yanked: Default::default(),
watcher: Watcher::start(),
mimetype: Default::default(),
}
}
pub fn refresh(&mut self) {
self.watcher.trigger(&self.current().cwd);
if let Some(p) = self.parent() {
self.watcher.trigger(&p.cwd);
}
emit!(Hover);
let mut to_watch = BTreeSet::new();
for tab in self.tabs.iter() {
to_watch.insert(tab.current.cwd.clone());
if let Some(ref p) = tab.parent {
to_watch.insert(p.cwd.clone());
}
if let Some(ref h) = tab.current.hovered {
if h.meta.is_dir() {
to_watch.insert(h.path());
}
}
}
self.watcher.watch(to_watch);
}
pub fn preview(&mut self) -> bool {
let hovered = if let Some(h) = self.hovered() {
h.clone()
} else {
return self.active_mut().preview.reset();
};
if hovered.meta.is_dir() {
self.active_mut().preview.go(&hovered.path, "inode/directory");
if self.active().history(&hovered.path).is_some() {
emit!(Preview(hovered.path, PreviewData::Folder));
}
} else if let Some(mime) = self.mimetype.get(&hovered.path).cloned() {
self.active_mut().preview.go(&hovered.path, &mime);
} else {
tokio::spawn(async move {
if let Ok(mimes) = external::file(&[hovered.path]).await {
emit!(Mimetype(mimes));
}
});
}
false
}
pub fn yank(&mut self, cut: bool) -> bool {
let selected = self.selected().into_iter().map(|f| f.path()).collect::<Vec<_>>();
self.yanked.0 = cut;
self.yanked.1.clear();
self.yanked.1.extend(selected);
false
}
#[inline]
pub fn yanked(&self) -> &(bool, HashSet<PathBuf>) { &self.yanked }
pub fn quit(&self, tasks: &Tasks) -> bool {
let tasks = tasks.len();
if tasks == 0 {
emit!(Quit);
return false;
}
tokio::spawn(async move {
let result = emit!(Input(InputOpt {
title: format!("There are {} tasks running, sure to quit? (y/N)", tasks),
value: "".to_string(),
position: Position::Top,
}))
.await;
if let Ok(choice) = result {
if choice.to_lowercase() == "y" {
emit!(Quit);
}
}
});
false
}
pub fn close(&mut self, tasks: &Tasks) -> bool {
if self.tabs.len() > 1 {
return self.tabs.close(self.tabs.idx());
}
self.quit(tasks)
}
pub fn open(&mut self, select: bool) -> bool {
let mut files = self
.selected()
.into_iter()
.filter(|f| f.meta.is_file())
.map(|f| (f.path(), self.mimetype.get(&f.path).cloned()))
.collect::<Vec<_>>();
if files.is_empty() {
return false;
}
tokio::spawn(async move {
let todo = files.iter().filter(|(_, m)| m.is_none()).map(|(p, _)| p).collect::<Vec<_>>();
if let Ok(mut mimes) = external::file(&todo).await {
files = files
.into_iter()
.map(|(p, m)| {
let mime = m.or_else(|| mimes.remove(&p));
(p, mime)
})
.collect::<Vec<_>>();
}
let files = files.into_iter().filter_map(|(p, m)| m.map(|m| (p, m))).collect::<Vec<_>>();
if !select {
emit!(Open(files, None));
return;
}
let openers = OPEN.common_openers(&files);
if openers.is_empty() {
return;
}
let result = emit!(Select(SelectOpt {
title: "Open with:".to_string(),
items: openers.iter().map(|o| o.cmd.clone()).collect(),
position: Position::Hovered,
}))
.await;
if let Ok(choice) = result {
emit!(Open(files, Some(openers[choice].clone())));
}
});
false
}
pub fn create(&self) -> bool {
let cwd = self.current().cwd.clone();
tokio::spawn(async move {
let result = emit!(Input(InputOpt {
title: "Create:".to_string(),
value: "".to_string(),
position: Position::Top,
}))
.await;
if let Ok(name) = result {
let path = cwd.join(&name);
if name.ends_with('/') {
fs::create_dir_all(path).await.ok();
} else {
fs::create_dir_all(path.parent().unwrap()).await.ok();
fs::File::create(path).await.ok();
}
}
});
false
}
pub fn rename(&self) -> bool {
if self.current().has_selected() {
return self.bulk_rename();
}
let hovered = if let Some(h) = self.hovered() {
h.path.clone()
} else {
return false;
};
tokio::spawn(async move {
let result = emit!(Input(InputOpt {
title: "Rename:".to_string(),
value: hovered.file_name().unwrap().to_string_lossy().to_string(),
position: Position::Hovered,
}))
.await;
if let Ok(new) = result {
let to = hovered.parent().unwrap().join(new);
fs::rename(&hovered, to).await.ok();
}
});
false
}
fn bulk_rename(&self) -> bool { false }
pub fn selected(&self) -> Vec<&File> {
self.current().selected().or_else(|| self.hovered().map(|h| vec![h])).unwrap_or_default()
}
pub fn update_read(&mut self, op: FilesOp) -> bool {
let path = op.path();
let cwd = self.current().cwd.clone();
let hovered = self.hovered().map(|h| h.path());
let mut b = if cwd == path && !self.current().in_search {
self.current_mut().update(op)
} else if matches!(self.parent(), Some(p) if p.cwd == path) {
self.active_mut().parent.as_mut().unwrap().update(op)
} else {
self
.active_mut()
.history
.entry(path.to_path_buf())
.or_insert_with(|| Folder::new(&path))
.update(op);
matches!(self.hovered(), Some(h) if h.path == path)
};
b |= self.active_mut().parent.as_mut().map_or(false, |p| p.hover(&cwd));
b |= hovered.as_ref().map_or(false, |h| self.current_mut().hover(h));
if hovered != self.hovered().map(|h| h.path()) {
emit!(Hover);
}
b
}
pub fn update_ioerr(&mut self, op: FilesOp) -> bool {
let path = op.path();
let op = FilesOp::read_empty(&path);
if path == self.current().cwd {
self.current_mut().update(op);
} else if matches!(self.parent(), Some(p) if p.cwd == path) {
self.active_mut().parent.as_mut().unwrap().update(op);
} else {
return false;
}
self.active_mut().leave();
true
}
pub fn update_search(&mut self, op: FilesOp) -> bool {
let path = op.path();
if self.current().in_search && self.current().cwd == path {
return self.current_mut().update(op);
}
let rep = mem::replace(self.current_mut(), Folder::new_search(&path));
if !rep.in_search {
self.active_mut().history.insert(path, rep);
}
self.current_mut().update(op);
true
}
pub fn update_mimetype(&mut self, mut mimes: BTreeMap<PathBuf, String>, tasks: &Tasks) -> bool {
mimes.retain(|f, m| self.mimetype.get(f) != Some(m));
if mimes.is_empty() {
return false;
}
tasks.precache_image(&mimes);
tasks.precache_video(&mimes);
self.mimetype.extend(mimes);
self.preview();
true
}
pub fn update_preview(&mut self, path: PathBuf, data: PreviewData) -> bool {
let hovered = if let Some(ref h) = self.current().hovered {
h.path()
} else {
return self.active_mut().preview.reset();
};
if hovered != path {
return false;
}
let preview = &mut self.active_mut().preview;
preview.path = path;
preview.data = data;
true
}
}
impl Manager {
#[inline]
pub fn tabs(&self) -> &Tabs { &self.tabs }
#[inline]
pub fn tabs_mut(&mut self) -> &mut Tabs { &mut self.tabs }
#[inline]
pub fn active(&self) -> &Tab { self.tabs.active() }
#[inline]
pub fn active_mut(&mut self) -> &mut Tab { self.tabs.active_mut() }
#[inline]
pub fn current(&self) -> &Folder { &self.tabs.active().current }
#[inline]
pub fn current_mut(&mut self) -> &mut Folder { &mut self.tabs.active_mut().current }
#[inline]
pub fn parent(&self) -> Option<&Folder> { self.tabs.active().parent.as_ref() }
#[inline]
pub fn hovered(&self) -> Option<&File> { self.tabs.active().current.hovered.as_ref() }
}

View file

@ -1,25 +0,0 @@
mod folder;
mod manager;
mod mode;
mod preview;
mod tab;
mod tabs;
mod watcher;
pub use folder::*;
pub use manager::*;
pub use mode::*;
pub use preview::*;
pub use tab::*;
pub use tabs::*;
pub use watcher::*;
pub const PARENT_RATIO: u32 = 1;
pub const CURRENT_RATIO: u32 = 4;
pub const PREVIEW_RATIO: u32 = 3;
pub const ALL_RATIO: u32 = PARENT_RATIO + CURRENT_RATIO + PREVIEW_RATIO;
pub const DIR_PADDING: u16 = 2;
pub const PREVIEW_BORDER: u16 = 2;
pub const PREVIEW_PADDING: u16 = 2;

View file

@ -1,41 +0,0 @@
use std::fmt::Display;
use crate::config::theme::{self, ColorGroup};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
#[default]
Normal,
Select(usize),
Unselect(usize),
}
impl Mode {
#[inline]
pub fn color<'a>(&self, group: &'a ColorGroup) -> &'a theme::Color {
match *self {
Mode::Normal => &group.normal,
Mode::Select(_) => &group.select,
Mode::Unselect(_) => &group.unselect,
}
}
#[inline]
pub fn start(&self) -> Option<usize> {
match self {
Mode::Normal => None,
Mode::Select(n) => Some(*n),
Mode::Unselect(n) => Some(*n),
}
}
}
impl Display for Mode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
Mode::Normal => write!(f, "NORMAL"),
Mode::Select(_) => write!(f, "SELECT"),
Mode::Unselect(_) => write!(f, "UN-SEL"),
}
}
}

View file

@ -1,170 +0,0 @@
use std::{fs::File, io::{BufRead, BufReader}, path::{Path, PathBuf}, sync::OnceLock};
use anyhow::{anyhow, Result};
use image::imageops::FilterType;
use syntect::{easy::HighlightFile, highlighting::{Theme, ThemeSet}, parsing::SyntaxSet, util::as_24_bit_terminal_escaped};
use tokio::{fs, task::JoinHandle};
use super::{ALL_RATIO, PREVIEW_BORDER, PREVIEW_PADDING, PREVIEW_RATIO};
use crate::{config::{PREVIEW, THEME}, core::{adapter::Kitty, external, files::{Files, FilesOp}, tasks::Precache}, emit, misc::{tty_ratio, tty_size, MimeKind}};
static SYNTECT_SYNTAX: OnceLock<SyntaxSet> = OnceLock::new();
static SYNTECT_THEME: OnceLock<Theme> = OnceLock::new();
#[derive(Debug)]
pub struct Preview {
pub path: PathBuf,
pub data: PreviewData,
handle: Option<JoinHandle<()>>,
}
#[derive(Debug, Default)]
pub enum PreviewData {
#[default]
None,
Folder,
Text(String),
Image(Vec<u8>),
}
impl Preview {
pub fn new() -> Self {
Self { path: Default::default(), data: Default::default(), handle: Default::default() }
}
fn size() -> (u16, u16) {
let s = tty_size();
let col = (s.ws_col as u32 * PREVIEW_RATIO / ALL_RATIO) as u16;
(col.saturating_sub(PREVIEW_BORDER), s.ws_row.saturating_sub(PREVIEW_PADDING))
}
pub fn go(&mut self, path: &Path, mime: &str) {
if let Some(handle) = self.handle.take() {
handle.abort();
}
let (path, mime) = (path.to_path_buf(), mime.to_owned());
self.handle = Some(tokio::spawn(async move {
let result = match MimeKind::new(&mime) {
MimeKind::Dir => Self::folder(&path).await,
MimeKind::JSON => Self::json(&path).await.map(PreviewData::Text),
MimeKind::Text => Self::highlight(&path).await.map(PreviewData::Text),
MimeKind::Image => Self::image(&path).await.map(PreviewData::Image),
MimeKind::Video => Self::video(&path).await.map(PreviewData::Image),
MimeKind::Archive => Self::archive(&path).await.map(PreviewData::Text),
MimeKind::Others => Err(anyhow!("Unsupported mimetype: {}", mime)),
};
emit!(Preview(path, result.unwrap_or_default()));
}));
}
pub fn reset(&mut self) -> bool {
if self.path == PathBuf::default() {
return false;
}
self.path = Default::default();
self.data = Default::default();
true
}
pub async fn folder(path: &Path) -> Result<PreviewData> {
emit!(Files(match Files::read_dir(&path).await {
Ok(items) => FilesOp::Read(path.to_path_buf(), items),
Err(_) => FilesOp::IOErr(path.to_path_buf()),
}));
Ok(PreviewData::Folder)
}
pub async fn image(mut path: &Path) -> Result<Vec<u8>> {
let cache = Precache::cache(path);
if fs::metadata(&cache).await.is_ok() {
path = cache.as_path();
}
let (w, h) = {
let r = tty_ratio();
let (w, h) = Self::size();
let (w, h) = ((w as f64 * r.0) as u32, (h as f64 * r.1) as u32);
(w.min(PREVIEW.max_width), h.min(PREVIEW.max_height))
};
let file = fs::read(path).await?;
tokio::task::spawn_blocking(move || -> Result<Vec<u8>> {
let img = image::load_from_memory(&file)?;
Kitty::image_show(if img.width() > w || img.height() > h {
img.resize(w, h, FilterType::Triangle)
} else {
img
})
})
.await?
}
pub async fn video(path: &Path) -> Result<Vec<u8>> {
let cache = Precache::cache(path);
if fs::metadata(&cache).await.is_err() {
external::ffmpegthumbnailer(path, &cache).await?;
}
Self::image(&cache).await
}
pub async fn json(path: &Path) -> Result<String> {
Ok(
external::jq(path)
.await?
.lines()
.take(Self::size().1 as usize)
.collect::<Vec<_>>()
.join("\n"),
)
}
pub async fn archive(path: &Path) -> Result<String> {
Ok(
external::lsar(path)
.await?
.into_iter()
.take(Self::size().1 as usize)
.map(|f| f.name)
.collect::<Vec<_>>()
.join("\n"),
)
}
pub async fn highlight(path: &Path) -> Result<String> {
let syntax = SYNTECT_SYNTAX.get_or_init(|| SyntaxSet::load_defaults_newlines());
let theme = SYNTECT_THEME.get_or_init(|| {
let from_file = || -> Result<Theme> {
let file = File::open(&THEME.preview.syntect_theme)?;
Ok(ThemeSet::load_from_reader(&mut BufReader::new(file))?)
};
from_file().unwrap_or_else(|_| ThemeSet::load_defaults().themes["base16-ocean.dark"].clone())
});
let path = path.to_path_buf();
let spaces = " ".repeat(PREVIEW.tab_size as usize);
tokio::task::spawn_blocking(move || -> Result<String> {
let mut h = HighlightFile::new(path, syntax, theme)?;
let mut line = String::new();
let mut buf = String::new();
let mut i = Self::size().1 as usize;
while i > 0 && h.reader.read_line(&mut line)? > 0 {
i -= 1;
line = line.replace('\t', &spaces);
let regions = h.highlight_lines.highlight_line(&line, syntax)?;
buf.push_str(&as_24_bit_terminal_escaped(&regions[..], false));
line.clear();
}
buf.push_str("\x1b[0m");
Ok(buf)
})
.await?
}
}

View file

@ -1,281 +0,0 @@
use std::{collections::BTreeMap, mem, path::{Path, PathBuf}};
use anyhow::{Error, Result};
use tokio::task::JoinHandle;
use super::{Folder, Mode, Preview};
use crate::{core::{external::{self, FzfOpt, ZoxideOpt}, files::{File, Files, FilesOp}, input::InputOpt, Event, Position, BLOCKER}, emit, misc::Defer};
pub struct Tab {
pub(super) current: Folder,
pub(super) parent: Option<Folder>,
search: Option<JoinHandle<Result<()>>>,
pub(super) mode: Mode,
pub(super) history: BTreeMap<PathBuf, Folder>,
pub(super) preview: Preview,
}
impl Tab {
pub fn new(path: &Path) -> Self {
Self {
current: Folder::new(path),
parent: path.parent().map(|p| Folder::new(p)),
search: None,
mode: Default::default(),
history: Default::default(),
preview: Preview::new(),
}
}
pub fn escape(&mut self) -> bool {
if matches!(self.mode, Mode::Select(_) | Mode::Unselect(_)) {
self.mode = Mode::Normal;
return true;
}
if self.select_all(Some(false)) {
return true;
}
self.search_stop()
}
pub fn arrow(&mut self, step: isize) -> bool {
let before = self.current.cursor();
let ok = if step > 0 {
self.current.next(step as usize)
} else {
self.current.prev(step.abs() as usize)
};
if !ok {
return false;
}
// Visual selection
if let Some(start) = self.mode.start() {
let after = self.current.cursor();
if (after > before && before < start) || (after < before && before > start) {
for i in before.min(start)..=start.max(before) {
self.current.select(Some(i), Some(false));
}
}
for i in start.min(after)..=after.max(start) {
self.current.select(Some(i), Some(true));
}
}
emit!(Hover);
true
}
pub async fn cd(&mut self, mut target: PathBuf) -> bool {
let file = if let Ok(f) = File::from(&target).await {
f
} else {
return false;
};
let mut hovered = None;
if !file.meta.is_dir() {
hovered = Some(file);
target = target.parent().unwrap().to_path_buf();
}
if self.current.cwd == target {
if hovered.map(|h| self.current.hover_force(h)).unwrap_or(false) {
emit!(Hover);
}
return false;
}
if let Some(rep) = self.parent.take() {
self.history.insert(rep.cwd.clone(), rep);
}
let rep = self.history_new(&target);
let rep = mem::replace(&mut self.current, rep);
if !rep.in_search {
self.history.insert(rep.cwd.clone(), rep);
}
if let Some(parent) = target.parent() {
self.parent = Some(self.history_new(parent));
}
if let Some(h) = hovered {
self.current.hover_force(h);
}
emit!(Refresh);
true
}
pub fn enter(&mut self) -> bool {
let hovered = if let Some(ref h) = self.current.hovered {
h.clone()
} else {
return false;
};
if !hovered.meta.is_dir() {
return false;
}
let rep = self.history_new(&hovered.path);
let rep = mem::replace(&mut self.current, rep);
if !rep.in_search {
self.history.insert(rep.cwd.clone(), rep);
}
if let Some(rep) = self.parent.take() {
self.history.insert(rep.cwd.clone(), rep);
}
self.parent = Some(self.history_new(hovered.path.parent().unwrap()));
emit!(Refresh);
true
}
pub fn leave(&mut self) -> bool {
let current = self
.current
.hovered
.as_ref()
.and_then(|h| h.path.parent())
.and_then(|p| if p == self.current.cwd { None } else { Some(p) })
.or_else(|| self.current.cwd.parent());
let current = if let Some(c) = current {
c.to_owned()
} else {
return false;
};
if let Some(rep) = self.parent.take() {
self.history.insert(rep.cwd.clone(), rep);
}
if let Some(parent) = current.parent() {
self.parent = Some(self.history_new(parent));
}
let rep = self.history_new(&current);
let rep = mem::replace(&mut self.current, rep);
if !rep.in_search {
self.history.insert(rep.cwd.clone(), rep);
}
emit!(Refresh);
true
}
// TODO
pub fn back(&mut self) -> bool { false }
// TODO
pub fn forward(&mut self) -> bool { false }
pub fn search(&mut self, grep: bool) -> bool {
if let Some(handle) = self.search.take() {
handle.abort();
}
let cwd = self.current.cwd.clone();
let hidden = self.current.files.show_hidden;
self.search = Some(tokio::spawn(async move {
let subject = emit!(Input(InputOpt {
title: "Search:".to_string(),
value: "".to_string(),
position: Position::Top,
}))
.await?;
let mut rx = if grep {
external::rg(external::RgOpt { cwd: cwd.clone(), hidden, subject })
} else {
external::fd(external::FdOpt { cwd: cwd.clone(), hidden, glob: false, subject })
}?;
emit!(Files(FilesOp::search_empty(&cwd)));
while let Some(chunk) = rx.recv().await {
if chunk.is_empty() {
break;
}
emit!(Files(FilesOp::Search(cwd.clone(), Files::read(chunk).await)));
}
Ok(())
}));
true
}
pub fn search_stop(&mut self) -> bool {
if let Some(handle) = self.search.take() {
handle.abort();
}
if self.current.in_search {
let cwd = self.current.cwd.clone();
let rep = self.history_new(&cwd);
drop(mem::replace(&mut self.current, rep));
}
emit!(Refresh);
true
}
pub fn jump(&self, global: bool) -> bool {
let cwd = self.current.cwd.clone();
tokio::spawn(async move {
let _guard = BLOCKER.acquire().await.unwrap();
let _defer = Defer::new(|| Event::Stop(false, None).emit());
emit!(Stop(true)).await;
let rx =
if global { external::fzf(FzfOpt { cwd }) } else { external::zoxide(ZoxideOpt { cwd }) }?;
if let Ok(target) = rx.await? {
emit!(Cd(target));
}
Ok::<(), Error>(())
});
false
}
pub fn select(&mut self, state: Option<bool>) -> bool {
let idx = Some(self.current.cursor());
self.current.select(idx, state)
}
pub fn select_all(&mut self, state: Option<bool>) -> bool { self.current.select(None, state) }
pub fn visual_mode(&mut self, unsel: bool) -> bool {
let idx = self.current.cursor();
if unsel {
self.mode = Mode::Unselect(idx);
self.current.select(Some(idx), Some(false));
} else {
self.mode = Mode::Select(idx);
self.current.select(Some(idx), Some(true));
};
true
}
}
impl Tab {
#[inline]
pub fn mode(&self) -> &Mode { &self.mode }
#[inline]
pub fn history(&self, path: &Path) -> Option<&Folder> { self.history.get(path) }
#[inline]
pub fn history_new(&mut self, path: &Path) -> Folder {
self.history.remove(path).unwrap_or_else(|| Folder::new(path))
}
#[inline]
pub fn preview(&self) -> &Preview { &self.preview }
}

View file

@ -1,98 +0,0 @@
use std::path::Path;
use super::Tab;
use crate::{config::MANAGER, emit};
const MAX_TABS: usize = 9;
pub struct Tabs {
idx: usize,
items: Vec<Tab>,
}
impl Tabs {
pub fn new() -> Self {
let tabs = Self { idx: 0, items: vec![Tab::new(&MANAGER.cwd)] };
emit!(Refresh);
tabs
}
pub fn create(&mut self, path: &Path) -> bool {
if self.items.len() >= MAX_TABS {
return false;
}
self.items.insert(self.idx + 1, Tab::new(path));
self.set_idx(self.idx + 1);
true
}
pub fn switch(&mut self, idx: isize, rel: bool) -> bool {
let idx = if rel { self.absolute(idx) } else { idx as usize };
if idx == self.idx || idx >= self.items.len() {
return false;
}
self.set_idx(idx);
true
}
pub fn swap(&mut self, rel: isize) -> bool {
let idx = self.absolute(rel);
if idx == self.idx {
return false;
}
self.items.swap(self.idx, idx);
self.set_idx(idx);
true
}
pub fn close(&mut self, idx: usize) -> bool {
let len = self.items.len();
if len < 2 || idx as usize >= len {
return false;
}
self.items.remove(idx);
if idx <= self.idx {
self.set_idx(self.absolute(1));
}
true
}
#[inline]
fn absolute(&self, rel: isize) -> usize {
if rel > 0 {
(self.idx + rel as usize).min(self.items.len() - 1)
} else {
self.idx.saturating_sub(rel.abs() as usize)
}
}
#[inline]
fn set_idx(&mut self, idx: usize) {
self.idx = idx;
emit!(Refresh);
}
}
impl Tabs {
#[inline]
pub fn idx(&self) -> usize { self.idx }
#[inline]
pub fn len(&self) -> usize { self.items.len() }
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &Tab> { self.items.iter() }
#[inline]
pub fn active(&self) -> &Tab { &self.items[self.idx] }
#[inline]
pub(super) fn active_mut(&mut self) -> &mut Tab { &mut self.items[self.idx] }
}

View file

@ -1,156 +0,0 @@
use std::{collections::BTreeSet, path::{Path, PathBuf}, sync::Arc};
use indexmap::IndexMap;
use notify::{event::{MetadataKind, ModifyKind}, EventKind, RecommendedWatcher, RecursiveMode, Watcher as _Watcher};
use parking_lot::RwLock;
use tokio::{fs, sync::mpsc::{self, Receiver, Sender}};
use crate::{core::files::{Files, FilesOp}, emit};
pub struct Watcher {
tx: Sender<PathBuf>,
watcher: RecommendedWatcher,
watched: Arc<RwLock<IndexMap<PathBuf, Option<PathBuf>>>>,
}
impl Watcher {
pub(super) fn start() -> Self {
let (tx, rx) = mpsc::channel(50);
let watcher = RecommendedWatcher::new(
{
let tx = tx.clone();
move |res: Result<notify::Event, notify::Error>| {
if res.is_err() {
return;
}
let event = res.unwrap();
let path = if let Some(first) = event.paths.first() {
first.clone()
} else {
return;
};
let parent = path.parent().unwrap_or(&path).to_path_buf();
match event.kind {
EventKind::Create(_) => {
tx.blocking_send(parent).ok();
}
EventKind::Modify(kind) => {
match kind {
ModifyKind::Metadata(kind) => match kind {
MetadataKind::Permissions => {}
MetadataKind::Ownership => {}
MetadataKind::Extended => {}
_ => return,
},
ModifyKind::Name(_) => {}
_ => return,
};
tx.blocking_send(path).ok();
tx.blocking_send(parent).ok();
}
EventKind::Remove(_) => {
tx.blocking_send(path).ok();
tx.blocking_send(parent).ok();
}
_ => return,
}
}
},
notify::Config::default(),
)
.unwrap();
let instance = Self { tx, watcher, watched: Default::default() };
tokio::spawn(Self::changed(rx, instance.watched.clone()));
instance
}
async fn changed(
mut rx: Receiver<PathBuf>,
watched: Arc<RwLock<IndexMap<PathBuf, Option<PathBuf>>>>,
) {
while let Some(path) = rx.recv().await {
let linked = watched
.read()
.iter()
.map_while(|(k, v)| v.as_ref().and_then(|v| path.strip_prefix(v).ok()).map(|v| k.join(v)))
.collect::<Vec<_>>();
let result = Files::read_dir(&path).await;
if linked.is_empty() {
emit!(Files(match result {
Ok(items) => FilesOp::Read(path, items),
Err(_) => FilesOp::IOErr(path),
}));
continue;
}
for ori in linked {
emit!(Files(match &result {
Ok(items) => {
let files = IndexMap::from_iter(items.iter().map(|(p, f)| {
let p = ori.join(p.strip_prefix(&path).unwrap());
let f = f.clone().set_path(&p);
(p, f)
}));
FilesOp::Read(ori, files)
}
Err(_) => FilesOp::IOErr(ori),
}));
}
}
}
pub(super) fn watch(&mut self, mut to_watch: BTreeSet<PathBuf>) {
let keys = self.watched.read().keys().cloned().collect::<BTreeSet<_>>();
for p in keys.difference(&to_watch) {
self.watcher.unwatch(p).ok();
}
for p in to_watch.clone().difference(&keys) {
if self.watcher.watch(&p, RecursiveMode::NonRecursive).is_err() {
to_watch.remove(p);
}
}
let mut todo = Vec::new();
let mut watched = self.watched.write();
*watched = IndexMap::from_iter(to_watch.into_iter().map(|k| {
if let Some(v) = watched.remove(&k) {
(k, v)
} else {
todo.push(k.clone());
(k, None)
}
}));
watched.sort_unstable_by(|_, a, _, b| b.cmp(a));
let watched = self.watched.clone();
tokio::spawn(async move {
let mut ext = IndexMap::new();
for k in todo {
match fs::canonicalize(&k).await {
Ok(v) if v != k => {
ext.insert(k, Some(v));
}
_ => {}
}
}
let mut watched = watched.write();
watched.extend(ext);
watched.sort_unstable_by(|_, a, _, b| b.cmp(a));
});
}
pub(super) fn trigger(&self, path: &Path) {
let tx = self.tx.clone();
let path = path.to_path_buf();
tokio::spawn(async move {
tx.send(path).await.ok();
});
}
}

View file

@ -1,14 +0,0 @@
pub mod adapter;
mod blocker;
mod event;
pub mod external;
pub mod files;
pub mod input;
pub mod manager;
pub mod position;
pub mod select;
pub mod tasks;
pub use blocker::*;
pub use event::*;
pub use position::*;

View file

@ -1,5 +0,0 @@
pub enum Position {
Top,
Hovered,
Coords(u16, u16),
}

View file

@ -1,5 +0,0 @@
mod select;
pub use select::*;
pub const SELECT_PADDING: u16 = 2;

View file

@ -1,108 +0,0 @@
use anyhow::{anyhow, Result};
use ratatui::prelude::Rect;
use tokio::sync::oneshot::Sender;
use super::SELECT_PADDING;
use crate::{core::Position, misc::tty_size};
#[derive(Default)]
pub struct Select {
title: String,
items: Vec<String>,
position: (u16, u16),
offset: usize,
cursor: usize,
callback: Option<Sender<Result<usize>>>,
pub visible: bool,
}
pub struct SelectOpt {
pub title: String,
pub items: Vec<String>,
pub position: Position,
}
impl Select {
pub fn show(&mut self, opt: SelectOpt, tx: Sender<Result<usize>>) {
self.close(false);
self.title = opt.title;
self.items = opt.items;
self.position = match opt.position {
Position::Coords(x, y) => (x, y),
_ => unimplemented!(),
};
self.callback = Some(tx);
self.visible = true;
}
pub fn close(&mut self, submit: bool) -> bool {
if let Some(cb) = self.callback.take() {
let _ = cb.send(if submit { Ok(self.cursor) } else { Err(anyhow!("canceled")) });
}
self.cursor = 0;
self.offset = 0;
self.visible = false;
true
}
pub fn next(&mut self, step: usize) -> bool {
let len = self.items.len();
if len == 0 {
return false;
}
let old = self.cursor;
self.cursor = (self.cursor + step).min(len - 1);
let limit = self.limit();
if self.cursor >= len.min(self.offset + limit) {
self.offset = len.saturating_sub(limit).min(self.offset + self.cursor - old);
}
old != self.cursor
}
pub fn prev(&mut self, step: usize) -> bool {
let old = self.cursor;
self.cursor = self.cursor.saturating_sub(step);
if self.cursor < self.offset {
self.offset = self.offset.saturating_sub(old - self.cursor);
}
old != self.cursor
}
#[inline]
pub fn window(&self) -> &[String] {
let end = (self.offset + self.limit()).min(self.items.len());
&self.items[self.offset..end]
}
#[inline]
pub fn limit(&self) -> usize {
self.items.len().min(tty_size().ws_row.saturating_sub(SELECT_PADDING).min(5) as usize)
}
}
impl Select {
#[inline]
pub fn title(&self) -> String { self.title.clone() }
#[inline]
pub fn rel_cursor(&self) -> usize { self.cursor - self.offset }
#[inline]
pub fn area(&self) -> Rect {
Rect {
x: self.position.0,
y: self.position.1 + 2,
width: 50,
height: self.limit() as u16 + SELECT_PADDING,
}
}
}

View file

@ -1,315 +0,0 @@
use std::{collections::VecDeque, fs::Metadata, path::{Path, PathBuf}};
use anyhow::Result;
use futures::{future::BoxFuture, FutureExt};
use tokio::{fs, io::{self, ErrorKind::{AlreadyExists, NotFound}}, sync::mpsc};
use tracing::{info, trace};
use super::TaskOp;
use crate::misc::{calculate_size, copy_with_progress};
pub(super) struct File {
rx: async_channel::Receiver<FileOp>,
tx: async_channel::Sender<FileOp>,
sch: mpsc::UnboundedSender<TaskOp>,
}
#[derive(Debug)]
pub(super) enum FileOp {
Paste(FileOpPaste),
Link(FileOpLink),
Delete(FileOpDelete),
Trash(FileOpTrash),
}
#[derive(Clone, Debug)]
pub(super) struct FileOpPaste {
pub id: usize,
pub from: PathBuf,
pub to: PathBuf,
pub cut: bool,
pub follow: bool,
pub retry: u8,
}
#[derive(Clone, Debug)]
pub(super) struct FileOpLink {
pub id: usize,
pub from: PathBuf,
pub to: PathBuf,
pub cut: bool,
pub length: u64,
}
#[derive(Clone, Debug)]
pub(super) struct FileOpDelete {
pub id: usize,
pub target: PathBuf,
pub length: u64,
}
#[derive(Clone, Debug)]
pub(super) struct FileOpTrash {
pub id: usize,
pub target: PathBuf,
pub length: u64,
}
impl File {
pub(super) fn new(sch: mpsc::UnboundedSender<TaskOp>) -> Self {
let (tx, rx) = async_channel::unbounded();
Self { tx, rx, sch }
}
#[inline]
pub(super) async fn recv(&self) -> Result<(usize, FileOp)> {
Ok(match self.rx.recv().await? {
FileOp::Paste(t) => (t.id, FileOp::Paste(t)),
FileOp::Link(t) => (t.id, FileOp::Link(t)),
FileOp::Delete(t) => (t.id, FileOp::Delete(t)),
FileOp::Trash(t) => (t.id, FileOp::Trash(t)),
})
}
pub(super) async fn work(&self, task: &mut FileOp) -> Result<()> {
match task {
FileOp::Paste(task) => {
match fs::remove_file(&task.to).await {
Err(e) if e.kind() != NotFound => Err(e)?,
_ => {}
}
let mut it = copy_with_progress(&task.from, &task.to);
while let Some(res) = it.recv().await {
match res {
Ok(0) => {
if task.cut {
fs::remove_file(&task.from).await.ok();
}
break;
}
Ok(n) => {
trace!("Paste task advanced {}: {:?}", n, task);
self.sch.send(TaskOp::Adv(task.id, 0, n))?
}
Err(e) if e.kind() == NotFound => {
trace!("Paste task partially done: {:?}", task);
break;
}
// Operation not permitted (os error 1)
// Attribute not found (os error 93)
Err(e) if task.retry < 3 && matches!(e.raw_os_error(), Some(1) | Some(93)) => {
trace!("Paste task retry: {:?}", task);
task.retry += 1;
return Ok(self.tx.send(FileOp::Paste(task.clone())).await?);
}
Err(e) => Err(e)?,
}
}
self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
}
FileOp::Link(task) => {
let src = match fs::read_link(&task.from).await {
Ok(src) => src,
Err(e) if e.kind() == NotFound => {
trace!("Link task partially done: {:?}", task);
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, task.length))?);
}
Err(e) => Err(e)?,
};
match fs::remove_file(&task.to).await {
Err(e) if e.kind() != NotFound => Err(e)?,
_ => fs::symlink(src, &task.to).await?,
}
if task.cut {
fs::remove_file(&task.from).await.ok();
}
self.sch.send(TaskOp::Adv(task.id, 1, task.length))?;
}
FileOp::Delete(task) => {
if let Err(e) = fs::remove_file(&task.target).await {
if e.kind() != NotFound && fs::symlink_metadata(&task.target).await.is_ok() {
info!("Delete task failed: {:?}, {}", task, e);
Err(e)?
}
}
self.sch.send(TaskOp::Adv(task.id, 1, task.length))?
}
FileOp::Trash(task) => {
#[cfg(target_os = "macos")]
{
use trash::{macos::{DeleteMethod, TrashContextExtMacos}, TrashContext};
let mut ctx = TrashContext::default();
ctx.set_delete_method(DeleteMethod::NsFileManager);
ctx.delete(&task.target)?;
}
#[cfg(not(target_os = "macos"))]
{
trash::delete(&task.target)?;
}
self.sch.send(TaskOp::Adv(task.id, 1, task.length))?;
}
}
Ok(())
}
fn done(&self, id: usize) -> Result<()> { Ok(self.sch.send(TaskOp::Done(id))?) }
pub(super) async fn paste(&self, mut task: FileOpPaste) -> Result<()> {
if task.cut {
match fs::rename(&task.from, &task.to).await {
Ok(_) => return self.done(task.id),
Err(e) if e.kind() == NotFound => return self.done(task.id),
_ => {}
}
}
let meta = Self::metadata(&task.from, task.follow).await?;
if !meta.is_dir() {
let id = task.id;
self.sch.send(TaskOp::New(id, meta.len()))?;
if meta.is_file() {
self.tx.send(FileOp::Paste(task)).await?;
} else if meta.is_symlink() {
self.tx.send(FileOp::Link(task.to_link(meta.len()))).await?;
}
return self.done(id);
}
let root = task.to.clone();
let skip = task.from.components().count();
let mut dirs = VecDeque::from([task.from]);
while let Some(src) = dirs.pop_front() {
let dest = root.join(src.components().skip(skip).collect::<PathBuf>());
match fs::create_dir(&dest).await {
Err(e) if e.kind() != AlreadyExists => {
info!("Create dir failed: {:?}, {}", dest, e);
continue;
}
_ => {}
}
let mut it = match fs::read_dir(&src).await {
Ok(it) => it,
Err(e) => {
info!("Read dir failed: {:?}, {}", src, e);
continue;
}
};
while let Ok(Some(entry)) = it.next_entry().await {
let src = entry.path();
let meta = if let Ok(meta) = Self::metadata(&src, task.follow).await {
meta
} else {
continue;
};
if meta.is_dir() {
dirs.push_back(src);
continue;
}
task.to = dest.join(src.file_name().unwrap());
task.from = src;
self.sch.send(TaskOp::New(task.id, meta.len()))?;
if meta.is_file() {
trace!("Paste: {:?} -> {:?}", task.from, task.to);
self.tx.send(FileOp::Paste(task.clone())).await?;
} else if meta.is_symlink() {
trace!("Link: {:?} -> {:?}", task.from, task.to);
self.tx.send(FileOp::Link(task.to_link(meta.len()))).await?;
}
}
}
self.done(task.id)
}
pub(super) async fn delete(&self, mut task: FileOpDelete) -> Result<()> {
let meta = fs::symlink_metadata(&task.target).await?;
if !meta.is_dir() {
let id = task.id;
task.length = meta.len();
self.sch.send(TaskOp::New(id, meta.len()))?;
self.tx.send(FileOp::Delete(task)).await?;
return self.done(id);
}
let mut dirs = VecDeque::from([task.target]);
while let Some(target) = dirs.pop_front() {
let mut it = match fs::read_dir(target).await {
Ok(it) => it,
Err(_) => continue,
};
while let Ok(Some(entry)) = it.next_entry().await {
let meta = match entry.metadata().await {
Ok(m) => m,
Err(_) => continue,
};
if meta.is_dir() {
dirs.push_front(entry.path());
continue;
}
task.target = entry.path();
task.length = meta.len();
self.sch.send(TaskOp::New(task.id, meta.len()))?;
self.tx.send(FileOp::Delete(task.clone())).await?;
}
}
self.done(task.id)
}
pub(super) async fn trash(&self, mut task: FileOpTrash) -> Result<()> {
let id = task.id;
task.length = calculate_size(&task.target).await;
self.sch.send(TaskOp::New(id, task.length))?;
self.tx.send(FileOp::Trash(task)).await?;
self.done(id)
}
async fn metadata(path: &Path, follow: bool) -> io::Result<Metadata> {
if !follow {
return fs::symlink_metadata(path).await;
}
let meta = fs::metadata(path).await;
if meta.is_ok() { meta } else { fs::symlink_metadata(path).await }
}
pub(super) fn remove_empty_dirs(dir: &Path) -> BoxFuture<()> {
trace!("Remove empty dirs: {:?}", dir);
async move {
let mut it = match fs::read_dir(dir).await {
Ok(it) => it,
Err(_) => return,
};
while let Ok(Some(entry)) = it.next_entry().await {
if entry.file_type().await.map(|t| t.is_dir()).unwrap_or(false) {
let path = entry.path();
Self::remove_empty_dirs(&path).await;
fs::remove_dir(path).await.ok();
}
}
fs::remove_dir(dir).await.ok();
}
.boxed()
}
}
impl FileOpPaste {
fn to_link(&self, length: u64) -> FileOpLink {
FileOpLink { id: self.id, from: self.from.clone(), to: self.to.clone(), cut: self.cut, length }
}
}

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