diff --git a/Cargo.lock b/Cargo.lock index bc73208..91c4896 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,78 +2,49 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "ab_glyph" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser", -] - -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" - [[package]] name = "accesskit" -version = "0.25.2" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e883d1d28c5fd5568c79ed2d2bd48d9f2fd3945c8974ed0f53690ceddb051be" +checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320" dependencies = [ + "enumn", "uuid", ] [[package]] name = "accesskit_atspi_common" -version = "0.21.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24f5baf62e34a4a6c30e3d697e4782f821a7337049c44c3b40576a27dfbb580d" +checksum = "023da0e5097f46df7092d5280b02efb9bbf8d93298daeced42652463e357d636" dependencies = [ "accesskit", "accesskit_consumer", "atspi-common", - "phf", + "phf 0.13.1", "serde", "zvariant", ] [[package]] name = "accesskit_consumer" -version = "0.39.2" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3da8f27636015191b2264ee1df681503170a632cafd832fdc1edfdd4e3a2fd3" +checksum = "5d10a236f96f87d70732e44520046785431ef01d5bcd6b041317bfadd2f88245" dependencies = [ "accesskit", - "hashbrown 0.17.1", -] - -[[package]] -name = "accesskit_ios" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5280724673bbfa8b30a838c013500b719392989be3b97c5a9964062c252c232" -dependencies = [ - "accesskit", - "accesskit_consumer", - "hashbrown 0.17.1", - "objc2 0.5.3", - "objc2-foundation 0.2.2", - "objc2-ui-kit 0.2.2", + "hashbrown 0.16.1", ] [[package]] name = "accesskit_macos" -version = "0.27.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123828ceeec755b05255e3976cb0852993202de98a0626c97dd8d34246991f84" +checksum = "ce02dc63b43f0c9296af9ac946312a2dc8814427d7a64d2d600971dac55b6076" dependencies = [ "accesskit", "accesskit_consumer", - "hashbrown 0.17.1", + "hashbrown 0.16.1", "objc2 0.5.3", "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", @@ -81,9 +52,9 @@ dependencies = [ [[package]] name = "accesskit_unix" -version = "0.24.1" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d5192871228c54f1b0fb4a85cef000e11a3804f25d2165f14afa0daa67f3f6" +checksum = "03e156ed3802e35eefe894ef2671bc6c889303d8a7e110b5e1b48f504b91362f" dependencies = [ "accesskit", "accesskit_atspi_common", @@ -99,31 +70,25 @@ dependencies = [ [[package]] name = "accesskit_windows" -version = "0.35.2" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "498668b90da9995302a0055aaecad4756932333da2ddef6baee1c00844c430fc" +checksum = "106c2b961215864d1c2e703ee63269c25c4e80a577ffb2c1017b9c17dcdf83a1" dependencies = [ "accesskit", "accesskit_consumer", - "hashbrown 0.17.1", + "hashbrown 0.16.1", "static_assertions", - "windows", - "windows-core", + "windows 0.62.2", + "windows-core 0.62.2", ] [[package]] -name = "accesskit_winit" -version = "0.34.2" +name = "addr2line" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4ab4437b520ff03088fbe48676a11e7d44a929535e64b31432c1073e48dbcc" +checksum = "e567177890eb1617b1f774005b66b26b2377afd138a2ca37aae7d8f0c81429d4" dependencies = [ - "accesskit", - "accesskit_ios", - "accesskit_macos", - "accesskit_unix", - "accesskit_windows", - "raw-window-handle", - "winit", + "gimli", ] [[package]] @@ -132,6 +97,18 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures 0.2.17", + "zeroize", +] + [[package]] name = "ahash" version = "0.8.12" @@ -139,7 +116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.4", + "const-random", "once_cell", "version_check", "zerocopy", @@ -154,37 +131,30 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" +dependencies = [ + "as-slice", +] + +[[package]] +name = "aligned-vec" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", +] + [[package]] name = "allocator-api2" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "android-activity" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" -dependencies = [ - "android-properties", - "bitflags 2.13.2", - "cc", - "jni", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys", - "num_enum", - "thiserror 2.0.21", -] - -[[package]] -name = "android-properties" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" - [[package]] name = "android_system_properties" version = "0.1.6" @@ -195,26 +165,60 @@ dependencies = [ ] [[package]] -name = "arboard" -version = "3.7.0" +name = "annotate-snippets" +version = "0.12.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb9553e62312c8756a5979254fc6d7da8bbeb5986a1e17037fab932f7037917" +checksum = "b2a5b0a5ab8561c603f16c3b78c24a386b1f70e7fc1b1b1e8c15738828e4a176" dependencies = [ - "clipboard-win", - "image", - "log", - "objc2 0.6.5", - "objc2-app-kit 0.3.2", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.2", - "parking_lot", - "percent-encoding", - "windows-sys 0.61.2", - "wl-clipboard-rs", - "x11rb", + "anstyle", + "memchr", + "unicode-width 0.2.3", ] +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "arbitrary" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bc62ac97cc33321f50863d514c3bc38a453947a8f9e781137e47c7401020aed" + +[[package]] +name = "arc-swap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380962b3d93b99642e50b9febf72c071e97e8b32d86eae9cf4ef582bb960ae6e" +dependencies = [ + "rustversion", +] + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + [[package]] name = "arrayref" version = "0.3.9" @@ -233,6 +237,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "ash" version = "0.38.0+1.3.281" @@ -242,6 +255,24 @@ dependencies = [ "libloading", ] +[[package]] +name = "ashpd" +version = "0.13.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb8421aaa9644a5faf26735f258b669b15f063313ef8f8e2bdb28912a1a6f111" +dependencies = [ + "enumflags2", + "futures-channel", + "futures-util", + "getrandom 0.4.3", + "serde", + "serde_repr", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "zbus", +] + [[package]] name = "async-broadcast" version = "0.7.2" @@ -280,6 +311,17 @@ dependencies = [ "slab", ] +[[package]] +name = "async-fs" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + [[package]] name = "async-io" version = "2.6.0" @@ -293,7 +335,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.1.6", + "rustix", "slab", "windows-sys 0.61.2", ] @@ -309,6 +351,17 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io", + "blocking", + "futures-lite", +] + [[package]] name = "async-process" version = "2.5.0" @@ -324,7 +377,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix 1.1.6", + "rustix", ] [[package]] @@ -350,7 +403,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.6", + "rustix", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -373,6 +426,12 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + [[package]] name = "atomic-waker" version = "1.1.2" @@ -422,13 +481,98 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "av-scenechange" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394" +dependencies = [ + "aligned", + "anyhow", + "arg_enum_proc_macro", + "arrayvec", + "log", + "num-rational", + "num-traits", + "pastey", + "rayon", + "thiserror 2.0.21", + "v_frame", + "y4m", +] + +[[package]] +name = "av1-grain" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "backtrace" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f4220217f3288537b83684130f42fad43320b1c3b805f1910d683d52ded24f" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide 0.9.1", + "object", + "rustc-demangle", + "windows-link 0.2.1", +] + +[[package]] +name = "base62" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3a647dce9631f152a99ec16cfc09267ae55fe280d5dc288964027d458076323" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "bit-set" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2f926cc3060f09db9ebc5b52823d85268d24bb917e472c0c4bea35780a7d" dependencies = [ - "bit-vec", + "bit-vec 0.9.1", +] + +[[package]] +name = "bit-set" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56d87354e4229f54a44f7bf2435906a4656dba36026ab6eaca629a2c436a691c" +dependencies = [ + "bit-vec 0.10.1", ] [[package]] @@ -437,6 +581,22 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" +[[package]] +name = "bit-vec" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5727b15fa97d4f4fee0a3b7c3d550ed0269f54329207b86388de918604e31269" +dependencies = [ + "borsh", + "serde", +] + +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -449,6 +609,48 @@ version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" +[[package]] +name = "bitstream-io" +version = "4.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f" +dependencies = [ + "no_std_io2", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + [[package]] name = "block2" version = "0.5.1" @@ -480,6 +682,30 @@ dependencies = [ "piper", ] +[[package]] +name = "borsh" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "553c5d846a6ba5150c65e3b1b8ec073bcf1abc20f9b7220de384a4443ea4e20a" +dependencies = [ + "borsh-derive", + "bytes", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cdfe656708a01f89b451a7d36466e6fe6c414de0aa18fc54f864f6f9ca9f56" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 3.0.9", +] + [[package]] name = "bstr" version = "1.13.1" @@ -487,9 +713,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" dependencies = [ "memchr", + "regex-automata", "serde_core", ] +[[package]] +name = "built" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9" + [[package]] name = "bumpalo" version = "3.20.3" @@ -516,6 +749,12 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "byteorder-lite" version = "0.1.0" @@ -528,20 +767,6 @@ version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" -[[package]] -name = "calloop" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" -dependencies = [ - "bitflags 2.13.2", - "log", - "polling", - "rustix 0.38.44", - "slab", - "thiserror 1.0.69", -] - [[package]] name = "calloop" version = "0.14.5" @@ -550,34 +775,49 @@ checksum = "43b32313e937c8721c9d17ee9bf60699a6402b4b7c2cb6ac1bee0ffcaa4b4e5e" dependencies = [ "bitflags 2.13.2", "polling", - "rustix 1.1.6", + "rustix", "tracing", ] -[[package]] -name = "calloop-wayland-source" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" -dependencies = [ - "calloop 0.13.0", - "rustix 0.38.44", - "wayland-backend", - "wayland-client", -] - [[package]] name = "calloop-wayland-source" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" dependencies = [ - "calloop 0.14.5", - "rustix 1.1.6", + "calloop", + "rustix", "wayland-backend", "wayland-client", ] +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cbindgen" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff" +dependencies = [ + "heck 0.4.1", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 2.0.119", + "tempfile", + "toml 0.8.23", +] + [[package]] name = "cc" version = "1.10.0" @@ -603,21 +843,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] -name = "cgl" -version = "0.3.2" +name = "chacha20" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ - "libc", + "cfg-if", + "cpufeatures 0.3.1", + "rand_core 0.10.1", ] [[package]] -name = "clipboard-win" -version = "5.4.3" +name = "chrono" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052af7878466feccda12ba7a6a67d019d712f296809559b47c12c8cc196d3a9a" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ - "error-code", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.1", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common 0.1.7", + "inout", + "zeroize", +] + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation 0.9.4", + "core-graphics 0.23.2", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation 0.9.4", + "core-graphics-types 0.1.3", + "libc", + "objc", ] [[package]] @@ -628,27 +916,14 @@ checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] -name = "color" -version = "0.3.3" +name = "color_quant" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ec7c5eb7a16992b1904d76c517d170ab353b0e0b3d5a0c81a8a0cd1037893cf" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "combine" -version = "4.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4356eba6976435498d05a311ee9fc486da3bc81c200d3f0d7dd9703b41913f92" -dependencies = [ - "bytes", - "memchr", -] +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "concurrent-queue" @@ -659,6 +934,60 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -669,6 +998,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -682,8 +1021,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", + "core-foundation 0.9.4", + "core-graphics-types 0.1.3", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.10.1", + "core-graphics-types 0.2.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-helmer-fork" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32eb7c354ae9f6d437a6039099ce7ecd049337a8109b23d73e48e8ffba8e9cd5" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.9.4", + "core-graphics-types 0.1.3", "foreign-types", "libc", ] @@ -695,7 +1060,87 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.10.1", + "libc", +] + +[[package]] +name = "core-text" +version = "21.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a593227b66cbd4007b2a050dfdd9e1d1318311409c8d600dc82ba1b15ca9c130" +dependencies = [ + "core-foundation 0.10.1", + "core-graphics 0.24.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + +[[package]] +name = "core_maths" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + +[[package]] +name = "cosmic-text" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" +dependencies = [ + "bitflags 2.13.2", + "fontdb", + "harfrust", + "linebender_resource_handle", + "log", + "rangemap", + "rustc-hash 2.1.3", + "self_cell", + "skrifa 0.40.0", + "smol_str", + "swash", + "sys-locale", + "unicode-bidi", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ "libc", ] @@ -708,6 +1153,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.23" @@ -721,10 +1194,131 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] -name = "cursor-icon" -version = "1.2.0" +name = "crypto-common" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "ctor" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" +dependencies = [ + "link-section", + "linktime-proc-macro", +] + +[[package]] +name = "data-url" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + +[[package]] +name = "deranged" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9de72ce2ad1f90dc62fa25f0f430ef85eb4b0d8fa0be4f30373bc40a21d28e" + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case 0.10.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common 0.1.7", + "subtle", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.4.6", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.5.3", + "windows-sys 0.61.2", +] [[package]] name = "dispatch" @@ -739,6 +1333,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ "bitflags 2.13.2", + "block2 0.6.2", "objc2 0.6.5", ] @@ -778,166 +1373,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] -name = "dpi" -version = "0.1.2" +name = "dunce" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] -name = "ecolor" -version = "0.37.0" +name = "dwrote" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31bcbef0d4263a63eb32c4834e5d711613035ce1333468e107d928923e21e6e2" +checksum = "9e1b35532432acc8b19ceed096e35dfa088d3ea037fe4f3c085f1f97f33b4d02" dependencies = [ - "bytemuck", - "emath", + "lazy_static", + "libc", + "winapi", + "wio", ] [[package]] -name = "eframe" -version = "0.37.0" +name = "dyn-clone" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c5642501a65ca657d05f00c643a5c14ff2346cb3818032bfe23d58e1f8e5f84" -dependencies = [ - "ahash", - "bytemuck", - "document-features", - "egui", - "egui-wgpu", - "egui-winit", - "egui_glow", - "egui_system_font_provider", - "glutin", - "glutin-winit", - "image", - "js-sys", - "log", - "objc2 0.6.5", - "objc2-app-kit 0.3.2", - "objc2-foundation 0.3.2", - "parking_lot", - "percent-encoding", - "pollster", - "profiling", - "raw-window-handle", - "send_wrapper", - "static_assertions", - "wasm-bindgen", - "web-sys", - "web-time", - "wgpu", - "windows-sys 0.61.2", - "winit", -] - -[[package]] -name = "egui" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec9144f49b7a28b5f395d3147e325b4fe3e77ba686eac11d1bdf0a7da3f375f" -dependencies = [ - "accesskit", - "ahash", - "bitflags 2.13.2", - "emath", - "epaint", - "itertools", - "log", - "nohash-hasher", - "profiling", - "smallvec", - "unicode-segmentation", - "web-sys", -] - -[[package]] -name = "egui-rust-test" -version = "0.1.0" -dependencies = [ - "eframe", - "egui", - "mlua", - "tree-sitter", - "tree-sitter-go", - "tree-sitter-javascript", - "tree-sitter-json", - "tree-sitter-python", - "tree-sitter-rust", -] - -[[package]] -name = "egui-wgpu" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0309cbe1febed48af5b974e4bcc424b35e9664863a4d402697147b57a488c864" -dependencies = [ - "ahash", - "bytemuck", - "document-features", - "egui", - "epaint", - "log", - "profiling", - "thiserror 2.0.21", - "type-map", - "web-time", - "wgpu", - "winit", -] - -[[package]] -name = "egui-winit" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e449f4c4a2a60c7ccb4ba7fa4078417bfe1f9ddc03b5e05ce75748e33a70de" -dependencies = [ - "accesskit_winit", - "arboard", - "block2 0.6.2", - "bytemuck", - "egui", - "log", - "objc2 0.6.5", - "objc2-app-kit 0.3.2", - "objc2-foundation 0.3.2", - "objc2-ui-kit 0.3.2", - "profiling", - "raw-window-handle", - "smithay-clipboard", - "web-time", - "webbrowser", - "windows-sys 0.61.2", - "winit", -] - -[[package]] -name = "egui_glow" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9275ca5cc35a6b7c94e0e8cedf22542f66cb0cf45ed8ab2657c78ff49fec7268" -dependencies = [ - "bytemuck", - "egui", - "glow", - "log", - "profiling", - "winit", -] - -[[package]] -name = "egui_system_font_provider" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2a2fdfe3c05dd9f691d2b1388b2312d6dce1af502f217c22136d22d9bd76f6" -dependencies = [ - "epaint", - "fontique", - "log", - "poll-promise", - "skrifa", - "sys-locale", - "unicode-script", -] +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" @@ -946,12 +1403,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be" [[package]] -name = "emath" -version = "0.37.0" +name = "embed-resource" +version = "3.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e73ce90f54750be8672c02be0743fe47530e6f251e066f0ee2869b59eb297af5" +checksum = "6168487b5e7eb2673e6efe1200b1848016e436a6ca0b8031bf04bd9d493a249f" dependencies = [ - "bytemuck", + "cc", + "memchr", + "rustc_version", + "toml 1.1.8+spec-1.1.0", + "vswhom", + "winreg", +] + +[[package]] +name = "encoding_rs" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e985e0451871ad22fb8d2b6b076e2028a502a0d3950998c2c5c0a4f9b5d9679" +dependencies = [ + "cfg-if", + "core_detect", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", +] + +[[package]] +name = "encoding_rs_io" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba3fe847045ecff794b9c138293a80db914678c453ad63fbf0c6a9eb6e00b22" +dependencies = [ + "encoding_rs", ] [[package]] @@ -960,6 +1445,26 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" +[[package]] +name = "enum-iterator" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "enumflags2" version = "0.7.12" @@ -982,36 +1487,35 @@ dependencies = [ ] [[package]] -name = "epaint" -version = "0.37.0" +name = "enumn" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97bac86ae3dde93fc3951e790951caea739ff39a6c89d909cdaf1d9278dbb1bd" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ - "ahash", - "bytemuck", - "ecolor", - "emath", - "epaint_default_fonts", - "font-types", - "harfrust", - "log", - "nohash-hasher", - "parking_lot", - "profiling", - "self_cell", - "skrifa", - "smallvec", - "unicode-general-category", - "unicode-properties", - "unicode-segmentation", - "vello_cpu", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "epaint_default_fonts" -version = "0.37.0" +name = "equator" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc1cc505827f4c23eedc297975a0fd038268d41293f389dd8ff3b574aefab19" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] name = "equivalent" @@ -1030,10 +1534,14 @@ dependencies = [ ] [[package]] -name = "error-code" -version = "3.4.0" +name = "etagere" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7" +checksum = "fc89bf99e5dc15954a60f707c1e09d7540e5cd9af85fa75caa0b510bc08c5342" +dependencies = [ + "euclid", + "svg_fmt", +] [[package]] name = "euclid" @@ -1064,6 +1572,23 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.74.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711fe42c9964295e01ee3fba3f9fe0e1d24b98886950d68efe81b1c76e21adf3" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide 0.8.9", + "num-complex", + "pulp", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" version = "2.5.0" @@ -1086,10 +1611,15 @@ dependencies = [ ] [[package]] -name = "fearless_simd" -version = "0.4.1" +name = "filedescriptor" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97b65636e5b9ef369943878ac74335ba1c55c1cb6adbf1e2c293c624248d693" +checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" +dependencies = [ + "libc", + "thiserror 1.0.69", + "winapi", +] [[package]] name = "find-msvc-tools" @@ -1115,10 +1645,48 @@ dependencies = [ ] [[package]] -name = "foldhash" -version = "0.1.5" +name = "float-cmp" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[package]] +name = "float-ord" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d" + +[[package]] +name = "float_next_after" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" + +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "flume" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.9", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" @@ -1126,6 +1694,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "font-types" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7" +dependencies = [ + "bytemuck", +] + [[package]] name = "font-types" version = "0.12.7" @@ -1136,25 +1713,26 @@ dependencies = [ ] [[package]] -name = "fontique" -version = "0.11.1" +name = "fontconfig-parser" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6688bc1294fe7117d788937b6c53480169b29c566954af490830d4c09da9516a" +checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" dependencies = [ - "hashbrown 0.17.1", - "linebender_resource_handle", + "roxmltree 0.20.0", +] + +[[package]] +name = "fontdb" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" +dependencies = [ + "fontconfig-parser", + "log", "memmap2", - "objc2 0.6.5", - "objc2-core-foundation", - "objc2-core-text", - "objc2-foundation 0.3.2", - "parlance", - "read-fonts", - "roxmltree", - "smallvec", - "windows", - "windows-core", - "yeslogic-fontconfig-sys", + "slotmap", + "tinyvec", + "ttf-parser", ] [[package]] @@ -1193,12 +1771,82 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "freetype-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7edc5b9669349acfda99533e9e0bcf26a51862ab43b08ee7745c55d28eb134" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-concurrency" +version = "7.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175cd8cca9e1d45b87f18ffa75088f2099e3c4fe5e2f83e42de112560bea8ea6" +dependencies = [ + "fixedbitset", + "futures-core", + "futures-lite", + "pin-project", + "smallvec", +] + [[package]] name = "futures-core" version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.34" @@ -1229,6 +1877,12 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + [[package]] name = "futures-task" version = "0.3.34" @@ -1241,21 +1895,48 @@ version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "gethostname" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "rustix 1.1.6", - "windows-link", + "rustix", + "windows-link 0.2.1", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", ] [[package]] @@ -1265,9 +1946,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1277,10 +1960,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", + "rand_core 0.10.1", + "wasm-bindgen", ] +[[package]] +name = "gif" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gif" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1033caf0b349c518623b5396bfb2cf0bddf44f0306d543a250e5743297aafd10" + [[package]] name = "gl_generator" version = "0.14.0" @@ -1293,20 +2005,33 @@ dependencies = [ ] [[package]] -name = "glifo" -version = "0.3.0" +name = "glob" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a26c1e23de04bdab3e34a21b6f877a479b96737792516b9b8b8f69b6661be" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "globset" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98b0d85522dc0a824cfebbc9594ff4a9b289c568bea0370319dfbdf20ccdd2d" dependencies = [ - "bytemuck", - "foldhash 0.2.0", - "hashbrown 0.17.1", + "aho-corasick", + "bstr", "log", - "peniko", - "png", - "skrifa", - "smallvec", - "vello_common", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", ] [[package]] @@ -1321,63 +2046,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "glutin" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" -dependencies = [ - "bitflags 2.13.2", - "cfg_aliases", - "cgl", - "dispatch2", - "glutin_egl_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "libloading", - "objc2 0.6.5", - "objc2-app-kit 0.3.2", - "objc2-core-foundation", - "objc2-foundation 0.3.2", - "once_cell", - "raw-window-handle", - "wayland-sys", - "windows-sys 0.52.0", - "x11-dl", -] - -[[package]] -name = "glutin-winit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" -dependencies = [ - "cfg_aliases", - "glutin", - "raw-window-handle", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" -dependencies = [ - "gl_generator", - "windows-sys 0.52.0", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" -dependencies = [ - "gl_generator", - "x11-dl", -] - [[package]] name = "glutin_wgl_sys" version = "0.6.1" @@ -1398,16 +2066,998 @@ dependencies = [ "log", "presser", "thiserror 2.0.21", - "windows", + "windows 0.62.2", ] [[package]] -name = "guillotiere" -version = "0.7.0" +name = "gpui-base" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b17e70c989c36bad147b27a58d148c0741c51448aa5653436547323e524d0ab" +checksum = "d862bc8f2e27710039013d075ac4995892e9687ff207fa530f880cbcd513936f" dependencies = [ - "euclid", + "aho-corasick", + "anyhow", + "ashpd", + "async-channel", + "chrono", + "data-url", + "futures", + "gpui-fast", + "gpui-pre", + "gpui-pre-macros", + "gpui-pre-sum-tree", + "html5ever", + "instant", + "itertools 0.13.0", + "lsp-types", + "markdown", + "markup5ever_rcdom", + "num-traits", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "raw-window-handle", + "regex", + "ropey", + "schemars", + "serde", + "serde_json", + "smallvec", + "smol", + "tracing", + "unicode-linebreak", + "unicode-segmentation", + "web-time", + "windows 0.58.0", +] + +[[package]] +name = "gpui-component" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46ce53430332e30f303364eaabfa10ed2aa23dfaf2a147e04370e0e9c423578b" +dependencies = [ + "anyhow", + "chrono", + "core-text", + "enum-iterator", + "gpui-base", + "gpui-component-macros", + "gpui-fast", + "gpui-kit-assets", + "gpui-pre", + "gpui-pre-macros", + "gpui-pre-sum-tree", + "instant", + "itertools 0.13.0", + "log", + "lsp-types", + "markdown", + "notify", + "num-traits", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "once_cell", + "paste", + "raw-window-handle", + "regex", + "resvg 0.45.1", + "ropey", + "rust-i18n", + "schemars", + "serde", + "serde_json", + "serde_repr", + "similar", + "smallvec", + "smol", + "tracing", + "tree-sitter", + "tree-sitter-go", + "tree-sitter-javascript", + "tree-sitter-json", + "tree-sitter-python", + "tree-sitter-rust", + "unicode-segmentation", + "unicode-width 0.2.3", + "uuid", + "windows 0.58.0", +] + +[[package]] +name = "gpui-component-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a512c830553e7dddc43c3f8faffc2d2d7bd24db21fe3dc1326dde9c470013768" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "gpui-editor-test" +version = "0.1.0" +dependencies = [ + "gpui-kit", + "mlua", +] + +[[package]] +name = "gpui-fast" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87b6d2f355531132e8f1ec357cb23901aba1d1b3e522260822ae199f02ec32da" +dependencies = [ + "accesskit", + "anyhow", + "async-channel", + "async-task", + "backtrace", + "bitflags 2.13.2", + "chrono", + "ctor", + "derive_more", + "embed-resource", + "etagere", + "futures", + "futures-concurrency", + "getrandom 0.3.4", + "gpui-fast-macros", + "gpui-pre-collections", + "gpui-pre-http-client", + "gpui-pre-refineable", + "gpui-pre-scheduler", + "gpui-pre-shared-string", + "gpui-pre-sum-tree", + "gpui-pre-util", + "heapless", + "image", + "inventory", + "itertools 0.14.0", + "libc", + "log", + "lyon", + "num_cpus", + "objc2-core-foundation", + "objc2-core-video", + "parking", + "parking_lot", + "pin-project", + "pollster 0.4.0", + "postage", + "profiling", + "proptest", + "rand 0.9.5", + "raw-window-handle", + "regex", + "resvg 0.46.0", + "schemars", + "seahash", + "serde", + "serde_json", + "slotmap", + "smallvec", + "spin 0.10.1", + "strum", + "taffy", + "thiserror 2.0.21", + "ttf-parser", + "url", + "usvg 0.46.0", + "uuid", + "waker-fn", + "web-time", + "windows 0.62.2", + "zed-scap", +] + +[[package]] +name = "gpui-fast-apple" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f0aff0a75a63953782a609bf023c68cdb71c3dbd74478223db9bbd1b744795" +dependencies = [ + "anyhow", + "async-task", + "block2 0.6.2", + "cbindgen", + "core-foundation 0.10.1", + "core-foundation-sys", + "core-graphics 0.24.0", + "core-text", + "derive_more", + "dispatch2", + "etagere", + "foreign-types", + "futures", + "gpui-fast", + "gpui-pre-collections", + "gpui-pre-util", + "image", + "libc", + "log", + "mach2", + "metal", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", + "objc2-security", + "parking_lot", + "pathfinder_geometry", + "smallvec", + "thiserror 2.0.21", + "zed-font-kit", +] + +[[package]] +name = "gpui-fast-linux" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5a4351392d339049584e06a58460a4907a060e3f46e49b7c130d80ffe36871" +dependencies = [ + "accesskit", + "accesskit_unix", + "anyhow", + "as-raw-xcb-connection", + "ashpd", + "bytemuck", + "calloop", + "calloop-wayland-source", + "filedescriptor", + "futures", + "gpui-fast", + "gpui-fast-wgpu", + "gpui-pre-collections", + "gpui-pre-http-client", + "gpui-pre-util", + "libc", + "log", + "notify-rust", + "oo7", + "open", + "parking_lot", + "raw-window-handle", + "smallvec", + "smol", + "strum", + "url", + "uuid", + "wayland-backend", + "wayland-client", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-plasma", + "wayland-protocols-wlr", + "x11rb", + "xkbcommon", + "zed-scap", + "zed-xim", +] + +[[package]] +name = "gpui-fast-macos" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e8b377d6dcbc0007e68098cb3f40bc2591a1d29526301e9572a70bb674f171" +dependencies = [ + "accesskit", + "accesskit_macos", + "anyhow", + "block2 0.6.2", + "core-foundation 0.10.1", + "core-foundation-sys", + "core-graphics 0.24.0", + "ctor", + "dispatch2", + "foreign-types", + "futures", + "gpui-fast", + "gpui-fast-apple", + "gpui-pre-collections", + "gpui-pre-scheduler", + "gpui-pre-util", + "image", + "itertools 0.14.0", + "log", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", + "objc2-core-graphics", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-user-notifications", + "parking_lot", + "raw-window-handle", + "semver", + "smallvec", + "strum", + "uuid", +] + +[[package]] +name = "gpui-fast-macros" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e07e9e22196a84bb8cb06c19fc6e5d2218fa11d6b573f914f423970a1b38c97e" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "gpui-fast-platform" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c4b2959631b713899ae6d58236a0ac7c7e404a6cd8c16f30822177eb90a5b59" +dependencies = [ + "anyhow", + "console_error_panic_hook", + "gpui-fast", + "gpui-fast-linux", + "gpui-fast-macos", + "gpui-fast-web", + "gpui-fast-wgpu", + "gpui-fast-windows", + "gpui-pre-ios", +] + +[[package]] +name = "gpui-fast-web" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad903fddb78ae4c8f1c24b7fa07c79a0697da7614183d8c7dad67bd296802901" +dependencies = [ + "anyhow", + "async-channel", + "console_error_panic_hook", + "futures", + "gpui-fast", + "gpui-fast-wgpu", + "gpui-pre-http-client", + "gpui-pre-scheduler", + "js-sys", + "log", + "parking_lot", + "raw-window-handle", + "smallvec", + "unicode-properties", + "unicode-script", + "unicode-segmentation", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm_thread", + "web-sys", + "web-time", +] + +[[package]] +name = "gpui-fast-wgpu" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebf72d3c1fee16dde347707ef306940d39656f80e35d3aaace01075996f12199" +dependencies = [ + "anyhow", + "bytemuck", + "cosmic-text", + "etagere", + "gpui-fast", + "gpui-pre-collections", + "gpui-pre-util", + "image", + "itertools 0.14.0", + "log", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "swash", + "unicode-bidi", + "unicode-segmentation", + "web-sys", + "wgpu", + "zed-font-kit", +] + +[[package]] +name = "gpui-fast-windows" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1a193343ef7faaa18eb9ccc0aadf8ec9571f2791c4419c2ca23aa17198f970" +dependencies = [ + "accesskit", + "accesskit_windows", + "anyhow", + "dunce", + "etagere", + "futures", + "gpui-fast", + "gpui-pre-collections", + "gpui-pre-scheduler", + "gpui-pre-util", + "image", + "itertools 0.14.0", + "log", + "parking_lot", + "rand 0.9.5", + "raw-window-handle", + "smallvec", + "uuid", + "windows 0.62.2", + "windows-core 0.62.2", + "windows-numerics 0.3.1", + "windows-registry 0.6.1", +] + +[[package]] +name = "gpui-kit" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25210f6e59ea9ffac3a033dbce9edafe5ff0dd2900f894fd1316f54da2fe2b89" +dependencies = [ + "gpui-base", + "gpui-component", + "gpui-fast", + "gpui-fast-platform", + "gpui-kit-assets", + "gpui-pre", + "gpui-pre-macros", + "gpui-pre-platform", + "gpui-pre-web", +] + +[[package]] +name = "gpui-kit-assets" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c214017b45e5654665f18faa551f58a2c2c8d25efe6632b1a443ba8edf365e96" +dependencies = [ + "anyhow", + "gpui-pre", + "gpui-pre-reqwest", + "log", + "rust-embed", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "gpui-pre" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df4b5f8d0c278308df2f11e0bfe0212dd77d7848ce1bdc4b9d513334414396f6" +dependencies = [ + "accesskit", + "anyhow", + "async-channel", + "async-task", + "backtrace", + "bitflags 2.13.2", + "chrono", + "ctor", + "derive_more", + "embed-resource", + "etagere", + "futures", + "futures-concurrency", + "getrandom 0.3.4", + "gpui-pre-collections", + "gpui-pre-http-client", + "gpui-pre-macros", + "gpui-pre-refineable", + "gpui-pre-scheduler", + "gpui-pre-shared-string", + "gpui-pre-sum-tree", + "gpui-pre-util", + "heapless", + "image", + "inventory", + "itertools 0.14.0", + "libc", + "log", + "lyon", + "num_cpus", + "objc2-core-foundation", + "objc2-core-video", + "parking", + "parking_lot", + "pin-project", + "pollster 0.4.0", + "postage", + "profiling", + "proptest", + "rand 0.9.5", + "raw-window-handle", + "regex", + "resvg 0.46.0", + "schemars", + "seahash", + "serde", + "serde_json", + "slotmap", + "smallvec", + "spin 0.10.1", + "strum", + "taffy", + "thiserror 2.0.21", + "ttf-parser", + "url", + "usvg 0.46.0", + "uuid", + "waker-fn", + "web-time", + "windows 0.62.2", + "zed-scap", +] + +[[package]] +name = "gpui-pre-apple" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97cd068d8134b4e073321b946491760aa1e4511e486084a92e73b9174bff78a" +dependencies = [ + "anyhow", + "async-task", + "block2 0.6.2", + "cbindgen", + "core-foundation 0.10.1", + "core-foundation-sys", + "core-graphics 0.24.0", + "core-text", + "derive_more", + "dispatch2", + "etagere", + "foreign-types", + "futures", + "gpui-pre", + "gpui-pre-collections", + "gpui-pre-util", + "image", + "libc", + "log", + "mach2", + "metal", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", + "objc2-security", + "parking_lot", + "pathfinder_geometry", + "smallvec", + "thiserror 2.0.21", + "zed-font-kit", +] + +[[package]] +name = "gpui-pre-collections" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f89bf8941a7437dd761161c552543fb8268b9633fe74e29eafbe0014cd2164b" +dependencies = [ + "gpui-pre-util", + "indexmap", + "rustc-hash 2.1.3", +] + +[[package]] +name = "gpui-pre-derive-refineable" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2998b1cebbaa0fa004fe4939a513bbf4103c7fb69ae2e84ee73634554e3f7edc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "gpui-pre-http-client" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e516820ee56ac357a87ff97b1a2c5f22c8d5dcd2a50cdd15c16949f24464d98e" +dependencies = [ + "anyhow", + "bytes", + "futures", + "http", + "http-body", + "log", + "parking_lot", + "serde", + "serde_json", + "serde_urlencoded", + "url", +] + +[[package]] +name = "gpui-pre-ios" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5773a1e3a399df64f3ecc5538727fd0575279bd190959cf97a9e2b698c0310b8" +dependencies = [ + "anyhow", + "block2 0.6.2", + "futures", + "gpui-pre", + "gpui-pre-apple", + "log", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", + "objc2-ui-kit", + "parking_lot", + "raw-window-handle", + "uuid", +] + +[[package]] +name = "gpui-pre-linux" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c6ffd2dce7b75cce0bb3382994912f84c2a05389a4a236bb8bd72cb098fc083" +dependencies = [ + "accesskit", + "accesskit_unix", + "anyhow", + "as-raw-xcb-connection", + "ashpd", + "bytemuck", + "calloop", + "calloop-wayland-source", + "filedescriptor", + "futures", + "gpui-pre", + "gpui-pre-collections", + "gpui-pre-http-client", + "gpui-pre-util", + "gpui-pre-wgpu", + "libc", + "log", + "notify-rust", + "oo7", + "open", + "parking_lot", + "raw-window-handle", + "smallvec", + "smol", + "strum", + "url", + "uuid", + "wayland-backend", + "wayland-client", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-plasma", + "wayland-protocols-wlr", + "x11rb", + "xkbcommon", + "zed-scap", + "zed-xim", +] + +[[package]] +name = "gpui-pre-macos" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e07a5e5c84f0b2160c194a1c852cc89d1942db66867938ceabcd7f763cb4386" +dependencies = [ + "accesskit", + "accesskit_macos", + "anyhow", + "block2 0.6.2", + "core-foundation 0.10.1", + "core-foundation-sys", + "core-graphics 0.24.0", + "ctor", + "dispatch2", + "foreign-types", + "futures", + "gpui-pre", + "gpui-pre-apple", + "gpui-pre-collections", + "gpui-pre-scheduler", + "gpui-pre-util", + "image", + "itertools 0.14.0", + "log", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", + "objc2-core-graphics", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-user-notifications", + "parking_lot", + "raw-window-handle", + "semver", + "smallvec", + "strum", + "uuid", +] + +[[package]] +name = "gpui-pre-macros" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c95d70a9fe10701533606c6135f9a1d4cd96e87e4e6062b3d426eb57b415daf" +dependencies = [ + "heck 0.5.0", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "gpui-pre-platform" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a7f07a15187e82ec76491492c7e3245db1b59633d3bedb00b828ffaf67c4b8" +dependencies = [ + "anyhow", + "console_error_panic_hook", + "gpui-pre", + "gpui-pre-ios", + "gpui-pre-linux", + "gpui-pre-macos", + "gpui-pre-web", + "gpui-pre-wgpu", + "gpui-pre-windows", +] + +[[package]] +name = "gpui-pre-refineable" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ce7e83592bc6c1ead2affd91b333f11b60c3eb7d06cae1605dd56f149fe8674" +dependencies = [ + "gpui-pre-derive-refineable", +] + +[[package]] +name = "gpui-pre-reqwest" +version = "0.12.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05be23908e707966824f8c51a609904b7f30739e8d915e120a53c1b995ba964c" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tokio-socks", + "tokio-util", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "windows-registry 0.4.0", +] + +[[package]] +name = "gpui-pre-scheduler" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87c2c6b0fabcd20e6773a0be30afa1f25637c53a06201bb80ab24a21fe198865" +dependencies = [ + "async-task", + "backtrace", + "chrono", + "flume", + "futures", + "parking_lot", + "rand 0.9.5", + "wasm_thread", + "web-time", +] + +[[package]] +name = "gpui-pre-shared-string" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8068f94355f173558a51998a32985a434af54cc6c7262a060fffc369a505998f" +dependencies = [ + "schemars", + "serde", + "smol_str", +] + +[[package]] +name = "gpui-pre-sum-tree" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ce66c57e9b5fd6c7a90fa9f9de2f9bb342127d670ca3c8fe5885270079eefa" +dependencies = [ + "gpui-pre-ztracing", + "heapless", + "rayon", + "tracing", +] + +[[package]] +name = "gpui-pre-util" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162dc29b2d2c0223ee4bb4e9f5e913eab4f62cad0943eb0c1122a74ac82b0768" +dependencies = [ + "anyhow", + "log", + "which", +] + +[[package]] +name = "gpui-pre-web" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1acd86af2347f0dd8b63c441a5dbd43b3fcd7dac69b340827c3497da5a13d6fb" +dependencies = [ + "anyhow", + "async-channel", + "console_error_panic_hook", + "futures", + "gpui-pre", + "gpui-pre-http-client", + "gpui-pre-scheduler", + "gpui-pre-wgpu", + "js-sys", + "log", + "parking_lot", + "raw-window-handle", + "smallvec", + "unicode-properties", + "unicode-script", + "unicode-segmentation", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm_thread", + "web-sys", + "web-time", +] + +[[package]] +name = "gpui-pre-wgpu" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce693915768aae38bf788f245af75aae78e3e1179245860fc80ce831d0a8f74e" +dependencies = [ + "anyhow", + "bytemuck", + "cosmic-text", + "etagere", + "gpui-pre", + "gpui-pre-collections", + "gpui-pre-util", + "image", + "itertools 0.14.0", + "log", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "swash", + "unicode-bidi", + "unicode-segmentation", + "web-sys", + "wgpu", + "zed-font-kit", +] + +[[package]] +name = "gpui-pre-windows" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80670f987b920fba019917b2e222ecf2b377f2a6d77872010c7d284c235837b3" +dependencies = [ + "accesskit", + "accesskit_windows", + "anyhow", + "dunce", + "etagere", + "futures", + "gpui-pre", + "gpui-pre-collections", + "gpui-pre-scheduler", + "gpui-pre-util", + "image", + "itertools 0.14.0", + "log", + "parking_lot", + "rand 0.9.5", + "raw-window-handle", + "smallvec", + "uuid", + "windows 0.62.2", + "windows-core 0.62.2", + "windows-numerics 0.3.1", + "windows-registry 0.6.1", +] + +[[package]] +name = "gpui-pre-ztracing" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "814cc08c526961c88703806a68ba4cf216a1d988ffbbdc673304f4dd25858952" +dependencies = [ + "gpui-pre-ztracing-macro", + "tracing", +] + +[[package]] +name = "gpui-pre-ztracing-macro" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f9dae92b9bc15baa6e530c90bdd4c689d3710bd4d18c3566deb1d6ae182daf" + +[[package]] +name = "granit-parser" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e20f99e46474f56bd905c56e817ebddcf377a611f94c53ac4649e4d3fa3c0cd0" +dependencies = [ + "arraydeque", + "smallvec", +] + +[[package]] +name = "h2" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d29020232d6aa3fb1daca64c1127cf662cf97f254ae16c18c05b8ab635fc118" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] @@ -1424,25 +3074,32 @@ dependencies = [ [[package]] name = "harfrust" -version = "0.12.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03d949a14aa089bbb282f7dd76a498a7f684428e4257202efc119ec010376f9" +checksum = "9da2e5ae821f6e96664977bf974d6d6a2d6682f9ccee23e62ec1d134246845f9" dependencies = [ "bitflags 2.13.2", "bytemuck", - "read-fonts", + "core_maths", + "read-fonts 0.37.0", "smallvec", ] [[package]] -name = "hashbrown" -version = "0.15.5" +name = "hash32" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" dependencies = [ - "foldhash 0.1.5", + "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.16.1" @@ -1451,7 +3108,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", - "foldhash 0.2.0", + "foldhash", ] [[package]] @@ -1460,9 +3117,31 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ - "foldhash 0.2.0", + "foldhash", ] +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.5.3" @@ -1475,6 +3154,168 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "html5ever" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3e324da4c95177d6291d4c8730197c0d1822f8a9766814a4a44fa5ab797c9c" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "hyper", + "libc", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "2.4.0" @@ -1579,6 +3420,22 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "ignore" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484be5657551d7868d67587df967fb4fcbe9d266a761cc855aaa148fda0b3cc7" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "image" version = "0.25.10" @@ -1587,12 +3444,49 @@ checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" dependencies = [ "bytemuck", "byteorder-lite", + "color_quant", + "exr", + "gif 0.14.2", + "image-webp", "moxcms", "num-traits", - "png", + "png 0.18.1", + "qoi", + "ravif", + "rayon", "tiff", + "zune-core 0.5.3", + "zune-jpeg 0.5.15", ] +[[package]] +name = "image-webp" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +dependencies = [ + "byteorder-lite", + "quick-error 2.0.1", +] + +[[package]] +name = "imagesize" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" + +[[package]] +name = "imagesize" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c" + +[[package]] +name = "imgref" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e44b0a4eaa4c82f441d50a963f2d5f05a787240aeee097597033e72accfd22f" + [[package]] name = "indexmap" version = "2.14.2" @@ -1601,6 +3495,61 @@ checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "inotify" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cc00ea907cab49550b7da656f80ebb97be1b997d931fbcd28d39734e17ce592" +dependencies = [ + "bitflags 2.13.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c033f80b2c113cdf91ab7a33faa9cbc014726dcad99880c8609af2a370edf37d" +dependencies = [ + "libc", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -1613,10 +3562,53 @@ dependencies = [ ] [[package]] -name = "itertools" -version = "0.15.0" +name = "ipnet" +version = "2.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] @@ -1627,36 +3619,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" -[[package]] -name = "jni" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" -dependencies = [ - "cfg-if", - "combine", - "jni-macros", - "jni-sys 0.4.1", - "log", - "simd_cesu8", - "thiserror 2.0.21", - "walkdir", - "windows-link", -] - -[[package]] -name = "jni-macros" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" -dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "simd_cesu8", - "syn 2.0.119", -] - [[package]] name = "jni-sys" version = "0.3.1" @@ -1723,6 +3685,37 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "kqueue" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d763e5b24120b4ddf50de6c92308156765aabfbbccebf401da7cff2d70a41ea" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" +dependencies = [ + "bitflags 2.13.2", + "libc", +] + +[[package]] +name = "kurbo" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62" +dependencies = [ + "arrayvec", + "euclid", + "smallvec", +] + [[package]] name = "kurbo" version = "0.13.1" @@ -1735,12 +3728,34 @@ dependencies = [ "smallvec", ] +[[package]] +name = "lazy_static" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" + +[[package]] +name = "lebe" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" + [[package]] name = "libc" version = "0.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" +[[package]] +name = "libfuzzer-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libloading" version = "0.8.9" @@ -1748,7 +3763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -1763,10 +3778,7 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" dependencies = [ - "bitflags 2.13.2", "libc", - "plain", - "redox_syscall 0.9.5", ] [[package]] @@ -1776,10 +3788,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" [[package]] -name = "linux-raw-sys" -version = "0.4.15" +name = "link-section" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "39c29a617ce3df32c08497bdc1ab6e2376e0b17948ac166a2fbe5977c5954cd9" + +[[package]] +name = "linktime-proc-macro" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e57c38c1e860fd37c604281cdfb1dd2216977fd76a50f85ba2f388ef3219616" [[package]] name = "linux-raw-sys" @@ -1813,6 +3831,37 @@ name = "log" version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" +dependencies = [ + "serde_core", +] + +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "lru-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" + +[[package]] +name = "lsp-types" +version = "0.97.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53353550a17c04ac46c585feb189c2db82154fc84b79c7a66c96c2c644f66071" +dependencies = [ + "bitflags 1.3.2", + "fluent-uri", + "serde", + "serde_json", + "serde_repr", +] [[package]] name = "lua-src" @@ -1833,6 +3882,149 @@ dependencies = [ "which", ] +[[package]] +name = "lyon" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0578bdecb7d6d88987b8b2b1e3a4e2f81df9d0ece1078623324a567904e7b7" +dependencies = [ + "lyon_algorithms", + "lyon_tessellation", +] + +[[package]] +name = "lyon_algorithms" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a6b9d4e8b48acd531fbf1241ad9b270df6e60b6b92bdea1469f4f40899d805" +dependencies = [ + "lyon_path", + "num-traits", +] + +[[package]] +name = "lyon_geom" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82dd26aa4dc0b5b70b9115de59824842bcb43cf4a28e1b1e6d0ad148c93f93e" +dependencies = [ + "arrayvec", + "euclid", + "num-traits", +] + +[[package]] +name = "lyon_path" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c463f9c428b7fc5ec885dcd39ce4aa61e29111d0e33483f6f98c74e89d8621e" +dependencies = [ + "lyon_geom", + "num-traits", +] + +[[package]] +name = "lyon_tessellation" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd4872650e70dc907dd4f7ebc449d7d657a0d2658e423b2e724970870bbbf75b" +dependencies = [ + "float_next_after", + "lyon_path", + "num-traits", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "mac-notification-sys" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd604973958ddcc11b561193c0fb96ba146506ef2f231ef2e7c35fd2cbc9beca" +dependencies = [ + "cc", + "log", + "objc2 0.6.5", + "objc2-foundation 0.3.2", + "time", + "uuid", +] + +[[package]] +name = "mach2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markdown" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5cab8f2cadc416a82d2e783a1946388b31654d391d1c7d92cc1f03e295b1deb" +dependencies = [ + "serde", + "unicode-id", +] + +[[package]] +name = "markup5ever" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +dependencies = [ + "log", + "phf 0.11.3", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "markup5ever_rcdom" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edaa21ab3701bfee5099ade5f7e1f84553fd19228cf332f13cd6e964bf59be18" +dependencies = [ + "html5ever", + "markup5ever", + "tendril", + "xml5ever", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + [[package]] name = "memchr" version = "2.8.3" @@ -1857,6 +4049,37 @@ dependencies = [ "autocfg", ] +[[package]] +name = "metal" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" +dependencies = [ + "bitflags 2.13.2", + "block", + "core-graphics-types 0.2.0", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1877,6 +4100,18 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mio" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.61.2", +] + [[package]] name = "mlua" version = "0.12.2" @@ -1929,6 +4164,12 @@ dependencies = [ "pxfm", ] +[[package]] +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + [[package]] name = "naga" version = "30.0.1" @@ -1936,7 +4177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a616d2fb8c89516ac2723a581f69d6c18576046bed761bd6b305e5618e6ae130" dependencies = [ "arrayvec", - "bit-set", + "bit-set 0.10.0", "bitflags 2.13.2", "cfg-if", "cfg_aliases", @@ -1967,27 +4208,6 @@ dependencies = [ "thiserror 2.0.21", ] -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags 2.13.2", - "jni-sys 0.3.1", - "log", - "ndk-sys", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - [[package]] name = "ndk-sys" version = "0.6.0+11769913" @@ -1997,6 +4217,21 @@ dependencies = [ "jni-sys 0.3.1", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "no_std_io2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" +dependencies = [ + "memchr", +] + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -2012,6 +4247,170 @@ dependencies = [ "memchr", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "normpath" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b11ce00d2594068e8a27c9146fdc5cf9f3ac38eb42c7cd34d05fea618873ac9f" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "notify" +version = "8.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f812702fbc75d35416d3f884e04925be7e9498f4eceea2e24ba34559284674" +dependencies = [ + "bitflags 2.13.2", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "objc2-core-foundation", + "objc2-core-services", + "walkdir", + "windows-sys 0.61.2", +] + +[[package]] +name = "notify-rust" +version = "4.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4587364a9a0074333429b3df75a30a205340c56a536ca3eb6ca0e59b87bbf8af" +dependencies = [ + "futures-lite", + "log", + "mac-notification-sys", + "serde", + "tauri-winrt-notification", + "zbus", +] + +[[package]] +name = "notify-types" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a437a9308232ce794b1e7fdf540d38ea37efc3c73492640c13b4c8568b8f108" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f9a86e097b0d187ad0e65667c2f58b9254671e86e7dbb78036b16692eae099" +dependencies = [ + "libm", + "num-integer", + "num-iter", + "num-traits", + "once_cell", + "rand 0.9.5", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "bytemuck", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2023,25 +4422,34 @@ dependencies = [ ] [[package]] -name = "num_enum" -version = "0.7.6" +name = "num_cpus" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "num_enum_derive", - "rustversion", + "hermit-abi", + "libc", ] [[package]] -name = "num_enum_derive" -version = "0.7.6" +name = "objc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.119", + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", ] [[package]] @@ -2079,8 +4487,8 @@ dependencies = [ "block2 0.5.1", "libc", "objc2 0.5.3", - "objc2-core-data", - "objc2-core-image", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-foundation 0.2.2", "objc2-quartz-core 0.2.2", ] @@ -2093,34 +4501,28 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.13.2", "block2 0.6.2", + "libc", "objc2 0.6.5", + "objc2-cloud-kit", + "objc2-core-data 0.3.2", "objc2-core-foundation", "objc2-core-graphics", + "objc2-core-image 0.3.2", + "objc2-core-text", + "objc2-core-video", "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", ] [[package]] name = "objc2-cloud-kit" -version = "0.2.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ "bitflags 2.13.2", - "block2 0.5.1", - "objc2 0.5.3", - "objc2-core-location", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-contacts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.3", - "objc2-foundation 0.2.2", + "objc2 0.6.5", + "objc2-foundation 0.3.2", ] [[package]] @@ -2135,6 +4537,17 @@ dependencies = [ "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.5", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" @@ -2142,7 +4555,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.13.2", + "block2 0.6.2", "dispatch2", + "libc", "objc2 0.6.5", ] @@ -2172,15 +4587,23 @@ dependencies = [ ] [[package]] -name = "objc2-core-location" -version = "0.2.2" +name = "objc2-core-image" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" dependencies = [ - "block2 0.5.1", - "objc2 0.5.3", - "objc2-contacts", - "objc2-foundation 0.2.2", + "objc2 0.6.5", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-core-services" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583300ad934cba24ff5292aee751ecc070f7ca6b39a574cc21b7b5e588e06a0b" +dependencies = [ + "libc", + "objc2-core-foundation", ] [[package]] @@ -2190,7 +4613,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ "bitflags 2.13.2", + "objc2 0.6.5", "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", + "objc2-metal 0.3.2", ] [[package]] @@ -2207,7 +4646,6 @@ checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.13.2", "block2 0.5.1", - "dispatch", "libc", "objc2 0.5.3", ] @@ -2220,6 +4658,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.13.2", "block2 0.6.2", + "libc", "objc2 0.6.5", "objc2-core-foundation", ] @@ -2235,18 +4674,6 @@ dependencies = [ "objc2-core-foundation", ] -[[package]] -name = "objc2-link-presentation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.3", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", -] - [[package]] name = "objc2-metal" version = "0.2.2" @@ -2299,34 +4726,12 @@ dependencies = [ ] [[package]] -name = "objc2-symbols" -version = "0.2.2" +name = "objc2-security" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" dependencies = [ - "objc2 0.5.3", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" -dependencies = [ - "bitflags 2.13.2", - "block2 0.5.1", - "objc2 0.5.3", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", - "objc2-core-location", - "objc2-foundation 0.2.2", - "objc2-link-presentation", - "objc2-quartz-core 0.2.2", - "objc2-symbols", - "objc2-uniform-type-identifiers", - "objc2-user-notifications", + "objc2-core-foundation", ] [[package]] @@ -2336,33 +4741,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ "bitflags 2.13.2", + "block2 0.6.2", "objc2 0.6.5", "objc2-core-foundation", "objc2-foundation 0.3.2", -] - -[[package]] -name = "objc2-uniform-type-identifiers" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.3", - "objc2-foundation 0.2.2", + "objc2-quartz-core 0.3.2", ] [[package]] name = "objc2-user-notifications" -version = "0.2.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" dependencies = [ "bitflags 2.13.2", - "block2 0.5.1", - "objc2 0.5.3", - "objc2-core-location", - "objc2-foundation 0.2.2", + "block2 0.6.2", + "objc2 0.6.5", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd229a0361b9d0d4396176e02d65897f487eebeab7caa6d443855ee152ca0b9c" +dependencies = [ + "memchr", ] [[package]] @@ -2372,15 +4794,62 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] -name = "orbclient" -version = "0.3.55" +name = "oo7" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" +checksum = "78f2bfed90f1618b4b48dcad9307f25e14ae894e2949642c87c351601d62cebd" dependencies = [ - "libc", - "libredox", + "aes", + "ashpd", + "async-fs", + "async-io", + "async-lock", + "blocking", + "cbc", + "cipher", + "digest 0.10.7", + "endi", + "futures-lite", + "futures-util", + "getrandom 0.4.3", + "hkdf", + "hmac", + "md-5", + "num", + "num-bigint-dig", + "pbkdf2", + "serde", + "serde_bytes", + "sha2 0.10.9", + "subtle", + "zbus", + "zbus_macros", + "zeroize", + "zvariant", ] +[[package]] +name = "open" +version = "5.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d8c8b8e725ad26404d6896eb2f064294a0a7b4f1d9120210d85544684c4ca95" +dependencies = [ + "is-wsl", + "libc", +] + +[[package]] +name = "openssl-probe" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e036b411754132fd6b74e94b74e9a13c5cf606fa93d1885c35860d3060820b1" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "ordered-float" version = "4.6.0" @@ -2400,25 +4869,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "os_pipe" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "owned_ttf_parser" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" -dependencies = [ - "ttf-parser", -] - [[package]] name = "parking" version = "2.2.1" @@ -2443,28 +4893,50 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", - "windows-link", + "windows-link 0.2.1", ] [[package]] -name = "parlance" -version = "0.1.1" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73072a9470554c8e794778acece2312661218aaabb635600957d952cf01c716e" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "peniko" -version = "0.6.1" +name = "pastey" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "839c8299360d2e998bdb106dc0a6cd71dcc5f4df51df1b620361bf50e283cca6" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" + +[[package]] +name = "pathfinder_geometry" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" dependencies = [ - "bytemuck", - "color", - "kurbo", - "linebender_resource_handle", - "smallvec", + "log", + "pathfinder_simd", +] + +[[package]] +name = "pathfinder_simd" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4500030c302e4af1d423f36f3b958d1aecb6c04184356ed5a833bf6b60435777" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", ] [[package]] @@ -2474,45 +4946,63 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "petgraph" -version = "0.8.3" +name = "phf" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ - "fixedbitset", - "hashbrown 0.15.5", - "indexmap", + "phf_shared 0.11.3", ] [[package]] name = "phf" -version = "0.14.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "010378780309880b08997fae13be7834dba947d36393bd372f2b1556deb2a2f6" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ "phf_macros", - "phf_shared", + "phf_shared 0.13.1", "serde", ] [[package]] -name = "phf_generator" -version = "0.14.0" +name = "phf_codegen" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb62e0959d5a1bebc965f4d15d9e2b7cea002b6b0f5ba8cde6cc26738467100" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.8", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ "fastrand", - "phf_shared", + "phf_shared 0.13.1", ] [[package]] name = "phf_macros" -version = "0.14.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fa8d0ca26d424d27630da600c6624696e7dec8bf7b3b492b383c5dc49e5e085" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", "syn 2.0.119", @@ -2520,13 +5010,28 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.14.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fd9027e2d9319be6349febd1db4e8d02aa544921200c9b777720ac34a3aa89" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.13" @@ -2571,10 +5076,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] -name = "plain" -version = "0.2.3" +name = "png" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.9", +] [[package]] name = "png" @@ -2589,16 +5101,6 @@ dependencies = [ "miniz_oxide 0.8.9", ] -[[package]] -name = "poll-promise" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6a58fecbf9da8965bcdb20ce4fd29788d1acee68ddbb64f0ba1b81bccdb7df" -dependencies = [ - "document-features", - "static_assertions", -] - [[package]] name = "polling" version = "3.11.0" @@ -2609,15 +5111,21 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.1.6", + "rustix", "windows-sys 0.61.2", ] [[package]] name = "pollster" -version = "1.0.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6355899e1c9462875b6757c79f3caa011a1fdae12bbb1a2e72dd1f234f8336" +checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7" + +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" [[package]] name = "polycool" @@ -2643,6 +5151,21 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "postage" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af3fb618632874fb76937c2361a7f22afd393c982a2165595407edc75b06d3c1" +dependencies = [ + "atomic", + "crossbeam-queue", + "parking_lot", + "pin-project", + "pollster 0.2.5", + "static_assertions", + "thiserror 1.0.69", +] + [[package]] name = "potential_utf" version = "0.1.6" @@ -2652,6 +5175,27 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "presser" version = "0.3.1" @@ -2664,7 +5208,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit", + "toml_edit 0.25.17+spec-1.1.0", ] [[package]] @@ -2681,6 +5225,75 @@ name = "profiling" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "proptest" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8530004ccb15eae51c7e40009fbe317f341f804db54dc033eec1c50be28cfa0" +dependencies = [ + "bit-set 0.11.1", + "bit-vec 0.10.1", + "bitflags 2.13.2", + "chacha20", + "core_detect", + "num-traits", + "proptest-macro", + "rand 0.10.3", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "proptest-macro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e99782ea31698c2206c6887c1220d2f594b291c26cb9ec5b6d7cf175320bc212" +dependencies = [ + "convert_case 0.11.0", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "pulp" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046aa45b989642ec2e4717c8e72d677b13edd831a4d3b6cf37d9a3e54912496a" +dependencies = [ + "bytemuck", + "cfg-if", + "libm", + "num-complex", + "paste", + "pulp-wasm-simd-flag", + "raw-cpuid", + "reborrow", + "version_check", +] + +[[package]] +name = "pulp-wasm-simd-flag" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8f70e07b9c3962945a74e59ca1c511bba65b6419468acc217c457d93f3c740" [[package]] name = "pxfm" @@ -2688,6 +5301,21 @@ version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-error" version = "2.0.1" @@ -2703,6 +5331,62 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4051e23e9185c255a7e33ef59cdbca87a22d359052eecd22fc6b901fb37d9d11" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.3", + "rustls", + "socket2", + "thiserror 2.0.21", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e750cca55fe4f0439a15d0bb529da9651e79993e8e72c61a899a36d462befbe" +dependencies = [ + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand 0.10.3", + "rand_pcg", + "ring", + "rustc-hash 2.1.3", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.21", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af66907df18639dcf4db56ca65490cabc4b27a97dbadd96f2926cca73298f016" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.61.2", +] + [[package]] name = "quote" version = "1.0.47" @@ -2724,12 +5408,171 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rand" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60aa6af80be32871323012e02e6e65f8a7cc7890931ae421d217ad8fe0df2ccf" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "range-alloc" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" +[[package]] +name = "rangemap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a611d15b50743feb4c76b7d03edcb0e64f399c26961e4efe6975bc398be6aa3d" + +[[package]] +name = "rav1e" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b" +dependencies = [ + "aligned-vec", + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av-scenechange", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.14.0", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "paste", + "profiling", + "rand 0.9.5", + "rand_chacha 0.9.0", + "simd_helpers", + "thiserror 2.0.21", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error 2.0.1", + "rav1e", + "rayon", + "rgb", +] + +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.13.2", +] + [[package]] name = "raw-window-handle" version = "0.6.2" @@ -2748,6 +5591,37 @@ dependencies = [ "objc2-quartz-core 0.3.2", ] +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "read-fonts" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5" +dependencies = [ + "bytemuck", + "core_maths", + "font-types 0.11.3", +] + [[package]] name = "read-fonts" version = "0.41.0" @@ -2755,18 +5629,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" dependencies = [ "bytemuck", - "font-types", + "font-types 0.12.7", "once_cell", ] [[package]] -name = "redox_syscall" -version = "0.4.1" +name = "reborrow" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] +checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" [[package]] name = "redox_syscall" @@ -2778,12 +5649,44 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.9.5" +name = "redox_users" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "580c875845b41ecb1564ad1ae4703044cef774145e3d7a94dc2b3fa7c97868fd" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "bitflags 2.13.2", + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" +dependencies = [ + "libredox", + "thiserror 2.0.21", +] + +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", ] [[package]] @@ -2821,6 +5724,78 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "resvg" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8928798c0a55e03c9ca6c4c6846f76377427d2c1e1f7e6de3c06ae57942df43" +dependencies = [ + "gif 0.13.3", + "image-webp", + "log", + "pico-args", + "rgb", + "svgtypes 0.15.3", + "tiny-skia", + "usvg 0.45.1", + "zune-jpeg 0.4.21", +] + +[[package]] +name = "resvg" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b563218631706d614e23059436526d005b50ab5f2d506b55a17eb65c5eb83419" +dependencies = [ + "gif 0.14.2", + "image-webp", + "log", + "pico-args", + "rgb", + "svgtypes 0.16.1", + "tiny-skia", + "usvg 0.46.0", + "zune-jpeg 0.5.15", +] + +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ropey" +version = "2.0.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4045a00dc327d084a2bbf126976e14125b54f23bd30511d45b842eba76c52d74" +dependencies = [ + "str_indices", +] + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + [[package]] name = "roxmltree" version = "0.21.2" @@ -2830,6 +5805,97 @@ dependencies = [ "memchr", ] +[[package]] +name = "rust-embed" +version = "8.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19afa5b4b6a611de00bd1bdae6ae6f39084c9399f0679c3f52d8469cf335cc23" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0d8afda6374eac59e066abee06d265247ebbaf3006cf878e2879e8356e34053" +dependencies = [ + "mime_guess", + "proc-macro2", + "quote", + "rust-embed-utils", + "shellexpand", + "syn 2.0.119", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d84e8ba78bd384263e5922f084cbe1b081c3b7e69add59c8fb097b879ba968a" +dependencies = [ + "globset", + "sha2 0.11.1", + "walkdir", +] + +[[package]] +name = "rust-i18n" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8502e73e6461c738659455c5d2cf95bc132760a6f203c717e66ee72b78906d7f" +dependencies = [ + "globwalk", + "regex", + "rust-i18n-macro", + "rust-i18n-support", + "smallvec", +] + +[[package]] +name = "rust-i18n-macro" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54a28dd9d46108d56b9f0c85b220908844233e561c03087890325104f90f2c6" +dependencies = [ + "glob", + "proc-macro2", + "quote", + "rust-i18n-support", + "serde", + "serde_json", + "syn 2.0.119", +] + +[[package]] +name = "rust-i18n-support" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e806c2a9701cbd6043992cd935c30cb1fdb128fa15e7b506f3b46f97045737c0" +dependencies = [ + "arc-swap", + "base62", + "foldhash", + "globwalk", + "itertools 0.11.0", + "normpath", + "serde", + "serde-saphyr", + "serde_json", + "siphasher", + "toml 0.8.23", + "triomphe", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2851,19 +5917,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.13.2", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - [[package]] name = "rustix" version = "1.1.6" @@ -2873,16 +5926,108 @@ dependencies = [ "bitflags 2.13.2", "errno", "libc", - "linux-raw-sys 0.12.1", + "linux-raw-sys", "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e13bd8c0e9365c43cfa5c9e8f9ad49d3c8444926c9aac819e0e4dc503c8fdf" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a073f5dc7469f984c52ad2752b63b0807745133b6de880b7b64c1ac4c48aec4" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443b1b6d39d7c663139942cc4558262562d2c84123bb6282ef177009ca8b281" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "rustybuzz" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" +dependencies = [ + "bitflags 2.13.2", + "bytemuck", + "core_maths", + "log", + "smallvec", + "ttf-parser", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "same-file" version = "1.0.6" @@ -2892,6 +6037,41 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cb23c424d8ee841bb4d813677ca237e2a610067d594fec130f87d6093495ab5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "schemars" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab508826f74a77ca9d5aba6ff19b522583ee3eaf28a19384ff3d0e5835fadf6e" +dependencies = [ + "dyn-clone", + "indexmap", + "ref-cast", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1c3a92094fa7d61aa124645844facb6b554dfc797136d0f5fd1f890e2bffc69" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 3.0.9", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -2905,16 +6085,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "sctk-adwaita" -version = "0.10.1" +name = "screencapturekit" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +checksum = "1a5eeeb57ac94960cfe5ff4c402be6585ae4c8d29a2cf41b276048c2e849d64e" dependencies = [ - "ab_glyph", - "log", - "memmap2", - "smithay-client-toolkit 0.19.2", - "tiny-skia", + "screencapturekit-sys", +] + +[[package]] +name = "screencapturekit-sys" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22411b57f7d49e7fe08025198813ee6fd65e1ee5eff4ebc7880c12c82bde4c60" +dependencies = [ + "block", + "dispatch", + "objc", + "objc-foundation", + "objc_id", + "once_cell", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] @@ -2928,12 +6147,10 @@ name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" +dependencies = [ + "serde", + "serde_core", +] [[package]] name = "serde" @@ -2945,6 +6162,33 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-saphyr" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8050abb251097357e24aff63ba2c52a6309ecb7d23a5474023df960a02694d8" +dependencies = [ + "annotate-snippets", + "base64 0.23.1", + "encoding_rs_io", + "granit-parser", + "nohash-hasher", + "num-traits", + "serde_core", + "smallvec", + "zmij", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.229" @@ -2965,13 +6209,24 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "serde_derive_internals" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + [[package]] name = "serde_json" version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" dependencies = [ - "foldhash 0.2.0", + "foldhash", "indexmap", "itoa", "memchr", @@ -2991,6 +6246,73 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7523beb55eece201a2356bee0bbca0d1ab466c14c07703b2e0ee6d42cb0c2c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d7069beb7d6ac7b9acd1039986e73443f24234f41074da099d6f994ac9ad19" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", +] + +[[package]] +name = "shellexpand" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32824fab5e16e6c4d86dc1ba84489390419a39f97699852b66480bb87d297ed8" +dependencies = [ + "dirs 6.0.0", +] + [[package]] name = "shlex" version = "2.0.1" @@ -3014,13 +6336,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] -name = "simd_cesu8" -version = "1.2.0" +name = "simd_helpers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" dependencies = [ - "rustc_version", - "simdutf8", + "quote", ] [[package]] @@ -3029,12 +6350,41 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +dependencies = [ + "bstr", + "unicode-segmentation", +] + +[[package]] +name = "simplecss" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c" +dependencies = [ + "log", +] + [[package]] name = "siphasher" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33f4fe9184a62d842c9ef383018f3306d8ba224fd9d836f56d7288308847c256" +[[package]] +name = "skrifa" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac" +dependencies = [ + "bytemuck", + "read-fonts 0.37.0", +] + [[package]] name = "skrifa" version = "0.44.0" @@ -3042,7 +6392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68" dependencies = [ "bytemuck", - "read-fonts", + "read-fonts 0.41.0", ] [[package]] @@ -3067,75 +6417,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" [[package]] -name = "smithay-client-toolkit" -version = "0.19.2" +name = "smol" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" dependencies = [ - "bitflags 2.13.2", - "calloop 0.13.0", - "calloop-wayland-source 0.3.0", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 0.38.44", - "thiserror 1.0.69", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols", - "wayland-protocols-wlr", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smithay-client-toolkit" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" -dependencies = [ - "bitflags 2.13.2", - "calloop 0.14.5", - "calloop-wayland-source 0.4.1", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 1.1.6", - "thiserror 2.0.21", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols", - "wayland-protocols-experimental", - "wayland-protocols-misc", - "wayland-protocols-wlr", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smithay-clipboard" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226" -dependencies = [ - "libc", - "smithay-client-toolkit 0.20.0", - "wayland-backend", + "async-channel", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-net", + "async-process", + "blocking", + "futures-lite", ] [[package]] name = "smol_str" -version = "0.2.2" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +checksum = "eeb7109d23f319619d4cc0de5464613c8b7b1a09db2774a58101459cf6be2f10" dependencies = [ - "serde", + "serde_core", +] + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spin" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" +dependencies = [ + "lock_api", ] [[package]] @@ -3159,6 +6491,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "str_indices" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6" + [[package]] name = "streaming-iterator" version = "0.1.9" @@ -3170,6 +6508,98 @@ name = "strict-num" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "svg_fmt" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" + +[[package]] +name = "svgtypes" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" +dependencies = [ + "kurbo 0.11.3", + "siphasher", +] + +[[package]] +name = "svgtypes" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695b5790b3131dafa99b3bbfd25a216edb3d216dad9ca208d4657bfb8f2abc3d" +dependencies = [ + "kurbo 0.13.1", + "siphasher", +] + +[[package]] +name = "swash" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2499c2d826531388872b2268718aed907a39bd785ab0dcfe57fab26283f92e" +dependencies = [ + "skrifa 0.44.0", + "yazi", + "zeno", +] [[package]] name = "syn" @@ -3193,6 +6623,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.14.0" @@ -3213,6 +6652,75 @@ dependencies = [ "libc", ] +[[package]] +name = "sysinfo" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows 0.57.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "taffy" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8480887e8803986d96a7173729565520d4bbb721ad6b7ad6941a22897207aa" +dependencies = [ + "serde", + "slotmap", + "smallvec", +] + +[[package]] +name = "tao-core-video-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "objc", +] + +[[package]] +name = "tauri-winrt-notification" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37a6c354fd28fc9e322ed9bd47e3959576dad28c9d58ea1cf888cce1c7ccb36" +dependencies = [ + "thiserror 2.0.21", + "windows 0.62.2", + "windows-version", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -3222,10 +6730,21 @@ dependencies = [ "fastrand", "getrandom 0.4.3", "once_cell", - "rustix 1.1.6", + "rustix", "windows-sys 0.61.2", ] +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -3284,9 +6803,37 @@ dependencies = [ "fax", "flate2", "half", - "quick-error", + "quick-error 2.0.1", "weezl", - "zune-jpeg", + "zune-jpeg 0.5.15", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", ] [[package]] @@ -3300,6 +6847,7 @@ dependencies = [ "bytemuck", "cfg-if", "log", + "png 0.17.16", "tiny-skia-path", ] @@ -3324,13 +6872,96 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" + [[package]] name = "tokio" version = "1.54.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b52fd3255258d26fac7264ab5a76b53c13367136dc011d3d6ad4f8ed070396a3" dependencies = [ + "bytes", + "libc", + "mio", "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9cc2678c2cdd569ef8215e2afd7954ada2ae20b4fdd2c5fe6139a3b02d105db" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-socks" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7e2948f60dbe26b35f2c7fb74ac2854c1fddded0fe9d7548fcc674a246f7615" +dependencies = [ + "either", + "futures-util", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e464cf451ba96ebfc6f9b6542f17ee8b8956e33f1e40d9690624e59d7a7f8a4b" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "libc", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", +] + +[[package]] +name = "toml" +version = "1.1.8+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned 1.1.2", + "toml_datetime 1.1.2+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.4", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", ] [[package]] @@ -3342,6 +6973,20 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.15", +] + [[package]] name = "toml_edit" version = "0.25.17+spec-1.1.0" @@ -3349,9 +6994,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3641d5bbb5349a79e1020a242d251efbc546ad8048d133958323ce9c40a9c9c" dependencies = [ "indexmap", - "toml_datetime", + "toml_datetime 1.1.2+spec-1.1.0", "toml_parser", - "winnow", + "winnow 1.0.4", ] [[package]] @@ -3360,9 +7005,48 @@ version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" dependencies = [ - "winnow", + "winnow 1.0.4", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "toml_writer" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.44" @@ -3397,9 +7081,9 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.25.10" +version = "0.26.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87" +checksum = "17ebdd3a5a7e28a1890b876fdbd0c3c0fe0a6336cffaa104f11b9f720c9daa29" dependencies = [ "cc", "regex", @@ -3466,30 +7150,36 @@ dependencies = [ ] [[package]] -name = "tree_magic_mini" -version = "3.2.2" +name = "triomphe" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8765b90061cba6c22b5831f675da109ae5561588290f9fa2317adab2714d5a6" +checksum = "0d15f4f5898bcfc5d8a8e45ed30b2f108d710c1a2e5489dbf80e078f707181bc" dependencies = [ - "memchr", - "nom", - "petgraph", + "arc-swap", + "serde", + "stable_deref_trait", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "ttf-parser" version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] [[package]] -name = "type-map" -version = "0.5.1" +name = "typenum" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" -dependencies = [ - "rustc-hash 2.1.3", -] +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "uds_windows" @@ -3503,10 +7193,40 @@ dependencies = [ ] [[package]] -name = "unicode-general-category" -version = "1.1.0" +name = "unarray" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicase" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357cc3acc6a036009fd6c973ed009037c732d60d0b4f6c673e9041497482a28f" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe" + +[[package]] +name = "unicode-ccc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" + +[[package]] +name = "unicode-id" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65dd75ab2d9d379dbe86d4059e91d8b5a6e7054865eaba1ddbfc7a817ff96392" [[package]] name = "unicode-ident" @@ -3515,10 +7235,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" [[package]] -name = "unicode-properties" -version = "0.1.4" +name = "unicode-linebreak" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-script" @@ -3532,12 +7258,30 @@ version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + [[package]] name = "unicode-width" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca718471876992059f251e33aafc334346ada08042b7661dd1fe313a9bced557" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -3550,6 +7294,66 @@ dependencies = [ "serde", ] +[[package]] +name = "usvg" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef" +dependencies = [ + "base64 0.22.1", + "data-url", + "flate2", + "fontdb", + "imagesize 0.13.0", + "kurbo 0.11.3", + "log", + "pico-args", + "roxmltree 0.20.0", + "rustybuzz", + "simplecss", + "siphasher", + "strict-num", + "svgtypes 0.15.3", + "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "usvg" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e419dff010bb12512b0ae9e3d2f318dfbdf0167fde7eb05465134d4e8756076f" +dependencies = [ + "base64 0.22.1", + "data-url", + "flate2", + "fontdb", + "imagesize 0.14.0", + "kurbo 0.13.1", + "log", + "pico-args", + "roxmltree 0.21.2", + "rustybuzz", + "simplecss", + "siphasher", + "strict-num", + "svgtypes 0.16.1", + "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -3562,38 +7366,22 @@ version = "1.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a0e2d11620c50695fe12bbbfde96b3477fe606e7284c22d505c12ce51214514" dependencies = [ + "getrandom 0.4.3", "js-sys", "serde_core", + "sha1_smol", "wasm-bindgen", ] [[package]] -name = "vello_common" -version = "0.2.0" +name = "v_frame" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb2141a2bca6e6d598e471fd4d1d7eed8e020aad6a28187edda07f091a325dd" +checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2" dependencies = [ - "bytemuck", - "fearless_simd", - "guillotiere", - "log", - "peniko", - "png", - "smallvec", - "thiserror 2.0.21", -] - -[[package]] -name = "vello_cpu" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace506ca414548966fcf3c283be94eb1cad8254de488791ee698bf438b0890a9" -dependencies = [ - "bytemuck", - "glifo", - "hashbrown 0.17.1", - "png", - "vello_common", + "aligned-vec", + "num-traits", + "wasm-bindgen", ] [[package]] @@ -3602,6 +7390,41 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "walkdir" version = "2.5.0" @@ -3612,6 +7435,21 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4cdd0dd910afe868b7ef477227d8d538b46b3075031afee8a9f2acb0a2ed0b" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + [[package]] name = "wasip2" version = "1.0.4+wasi-0.2.12" @@ -3677,6 +7515,31 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasm_thread" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7516db7f32decdadb1c3b8deb1b7d78b9df7606c5cc2f6241737c2ab3a0258e" +dependencies = [ + "futures", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wayland-backend" version = "0.3.17" @@ -3685,7 +7548,8 @@ checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078" dependencies = [ "cc", "downcast-rs", - "rustix 1.1.6", + "log", + "rustix", "scoped-tls", "smallvec", "wayland-sys", @@ -3698,29 +7562,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073" dependencies = [ "bitflags 2.13.2", - "rustix 1.1.6", + "rustix", "wayland-backend", "wayland-scanner", ] -[[package]] -name = "wayland-csd-frame" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" -dependencies = [ - "bitflags 2.13.2", - "cursor-icon", - "wayland-backend", -] - [[package]] name = "wayland-cursor" version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" dependencies = [ - "rustix 1.1.6", + "rustix", "wayland-client", "xcursor", ] @@ -3737,32 +7590,6 @@ dependencies = [ "wayland-scanner", ] -[[package]] -name = "wayland-protocols-experimental" -version = "20250721.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" -dependencies = [ - "bitflags 2.13.2", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-misc" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" -dependencies = [ - "bitflags 2.13.2", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - [[package]] name = "wayland-protocols-plasma" version = "0.3.12" @@ -3832,22 +7659,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webbrowser" -version = "1.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c8ddfbbf66e501434657400268cefe51b95140a0266236415cda7627732df7" -dependencies = [ - "jni", - "log", - "ndk-context", - "objc2 0.6.5", - "objc2-app-kit 0.3.2", - "objc2-foundation 0.3.2", - "url", - "web-sys", -] - [[package]] name = "weezl" version = "0.1.12" @@ -3891,8 +7702,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c018fce9b6270aa203c2fdd56f3cce996713534bd757e4ea58c8560b121f14" dependencies = [ "arrayvec", - "bit-set", - "bit-vec", + "bit-set 0.10.0", + "bit-vec 0.9.1", "bitflags 2.13.2", "bytemuck", "cfg_aliases", @@ -3964,7 +7775,7 @@ dependencies = [ "android_system_properties", "arrayvec", "ash", - "bit-set", + "bit-set 0.10.0", "bitflags 2.13.2", "block2 0.6.2", "bytemuck", @@ -4006,9 +7817,9 @@ dependencies = [ "web-sys", "wgpu-naga-bridge", "wgpu-types", - "windows", - "windows-core", - "windows-result", + "windows 0.62.2", + "windows-core 0.62.2", + "windows-result 0.4.1", ] [[package]] @@ -4046,6 +7857,22 @@ dependencies = [ "libc", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.11" @@ -4055,16 +7882,77 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections 0.2.0", + "windows-core 0.61.2", + "windows-future 0.2.1", + "windows-link 0.1.3", + "windows-numerics 0.2.0", +] + [[package]] name = "windows" version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ - "windows-collections", - "windows-core", - "windows-future", - "windows-numerics", + "windows-collections 0.3.2", + "windows-core 0.62.2", + "windows-future 0.3.2", + "windows-numerics 0.3.1", +] + +[[package]] +name = "windows-capture" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a4df73e95feddb9ec1a7e9c2ca6323b8c97d5eeeff78d28f1eccdf19c882b24" +dependencies = [ + "parking_lot", + "rayon", + "thiserror 2.0.21", + "windows 0.61.3", + "windows-future 0.2.1", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", ] [[package]] @@ -4073,7 +7961,45 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-core", + "windows-core 0.62.2", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] @@ -4082,11 +8008,22 @@ version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading 0.1.0", ] [[package]] @@ -4095,9 +8032,31 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "windows-core", - "windows-link", - "windows-threading", + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading 0.2.1", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -4111,6 +8070,28 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "windows-interface" version = "0.59.3" @@ -4122,20 +8103,85 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + [[package]] name = "windows-numerics" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.62.2", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result 0.3.4", + "windows-strings 0.3.1", + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", ] [[package]] @@ -4144,7 +8190,35 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", ] [[package]] @@ -4153,7 +8227,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", ] [[package]] @@ -4162,16 +8245,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -4180,7 +8254,22 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -4189,14 +8278,40 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", ] [[package]] @@ -4205,51 +8320,144 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -4257,55 +8465,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winit" -version = "0.30.13" +name = "windows_x86_64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ - "ahash", - "android-activity", - "atomic-waker", - "bitflags 2.13.2", - "block2 0.5.1", - "bytemuck", - "calloop 0.13.0", - "cfg_aliases", - "concurrent-queue", - "core-foundation", - "core-graphics", - "cursor-icon", - "dpi", - "js-sys", - "libc", - "memmap2", - "ndk", - "objc2 0.5.3", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "objc2-ui-kit 0.2.2", - "orbclient", - "percent-encoding", - "pin-project", - "raw-window-handle", - "redox_syscall 0.4.1", - "rustix 0.38.44", - "sctk-adwaita", - "smithay-client-toolkit 0.19.2", - "smol_str", - "tracing", - "unicode-segmentation", - "wasm-bindgen", - "wasm-bindgen-futures", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-plasma", - "web-sys", - "web-time", - "windows-sys 0.52.0", - "x11-dl", - "x11rb", - "xkbcommon-dl", + "memchr", ] [[package]] @@ -4317,30 +8488,31 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10" +dependencies = [ + "cfg-if", + "windows-sys 0.61.2", +] + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wl-clipboard-rs" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "959c7ac3b8afde864f7a7448ac16f29b2b83350b7eccbf77fb781c3999aa6848" -dependencies = [ - "libc", - "log", - "os_pipe", - "rustix 1.1.6", - "thiserror 2.0.21", - "tree_magic_mini", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-wlr", -] - [[package]] name = "writeable" version = "0.6.4" @@ -4348,13 +8520,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] -name = "x11-dl" +name = "x11" version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" dependencies = [ "libc", - "once_cell", "pkg-config", ] @@ -4367,10 +8538,9 @@ dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", - "libloading", - "once_cell", - "rustix 1.1.6", + "rustix", "x11rb-protocol", + "xcursor", ] [[package]] @@ -4379,6 +8549,18 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" +[[package]] +name = "xcb" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6c2ad15e0e922856ee89afe862b8992334bbe7953adad56cd1199358cb30566" +dependencies = [ + "bitflags 2.13.2", + "libc", + "quick-xml", + "x11", +] + [[package]] name = "xcursor" version = "0.3.11" @@ -4386,15 +8568,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23" [[package]] -name = "xkbcommon-dl" -version = "0.4.2" +name = "xim-ctext" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +checksum = "2ac61a7062c40f3c37b6e82eeeef835d5cc7824b632a72784a89b3963c33284c" +dependencies = [ + "encoding_rs", +] + +[[package]] +name = "xim-parser" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcee45f89572d5a65180af3a84e7ddb24f5ea690a6d3aa9de231281544dd7b7" dependencies = [ "bitflags 2.13.2", - "dlib", - "log", - "once_cell", +] + +[[package]] +name = "xkbcommon" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9" +dependencies = [ + "as-raw-xcb-connection", + "libc", + "memmap2", "xkeysym", ] @@ -4410,6 +8609,35 @@ version = "0.8.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" +[[package]] +name = "xml5ever" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bbb26405d8e919bc1547a5aa9abc95cbfa438f04844f5fdd9dc7596b748bf69" +dependencies = [ + "log", + "mac", + "markup5ever", +] + +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "y4m" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" + +[[package]] +name = "yazi" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" + [[package]] name = "yeslogic-fontconfig-sys" version = "6.0.1" @@ -4466,14 +8694,14 @@ dependencies = [ "hex", "libc", "ordered-stream", - "rustix 1.1.6", + "rustix", "serde", "serde_repr", "tracing", "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow", + "winnow 1.0.4", "zbus_macros", "zbus_names", "zvariant", @@ -4525,7 +8753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812a12be4ead7a59e18ea8f047d08add0066b73bc62fc1467066a2472ae088dd" dependencies = [ "serde", - "winnow", + "winnow 1.0.4", "zvariant", ] @@ -4536,7 +8764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a" dependencies = [ "serde", - "winnow", + "winnow 1.0.4", "zbus_names", "zvariant", ] @@ -4550,6 +8778,73 @@ dependencies = [ "serde", ] +[[package]] +name = "zed-font-kit" +version = "0.14.1-zed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3898e450f36f852edda72e3f985c34426042c4951790b23b107f93394f9bff5" +dependencies = [ + "bitflags 2.13.2", + "byteorder", + "core-foundation 0.10.1", + "core-graphics 0.24.0", + "core-text", + "dirs 5.0.1", + "dwrote", + "float-ord", + "freetype-sys", + "lazy_static", + "libc", + "log", + "pathfinder_geometry", + "pathfinder_simd", + "walkdir", + "winapi", + "yeslogic-fontconfig-sys", +] + +[[package]] +name = "zed-scap" +version = "0.0.8-zed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b338d705ae33a43ca00287c11129303a7a0aa57b101b72a1c08c863f698ac8" +dependencies = [ + "anyhow", + "cocoa", + "core-graphics-helmer-fork", + "log", + "objc", + "rand 0.8.8", + "screencapturekit", + "screencapturekit-sys", + "sysinfo", + "tao-core-video-sys", + "windows 0.61.3", + "windows-capture", + "x11", + "xcb", +] + +[[package]] +name = "zed-xim" +version = "0.4.0-zed" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0b46ed118eba34d9ba53d94ddc0b665e0e06a2cf874cfa2dd5dec278148642" +dependencies = [ + "ahash", + "hashbrown 0.14.5", + "log", + "x11rb", + "xim-ctext", + "xim-parser", +] + +[[package]] +name = "zeno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" + [[package]] name = "zerocopy" version = "0.8.63" @@ -4591,6 +8886,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13084392c5e4bc371903e2935a5eaeed24905a7511356b883835e18a78f6879" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "zerotrie" version = "0.2.5" @@ -4636,19 +8951,43 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + [[package]] name = "zune-core" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" +dependencies = [ + "zune-core 0.4.12", +] + [[package]] name = "zune-jpeg" version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ - "zune-core", + "zune-core 0.5.3", ] [[package]] @@ -4660,7 +8999,8 @@ dependencies = [ "endi", "enumflags2", "serde", - "winnow", + "serde_bytes", + "winnow 1.0.4", "zcheapstr", "zvariant_derive", "zvariant_utils", @@ -4689,5 +9029,5 @@ dependencies = [ "quote", "serde", "syn 3.0.9", - "winnow", + "winnow 1.0.4", ] diff --git a/Cargo.toml b/Cargo.toml index faa13bd..17ff95b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,20 +1,20 @@ [package] -name = "egui-rust-test" +name = "gpui-editor-test" version = "0.1.0" edition = "2024" [dependencies] -egui = "0.37" -eframe = { version = "0.37", features = ["wayland", "x11", "default_fonts"] } +gpui-kit = { version = "0.8.1", features = [ + "tree-sitter", + "tree-sitter-rust", + "tree-sitter-go", + "tree-sitter-javascript", + "tree-sitter-python", +] } mlua = { version = "0.12", features = ["lua54", "vendored", "macros"] } -# tree-sitter и грамматики для подсветки синтаксиса. -tree-sitter = "0.25" -tree-sitter-rust = "0.24" -tree-sitter-go = "0.23" -tree-sitter-javascript = "0.23" -tree-sitter-json = "0.24" -tree-sitter-python = "0.23" +[dev-dependencies] +gpui-kit = { version = "0.8.1", features = ["test-support"] } [profile.dev] opt-level = 1 diff --git a/init.lua b/init.lua index c81e6ba..cf0574b 100644 --- a/init.lua +++ b/init.lua @@ -27,8 +27,10 @@ print("[lua] init.lua выполнен") -- -- "" C при зажатом Shift -- -- "" Z при зажатом Ctrl -- -- "" отпускание R при зажатом Alt --- -- клавиша берётся по физическому коду: --- -- Caps Lock и раскладка не важны +-- -- клавиша сравнивается с именем клавиши от GPUI: +-- -- Caps Lock не важен; на Linux и Windows буквы +-- -- берутся по аппаратному keycode, поэтому +-- -- работает и на русской раскладке -- app:close() -- закрыть окно -- app:toggle_maximize() -- app:set_maximized(true/false) diff --git a/src/api.rs b/src/api.rs index 20f5441..6f625a1 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,22 +1,57 @@ //! Глобальный API приложения. //! //! Единственная точка входа для команд управления окном и редактором: UI-код -//! не работает с `ViewportCommand` и состоянием редактора напрямую, а вызывает +//! и Lua-сценарии не трогают `Window` и состояние вида напрямую, а вызывают //! методы [`AppApi`]. +//! +//! Команды окна не выполняются в момент вызова: Lua-обработчик выполняется вне +//! контекста `App`/`Window`, поэтому [`AppApi`] складывает их в очередь, а вид +//! вычитывает её в начале кадра. -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; +use std::collections::VecDeque; use std::rc::Rc; -use eframe::egui; - -use crate::editor::EditorState; +use crate::editor::{Language, Workspace}; use crate::keymap::{KeyBinding, KeyMap}; -use crate::syntax::Language; thread_local! { - /// Текущий экземпляр API. `thread_local`, потому что `egui::Context` привязан - /// к потоку с event loop; заодно это делает тесты независимыми друг от друга. + /// Текущий экземпляр API. `thread_local`, потому что UI GPUI привязан к + /// потоку с event loop; заодно это делает тесты независимыми друг от друга. static INSTANCE: RefCell> = const { RefCell::new(None) }; + + /// Команды окна, ожидающие ближайшего кадра. + static WINDOW_COMMANDS: RefCell> = const { RefCell::new(VecDeque::new()) }; + + /// Развёрнуто ли окно. Вид обновляет значение в каждом кадре, чтобы + /// `app:is_maximized()` из Lua видел актуальное состояние. + static WINDOW_MAXIMIZED: Cell = const { Cell::new(false) }; +} + +/// Действие над окном, отложенное до ближайшего кадра. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum WindowCommand { + Close, + Minimize, + ToggleMaximize, + SetMaximized(bool), +} + +/// Запоминает, развёрнуто ли окно сейчас. +pub fn set_window_maximized(maximized: bool) { + WINDOW_MAXIMIZED.with(|state| state.set(maximized)); +} + +/// Забирает накопленные команды окна. +/// +/// Очередь очищается: выполнять команды нужно ровно один раз. +pub fn drain_window_commands() -> Vec { + WINDOW_COMMANDS.with(|queue| queue.borrow_mut().drain(..).collect()) +} + +/// Кладёт команду в очередь. +fn push_window_command(command: WindowCommand) { + WINDOW_COMMANDS.with(|queue| queue.borrow_mut().push_back(command)); } /// Краткая информация об открытой вкладке. @@ -31,8 +66,8 @@ pub struct TabInfo { /// Глобальный объект с функциями управления приложением. /// /// Использование: `AppApi::global().close()`, `AppApi::global().tabs()`. -/// Экземпляр устанавливается в начале каждого кадра (см. [`AppApi::install`]), -/// поэтому всегда указывает на актуальные `egui::Context` и состояние редактора. +/// Экземпляр устанавливается один раз при создании приложения (см. +/// [`AppApi::install`]) и указывает на общие с видом документы и карту клавиш. /// /// Методы этого `impl`-блока автоматически экспортируются в Lua через /// `#[mlua::userdata_impl]`: в сценариях они доступны как `app:method(...)`. @@ -40,28 +75,18 @@ pub struct TabInfo { #[derive(Clone, mlua::UserData)] pub struct AppApi { #[lua(skip)] - ctx: egui::Context, - #[lua(skip)] - editor: Rc>, + workspace: Rc>, #[lua(skip)] keymap: Rc>, } #[mlua::userdata_impl] impl AppApi { - /// Делает переданные контекст, состояние редактора и карту клавиш текущими - /// для [`AppApi::global`]. + /// Делает переданные документы и карту клавиш текущими для + /// [`AppApi::global`]. #[lua(skip)] - pub fn install( - ctx: egui::Context, - editor: Rc>, - keymap: Rc>, - ) -> Self { - let api = Self { - ctx, - editor, - keymap, - }; + pub fn install(workspace: Rc>, keymap: Rc>) -> Self { + let api = Self { workspace, keymap }; INSTANCE.with(|slot| *slot.borrow_mut() = Some(api.clone())); api } @@ -69,7 +94,7 @@ impl AppApi { /// Глобальный экземпляр API. /// /// # Panics - /// Если [`AppApi::install`] ещё не вызывался (ни одного кадра не отрисовано). + /// Если [`AppApi::install`] ещё не вызывался. #[lua(skip)] pub fn global() -> Self { INSTANCE.with(|slot| { @@ -79,18 +104,12 @@ impl AppApi { }) } - /// Контекст egui, к которому привязан API. - #[lua(skip)] - pub fn context(&self) -> &egui::Context { - &self.ctx - } - /// Все открытые вкладки в порядке слева направо. #[allow(dead_code)] // Часть публичного API приложения: вызывается внешним кодом и тестами. #[lua(infallible)] pub fn tabs(&self) -> Vec { - self.editor + self.workspace .borrow() .documents() .iter() @@ -107,7 +126,7 @@ impl AppApi { // Часть публичного API приложения: вызывается внешним кодом и тестами. #[lua(infallible, name = "active_tab")] pub fn active_tab_index(&self) -> usize { - self.editor.borrow().active_index() + self.workspace.borrow().active_index() } /// Переключает на следующую вкладку (по кругу) и возвращает её индекс. @@ -115,9 +134,9 @@ impl AppApi { // Часть публичного API приложения: вызывается внешним кодом и тестами. #[lua(infallible)] pub fn next_tab(&self) -> usize { - let mut editor = self.editor.borrow_mut(); - let next = (editor.active_index() + 1) % editor.documents().len(); - editor.set_active(next); + let mut workspace = self.workspace.borrow_mut(); + let next = (workspace.active_index() + 1) % workspace.documents().len(); + workspace.set_active(next); next } @@ -126,10 +145,10 @@ impl AppApi { // Часть публичного API приложения: вызывается внешним кодом и тестами. #[lua(infallible)] pub fn previous_tab(&self) -> usize { - let mut editor = self.editor.borrow_mut(); - let count = editor.documents().len(); - let previous = (editor.active_index() + count - 1) % count; - editor.set_active(previous); + let mut workspace = self.workspace.borrow_mut(); + let count = workspace.documents().len(); + let previous = (workspace.active_index() + count - 1) % count; + workspace.set_active(previous); previous } @@ -139,11 +158,11 @@ impl AppApi { /// последняя вкладка, вместо неё открывается пустой документ. #[lua(infallible)] pub fn close_tab(&self, index: usize) -> bool { - let mut editor = self.editor.borrow_mut(); - if index >= editor.documents().len() { + let mut workspace = self.workspace.borrow_mut(); + if index >= workspace.documents().len() { return false; } - editor.close(index); + workspace.close(index); true } @@ -153,10 +172,13 @@ impl AppApi { /// При успешной записи с вкладки снимается маркер несохранённых изменений. #[lua(skip)] pub fn save(&self) -> std::io::Result<()> { - let mut editor = self.editor.borrow_mut(); - let doc = editor.active_mut(); - std::fs::write(&doc.name, &doc.content)?; - doc.mark_saved(); + let (path, content) = { + let workspace = self.workspace.borrow(); + let doc = workspace.active(); + (doc.name.clone(), doc.content.clone()) + }; + std::fs::write(&path, content)?; + self.workspace.borrow_mut().mark_active_saved(); Ok(()) } @@ -176,8 +198,7 @@ impl AppApi { /// * `!a` — отпускание клавиши; /// * `` — отпускание клавиши при зажатом Alt. /// - /// Клавиша определяется по физическому коду, поэтому Caps Lock и раскладка - /// не важны. Повторное назначение той же клавиши заменяет обработчик. + /// Повторное назначение той же клавиши заменяет обработчик. /// /// # Errors /// Возвращает ошибку Lua, если запись привязки некорректна. @@ -190,13 +211,13 @@ impl AppApi { /// Содержимое активной вкладки. #[lua(infallible)] pub fn active_text(&self) -> String { - self.editor.borrow().active().content.clone() + self.workspace.borrow().active().content.clone() } /// Заменяет содержимое активной вкладки. #[lua(skip)] pub fn set_active_text(&self, text: impl Into) { - self.editor.borrow_mut().active_mut().content = text.into(); + self.workspace.borrow_mut().set_active_text(text); } /// Lua-версия [`AppApi::set_active_text`] (generic-методы не экспортируются). @@ -208,9 +229,9 @@ impl AppApi { /// Открывает новую пустую вкладку, делает её активной и возвращает её индекс. #[lua(infallible)] pub fn open_tab(&self) -> usize { - let mut editor = self.editor.borrow_mut(); - editor.open_new(); - editor.active_index() + let mut workspace = self.workspace.borrow_mut(); + workspace.open_new(); + workspace.active_index() } /// Делает вкладку активной по её номеру в списке [`AppApi::tabs`]. @@ -218,11 +239,11 @@ impl AppApi { /// Возвращает `false`, если вкладки с таким номером нет. #[lua(infallible)] pub fn set_active_tab(&self, index: usize) -> bool { - let mut editor = self.editor.borrow_mut(); - if index >= editor.documents().len() { + let mut workspace = self.workspace.borrow_mut(); + if index >= workspace.documents().len() { return false; } - editor.set_active(index); + workspace.set_active(index); true } @@ -238,12 +259,7 @@ impl AppApi { let Some(language) = Language::from_name(language) else { return false; }; - let mut editor = self.editor.borrow_mut(); - let Some(doc) = editor.document_mut(index) else { - return false; - }; - doc.language = Some(language); - true + self.workspace.borrow_mut().set_language(index, language) } /// Lua-версия [`AppApi::set_language`]. @@ -256,7 +272,7 @@ impl AppApi { /// или `nil`, если подсветка выключена / вкладки нет. #[lua(infallible)] pub fn language(&self, index: usize) -> Option { - self.editor + self.workspace .borrow() .document(index) .and_then(|doc| doc.language) @@ -268,43 +284,36 @@ impl AppApi { /// Возвращает `false`, если вкладки с таким номером нет. #[lua(infallible)] pub fn clear_language(&self, index: usize) -> bool { - let mut editor = self.editor.borrow_mut(); - let Some(doc) = editor.document_mut(index) else { - return false; - }; - doc.language = None; - true + self.workspace.borrow_mut().clear_language(index) } /// Закрывает окно приложения. #[lua(infallible)] pub fn close(&self) { - self.ctx.send_viewport_cmd(egui::ViewportCommand::Close); + push_window_command(WindowCommand::Close); } /// Разворачивает окно на весь экран или возвращает его прежний размер. #[lua(infallible)] pub fn toggle_maximize(&self) { - self.set_maximized(!self.is_maximized()); + push_window_command(WindowCommand::ToggleMaximize); } /// Разворачивает (`true`) или восстанавливает (`false`) окно. #[lua(infallible)] pub fn set_maximized(&self, maximized: bool) { - self.ctx - .send_viewport_cmd(egui::ViewportCommand::Maximized(maximized)); + push_window_command(WindowCommand::SetMaximized(maximized)); } /// Сворачивает окно. #[lua(infallible)] pub fn minimize(&self) { - self.ctx - .send_viewport_cmd(egui::ViewportCommand::Minimized(true)); + push_window_command(WindowCommand::Minimize); } /// Развёрнуто ли окно прямо сейчас. #[lua(infallible)] pub fn is_maximized(&self) -> bool { - self.ctx.input(|i| i.viewport().maximized.unwrap_or(false)) + WINDOW_MAXIMIZED.with(Cell::get) } } diff --git a/src/app.rs b/src/app.rs index f698994..07d711d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,175 +1,398 @@ -//! Приложение: окно без системных рамок и его содержимое. +//! Приложение: окно, вкладки и редактор кода. +//! +//! Вид [`MyApp`] — единственное место, где доменная модель [`Workspace`] +//! встречается с виджетами gpui-component. Текст вкладки живёт в модели, +//! а `Editor` показывает активный документ; синхронизация выполняется в +//! `render`, когда меняется [`Workspace::revision`]. use std::cell::RefCell; use std::rc::Rc; -use eframe::egui; +use gpui_kit::component::button::{Button, ButtonVariants}; +use gpui_kit::component::input::{Editor, EditorState, InputEvent, TabSize}; +use gpui_kit::component::tab::{Tab, TabBar}; +use gpui_kit::component::{ActiveTheme, IconName, Sizable, StyledExt, TitleBar, h_flex}; +use gpui_kit::*; -use crate::api::AppApi; -use crate::constants::CORNER_RADIUS; -use crate::editor::EditorState; +use crate::api::{self, AppApi, WindowCommand}; +use crate::constants::{TAB_SIZE, WINDOW_TITLE}; +use crate::editor::Workspace; use crate::keymap::KeyMap; use crate::script::ScriptEngine; -use crate::ui::title_bar::TitleBarResponses; -use crate::ui::{code_editor, resize_handles, tabs, title_bar}; -#[derive(Default)] +/// Приложение текстового редактора. pub struct MyApp { - /// Открытые документы, вкладки над редактором и активная вкладка. + /// Открытые документы, вкладки и активная вкладка. /// /// Состояние общее с [`AppApi`] (`Rc>`), чтобы им можно было - /// управлять через `AppApi::global()`. - editor: Rc>, + /// управлять через `AppApi::global()` и Lua. + workspace: Rc>, /// Привязки клавиш и их Lua-обработчики. /// /// Лежит перед `scripts`, чтобы обработчики (ссылки на Lua-значения) /// уничтожились раньше самого Lua-движка. keymap: Rc>, + /// Виджет редактора, показывающий активный документ. + editor: Entity, + /// Ревизия [`Workspace`], уже перенесённая в `editor`. + synced_revision: u64, + /// Идентификатор документа, который сейчас показан в редакторе. + /// + /// Нужен, чтобы отличить переключение вкладки от изменения её текста и + /// сохранить/восстановить курсор при переходе. + displayed_id: u64, + /// Курсор редактора ещё ни разу не получал фокус. + focused_once: bool, + /// Подписка на изменения редактора; держим её, пока жив вид. + _editor_subscription: Subscription, /// Движок Lua, созданный при старте. /// /// Хранится, чтобы глобальное окружение и загруженные модули жили, пока /// работает приложение. - #[allow(dead_code)] scripts: Option, } -impl eframe::App for MyApp { - /// Фон вне скруглённого окна должен быть полностью прозрачным, - /// иначе eframe зальёт его цветом по умолчанию и скругления не будет видно. - fn clear_color(&self, _visuals: &egui::Visuals) -> [f32; 4] { - egui::Color32::TRANSPARENT.to_normalized_gamma_f32() - } - - fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { - self.show(ui); - } -} - impl MyApp { - /// Создаёт приложение и сразу выполняет стартовый Lua-сценарий. + /// Создаёт приложение, но не выполняет стартовый сценарий. /// - /// Ошибки чтения/выполнения сценария печатаются в stderr и не мешают - /// запуску приложения: без `init.lua` редактор просто работает как обычно. - pub fn new(cc: &eframe::CreationContext<'_>) -> Self { - let mut app = Self::default(); + /// Такой конструктор удобен тестам: они не зависят от `init.lua` в + /// рабочем каталоге. Боевой запуск использует [`Self::with_startup_script`]. + pub fn new(window: &mut Window, cx: &mut Context) -> Self { + let workspace = Rc::new(RefCell::new(Workspace::default())); + let keymap = Rc::new(RefCell::new(KeyMap::default())); - // API доступен сценарию уже до первого кадра. - let api = AppApi::install(cc.egui_ctx.clone(), app.editor.clone(), app.keymap.clone()); - match ScriptEngine::new(api) { + let initial_text = workspace.borrow().active().content.clone(); + let editor = cx.new(|cx| { + EditorState::new(window, cx) + .line_number(true) + .folding(true) + .searchable(true) + .tab_size(TabSize { + tab_size: TAB_SIZE, + hard_tabs: false, + }) + .default_value(initial_text) + }); + + // Любая правка в виджете сразу попадает в модель. Ревизию при этом не + // трогаем: редактор уже показывает этот текст, и обратная + // синхронизация сбросила бы курсор после каждого символа. + let _editor_subscription = cx.subscribe_in( + &editor, + window, + |this, _editor, event: &InputEvent, _window, cx| { + if matches!(event, InputEvent::Change) { + let text = this.editor.read(cx).value().to_string(); + let mut workspace = this.workspace.borrow_mut(); + let was_dirty = workspace.active().is_dirty(); + workspace.replace_active_content(text); + // Индикатор на вкладке меняется только при переходе + // «чисто → грязно» (или обратно после отмены правки). + if was_dirty != workspace.active().is_dirty() { + drop(workspace); + cx.notify(); + } + } + }, + ); + + let displayed_id = workspace.borrow().active().id; + AppApi::install(workspace.clone(), keymap.clone()); + + Self { + workspace, + keymap, + editor, + synced_revision: 0, + displayed_id, + focused_once: false, + _editor_subscription, + scripts: None, + } + } + + /// Выполняет `init.lua` из каталога сценариев. + /// + /// Ошибки печатаются в stderr и не мешают запуску: без `init.lua` + /// редактор работает как обычно. + pub fn with_startup_script(mut self) -> Self { + match ScriptEngine::new(AppApi::global()) { Ok(engine) => { if let Err(err) = engine.run_startup() { eprintln!("Lua: {err}"); } - app.scripts = Some(engine); + self.scripts = Some(engine); } Err(err) => eprintln!("Lua: не удалось создать движок: {err}"), } - - app + self } - /// Состояние редактора (доступ для тестов). + /// Общие документы (доступ для тестов). #[cfg(test)] - pub fn editor(&self) -> std::cell::Ref<'_, EditorState> { - self.editor.borrow() + pub fn workspace_handle(&self) -> Rc> { + self.workspace.clone() } - /// Всё содержимое окна. Вынесено из `eframe::App::ui`, чтобы можно было - /// вернуть наружу `Response`-ы заголовка (пригодится для проверок/тестов). - pub fn show(&mut self, ui: &mut egui::Ui) -> TitleBarResponses { - let ctx = ui.ctx().clone(); - - // Публикуем глобальный API на текущий кадр: дальше любой модуль может - // управлять приложением и редактором через `AppApi::global()`. - AppApi::install(ctx.clone(), self.editor.clone(), self.keymap.clone()); - - // Обработчики клавиш вызываем до отрисовки, чтобы изменения состояния - // успели попасть в текущий кадр. - self.dispatch_keys(&ctx); - - // Базовый фрейм для всего окна приложения со скруглением - let style = ui.style().clone(); - let panel_frame = egui::Frame::new() - .fill(style.visuals.window_fill()) // Фон из текущей темы - .corner_radius(egui::CornerRadius::same(CORNER_RADIUS)) // Скругление углов самого окна - .stroke(egui::Stroke::new( - 1.0, - style.visuals.widgets.noninteractive.bg_stroke.color, - )) - .inner_margin(0.0) // Чтобы заголовок плотно прижимался к краям - .outer_margin(0.0); - - let mut bar = None; - - egui::CentralPanel::default() - .frame(panel_frame) - .show(ui, |ui| { - // 1. Отрисовка интегрированного заголовка (Title Bar) - // с именем активного документа, как в обычном редакторе. - let title = self.editor.borrow().active().name.clone(); - bar = Some(title_bar::render(ui, &title)); - - // 2. Вкладки и редактор занимают всю оставшуюся площадь - self.show_workspace(ui); - }); - - // Контент прилегает к краям панели, поэтому рамку окна рисуем поверх него. - ui.painter().rect_stroke( - ctx.content_rect(), - egui::CornerRadius::same(CORNER_RADIUS), - egui::Stroke::new(1.0, style.visuals.widgets.noninteractive.bg_stroke.color), - egui::StrokeKind::Inside, - ); - - // 3. Невидимые зоны изменения размера по краям (после контента — значит, поверх него). - resize_handles::render(ui); - - bar.expect("CentralPanel всегда отрисовывает заголовок") + /// Редактор активной вкладки (доступ для тестов). + #[cfg(test)] + pub fn editor_handle(&self) -> Entity { + self.editor.clone() } - /// Вызывает Lua-обработчики, совпавшие с событиями клавиатуры этого кадра. - fn dispatch_keys(&self, ctx: &egui::Context) { - // Заём карты заканчивается до вызова колбэков: обработчик может сам - // вызвать `app:map_key` и изменить привязки. - let callbacks = self.keymap.borrow().callbacks_for(ctx); - for callback in callbacks { - if let Err(err) = callback.call::<()>(()) { - eprintln!("Lua: ошибка в обработчике клавиши: {err}"); + /// Переносит изменения модели в виджет редактора. + /// + /// `set_value` сбрасывает выделение и прокрутку, поэтому вызывается только + /// когда текст действительно изменился извне (смена вкладки, Lua, `+`/`×`). + fn sync_editor(&mut self, window: &mut Window, cx: &mut Context) { + let revision = self.workspace.borrow().revision(); + if revision == self.synced_revision { + return; + } + self.synced_revision = revision; + + let (active_id, content, language, cursor) = { + let workspace = self.workspace.borrow(); + let doc = workspace.active(); + (doc.id, doc.content.clone(), doc.language, doc.cursor) + }; + + let switching = active_id != self.displayed_id; + if switching { + // Запоминаем курсор покидаемой вкладки до того, как индекс + // документа перестанет быть актуальным. + let cursor = self.editor.read(cx).cursor(); + if let Some(doc) = self + .workspace + .borrow_mut() + .document_mut_by_id(self.displayed_id) + { + doc.cursor = cursor; + } + } + self.displayed_id = active_id; + + let highlight = language + .map(|language| language.highlight_name()) + .unwrap_or(""); + self.editor.update(cx, |state, cx| { + if state.value().as_ref() != content.as_str() { + state.set_value(content, window, cx); + } + if state.language_name().as_ref() != highlight { + state.set_highlighter(highlight, cx); + } + if switching { + let cursor = cursor.min(state.value().len()); + state.set_selected_range(cursor..cursor, cx); + } + state.focus(window, cx); + }); + } + + /// Полоса вкладок: активная вкладка, маркер несохранённых изменений и «+». + fn render_tabs(&self, cx: &mut Context) -> impl IntoElement { + let (tabs, active) = { + let workspace = self.workspace.borrow(); + ( + workspace + .documents() + .iter() + .map(|doc| (doc.name.clone(), doc.is_dirty())) + .collect::>(), + workspace.active_index(), + ) + }; + + let entity = cx.entity(); + let mut bar = TabBar::new("tabs").selected_index(active); + + for (index, (name, dirty)) in tabs.into_iter().enumerate() { + // У несохранённого документа вместо крестика горит точка — как в + // исходном приложении. + let suffix: AnyElement = if dirty { + div() + .size(px(6.)) + .rounded_full() + .bg(cx.theme().primary) + .into_any_element() + } else { + let entity = entity.clone(); + Button::new(format!("close-tab-{index}")) + .xsmall() + .ghost() + .icon(IconName::Close) + .tooltip("Закрыть вкладку") + .on_click(move |_, _, cx| { + // Иначе клик закроет вкладку и тут же переключит на неё + // соседнюю по уже устаревшему индексу. + cx.stop_propagation(); + entity.update(cx, |this, cx| { + this.workspace.borrow_mut().close(index); + cx.notify(); + }); + }) + .into_any_element() + }; + + bar = bar.child(Tab::new().label(name).suffix(suffix)); + } + + bar.suffix( + Button::new("new-tab") + .xsmall() + .ghost() + .icon(IconName::Plus) + .tooltip("Новая вкладка") + .on_click({ + let entity = entity.clone(); + move |_, _, cx| { + entity.update(cx, |this, cx| { + this.workspace.borrow_mut().open_new(); + cx.notify(); + }); + } + }), + ) + .on_click({ + let entity = entity.clone(); + move |index, _, cx| { + entity.update(cx, |this, cx| { + this.workspace.borrow_mut().set_active(*index); + cx.notify(); + }); + } + }) + } +} + +impl Render for MyApp { + fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { + // Состояние окна нужно `app:is_maximized()` из Lua. + api::set_window_maximized(window.is_maximized()); + // Команды могли накопиться в Lua-обработчике или в стартовом сценарии. + apply_window_commands(window); + + self.sync_editor(window, cx); + if !self.focused_once { + self.focused_once = true; + self.editor.update(cx, |state, cx| state.focus(window, cx)); + } + + let title = { + let workspace = self.workspace.borrow(); + format!("{} — {WINDOW_TITLE}", workspace.active().name) + }; + + let keymap = self.keymap.clone(); + let entity = cx.entity(); + + div() + .id("app-root") + .size_full() + .flex() + .flex_col() + .bg(cx.theme().background) + .text_color(cx.theme().foreground) + .on_key_down({ + let keymap = keymap.clone(); + let entity = entity.clone(); + move |event, window, cx| { + let mut handled = false; + if is_save_shortcut(&event.keystroke) { + save_active_tab(); + handled = true; + } + handled |= dispatch_keymap(&keymap, &event.keystroke, true); + // Обработчик мог поставить команду окна или изменить документы. + apply_window_commands(window); + if handled { + entity.update(cx, |_, cx| cx.notify()); + } + } + }) + .on_key_up({ + let keymap = keymap.clone(); + let entity = entity.clone(); + move |event, window, cx| { + let handled = dispatch_keymap(&keymap, &event.keystroke, false); + apply_window_commands(window); + if handled { + entity.update(cx, |_, cx| cx.notify()); + } + } + }) + .child( + TitleBar::new().child( + h_flex() + .w_full() + .pr_2() + .justify_between() + .child(div().text_sm().font_medium().child(title)) + .child( + div() + .text_xs() + .text_color(cx.theme().muted_foreground) + .child("gpui-kit · tree-sitter"), + ), + ), + ) + .child(self.render_tabs(cx)) + .child( + div() + .flex_1() + .w_full() + .min_h_0() + .child(Editor::new(&self.editor).bordered(false).size_full()), + ) + } +} + +/// Выполняет накопленные команды окна. +fn apply_window_commands(window: &mut Window) { + for command in api::drain_window_commands() { + match command { + WindowCommand::Close => { + window.remove_window(); + return; + } + WindowCommand::Minimize => window.minimize_window(), + WindowCommand::ToggleMaximize => window.zoom_window(), + WindowCommand::SetMaximized(maximized) => { + if window.is_maximized() != maximized { + window.zoom_window(); + } } } } +} - /// Полоса вкладок и редактор активного документа. - fn show_workspace(&mut self, ui: &mut egui::Ui) { - let mut focus_editor = false; +/// Ctrl+S (Cmd+S на macOS) сохраняет активную вкладку. +fn is_save_shortcut(keystroke: &Keystroke) -> bool { + keystroke.key.eq_ignore_ascii_case("s") + && (keystroke.modifiers.control || keystroke.modifiers.platform) + && !keystroke.modifiers.alt +} - // Ctrl+S пишет активную вкладку в файл с её названием. - if ui.input_mut(|input| input.consume_key(egui::Modifiers::COMMAND, egui::Key::S)) - && let Err(err) = AppApi::global().save() - { - eprintln!("Не удалось сохранить вкладку: {err}"); - } - - // Заём держим только на время отрисовки, чтобы действия из API - // (они берут тот же `RefCell`) не конфликтовали с ним. - let actions = { - let editor = self.editor.borrow(); - tabs::render(ui, editor.documents(), editor.active_index()) - }; - - if let Some(index) = actions.clicked_tab { - self.editor.borrow_mut().set_active(index); - focus_editor = true; - } - if let Some(index) = actions.closed_tab { - AppApi::global().close_tab(index); - } - if actions.add_clicked { - self.editor.borrow_mut().open_new(); - focus_editor = true; - } - - let mut editor = self.editor.borrow_mut(); - code_editor::render(ui, editor.active_mut(), focus_editor); +/// Сохраняет активную вкладку, печатая ошибку в stderr. +fn save_active_tab() { + if let Err(err) = AppApi::global().save() { + eprintln!("Не удалось сохранить вкладку: {err}"); } } + +/// Вызывает Lua-обработчики, совпавшие с событием клавиатуры. +/// +/// Возвращает `true`, если хотя бы один обработчик вызван. Заём карты +/// заканчивается до вызова колбэков: обработчик может сам вызвать +/// `app:map_key` и изменить привязки. +fn dispatch_keymap(keymap: &Rc>, keystroke: &Keystroke, pressed: bool) -> bool { + let callbacks = keymap.borrow().callbacks_for(keystroke, pressed); + let handled = !callbacks.is_empty(); + for callback in callbacks { + if let Err(err) = callback.call::<()>(()) { + eprintln!("Lua: ошибка в обработчике клавиши: {err}"); + } + } + handled +} diff --git a/src/constants.rs b/src/constants.rs index d87a5a7..61df23e 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,16 +1,22 @@ -//! Константы оформления окна. +//! Константы оформления окна и сценариев. -/// Насколько сильно скругляются углы окна. -pub const CORNER_RADIUS: u8 = 12; +/// Ширина окна при запуске. +pub const WINDOW_WIDTH: f32 = 900.0; -/// Высота интегрированного заголовка. -pub const TITLE_BAR_HEIGHT: f32 = 32.0; +/// Высота окна при запуске. +pub const WINDOW_HEIGHT: f32 = 600.0; -/// Толщина невидимой зоны по краям окна, за которую можно менять размер. -pub const RESIZE_BORDER: f32 = 6.0; +/// Минимальная ширина окна. +pub const MIN_WINDOW_WIDTH: f32 = 420.0; -/// Высота полосы вкладок над редактором. -pub const TAB_BAR_HEIGHT: f32 = 34.0; +/// Минимальная высота окна. +pub const MIN_WINDOW_HEIGHT: f32 = 280.0; + +/// Подпись окна в панели задач и в заголовке. +pub const WINDOW_TITLE: &str = "Custom Window App"; + +/// Ширина одного уровня отступа в редакторе. +pub const TAB_SIZE: usize = 4; /// Каталог, в котором приложение ищет Lua-сценарии. /// diff --git a/src/editor.rs b/src/editor.rs index d43669e..40eb3cf 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -1,18 +1,88 @@ //! Документы редактора и состояние вкладок. +//! +//! Это доменная модель приложения: текст, имена и языки вкладок живут здесь, +//! а виджет `Editor` из gpui-component показывает активный документ. Такое +//! разделение позволяет Lua-сценариям менять документы без доступа к `Window` +//! и `App`: вид обновляет редактор, когда меняется [`Workspace::revision`]. use std::sync::atomic::{AtomicU64, Ordering}; -use crate::syntax::{Language, SyntaxState}; - /// Счётчик идентификаторов документов. static NEXT_ID: AtomicU64 = AtomicU64::new(1); +/// Языки, для которых в редакторе включена подсветка tree-sitter. +/// +/// Названия намеренно короткие (`js`, а не `javascript`): именно их возвращает +/// [`Language::name`] и показывает Lua-API. gpui-component принимает такие +/// псевдонимы и сам приводит их к имени грамматики. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Language { + Rust, + Go, + JavaScript, + Json, + Python, +} + +impl Language { + /// Все поддерживаемые языки. + #[allow(dead_code)] + // Часть публичного интерфейса модуля: удобно для перебора языков снаружи. + pub const ALL: [Self; 5] = [ + Self::Rust, + Self::Go, + Self::JavaScript, + Self::Json, + Self::Python, + ]; + + /// Разбирает название языка из API/сценария. + /// + /// Основные имена — `rust`, `go`, `js`, `json`, `python`; короткие + /// (`rs`, `golang`, `javascript`, `py`) и регистр тоже принимаются. + pub fn from_name(name: &str) -> Option { + match name.trim().to_ascii_lowercase().as_str() { + "rust" | "rs" => Some(Self::Rust), + "go" | "golang" => Some(Self::Go), + "js" | "javascript" | "node" => Some(Self::JavaScript), + "json" => Some(Self::Json), + "python" | "py" => Some(Self::Python), + _ => None, + } + } + + /// Каноническое имя языка (то, что возвращает `AppApi::language`). + pub fn name(self) -> &'static str { + match self { + Self::Rust => "rust", + Self::Go => "go", + Self::JavaScript => "js", + Self::Json => "json", + Self::Python => "python", + } + } + + /// Имя языка для `EditorState::set_highlighter`. + /// + /// Здесь `js` разворачивается в `javascript`: так грамматика находится + /// без дополнительных псевдонимов на нашей стороне. + pub fn highlight_name(self) -> &'static str { + match self { + Self::Rust => "rust", + Self::Go => "go", + Self::JavaScript => "javascript", + Self::Json => "json", + Self::Python => "python", + } + } +} + /// Открытый в редакторе документ. pub struct Document { /// Стабильный идентификатор, пока документ открыт. /// - /// По нему `TextEdit` и `ScrollArea` хранят курсор, выделение и прокрутку, - /// поэтому переключение вкладок не сбрасывает состояние редактора. + /// По нему вид отличает «ту же вкладку» от «другой вкладки с тем же + /// индексом» после закрытия соседей. pub id: u64, pub name: String, pub content: String, @@ -21,8 +91,8 @@ pub struct Document { /// `None` — подсветка выключена (поведение по умолчанию). Включается /// только явно через `AppApi::set_language`, например из Lua-сценария. pub language: Option, - /// Разбор tree-sitter и кэш подсветки для этого документа. - pub syntax: SyntaxState, + /// Позиция курсора в байтах на момент ухода с вкладки. + pub cursor: usize, /// Содержимое на момент последнего «сохранения». saved_content: String, } @@ -36,7 +106,7 @@ impl Document { saved_content: content.clone(), content, language: None, - syntax: SyntaxState::default(), + cursor: 0, } } @@ -55,13 +125,19 @@ impl Document { /// /// Инвариант: `documents` никогда не пуст — редактор всегда показывает хотя бы /// один документ. Это позволяет `active`/`active_mut` не возвращать `Option`. -pub struct EditorState { +pub struct Workspace { documents: Vec, active: usize, next_untitled: u32, + /// Номер «поколения» состояния. + /// + /// Вид перечитывает активный документ в редактор только когда ревизия + /// изменилась. Набор текста сам обновляет документ и ревизию не трогает, + /// иначе редактор переставлял бы курсор после каждого символа. + revision: u64, } -impl Default for EditorState { +impl Default for Workspace { fn default() -> Self { Self { documents: vec![ @@ -70,11 +146,12 @@ impl Default for EditorState { ], active: 0, next_untitled: 0, + revision: 0, } } } -impl EditorState { +impl Workspace { pub fn documents(&self) -> &[Document] { &self.documents } @@ -96,15 +173,26 @@ impl EditorState { self.documents.get(index) } - /// Изменяемый документ по номеру вкладки (для API). - pub fn document_mut(&mut self, index: usize) -> Option<&mut Document> { - self.documents.get_mut(index) + /// Изменяемый документ по стабильному идентификатору. + pub fn document_mut_by_id(&mut self, id: u64) -> Option<&mut Document> { + self.documents.iter_mut().find(|doc| doc.id == id) + } + + /// Текущая ревизия состояния. + pub fn revision(&self) -> u64 { + self.revision + } + + /// Сообщает виду, что документы нужно перечитать. + fn bump(&mut self) { + self.revision = self.revision.wrapping_add(1); } /// Делает вкладку активной, если индекс существует. pub fn set_active(&mut self, index: usize) { - if index < self.documents.len() { + if index < self.documents.len() && index != self.active { self.active = index; + self.bump(); } } @@ -116,6 +204,7 @@ impl EditorState { "", )); self.active = self.documents.len() - 1; + self.bump(); } /// Закрывает вкладку и выбирает соседнюю. @@ -135,6 +224,53 @@ impl EditorState { } else if index == self.active { self.active = self.active.min(self.documents.len() - 1); } + self.bump(); + } + + /// Обновляет текст активного документа без изменения ревизии. + /// + /// Используется видом после ввода в редакторе: сам виджет уже показывает + /// этот текст, поэтому повторная синхронизация только сбросила бы курсор. + pub fn replace_active_content(&mut self, content: String) { + self.active_mut().content = content; + } + + /// Заменяет текст активной вкладки извне (Lua, меню, тесты). + pub fn set_active_text(&mut self, text: impl Into) { + self.active_mut().content = text.into(); + self.bump(); + } + + /// Включает подсветку для вкладки; возвращает `false`, если вкладки нет. + pub fn set_language(&mut self, index: usize, language: Language) -> bool { + let Some(doc) = self.documents.get_mut(index) else { + return false; + }; + if doc.language != Some(language) { + doc.language = Some(language); + self.bump(); + } + true + } + + /// Выключает подсветку для вкладки; возвращает `false`, если вкладки нет. + pub fn clear_language(&mut self, index: usize) -> bool { + let Some(doc) = self.documents.get_mut(index) else { + return false; + }; + if doc.language.take().is_some() { + self.bump(); + } + true + } + + /// Помечает активный документ сохранённым. + /// + /// Ревизия меняется, чтобы индикатор несохранённых изменений на вкладке + /// перерисовался даже без отдельного уведомления вида. + pub fn mark_active_saved(&mut self) { + self.active_mut().mark_saved(); + self.bump(); } } diff --git a/src/keymap.rs b/src/keymap.rs index 80cab0b..186e837 100644 --- a/src/keymap.rs +++ b/src/keymap.rs @@ -7,10 +7,21 @@ //! * `!a` — отпускание клавиши; //! * `` — отпускание клавиши при зажатом Alt. //! -//! Клавиша всегда определяется по физическому коду (`physical_key`), поэтому -//! Caps Lock и текущая раскладка клавиатуры на совпадение не влияют. +//! Клавиша сравнивается с `Keystroke.key` из GPUI. Это не результат ввода, а +//! имя клавиши, которое платформа уже нормализует: +//! +//! * Caps Lock не превращает `a` в `A`; +//! * на Linux и Windows буквы берутся по аппаратному keycode, поэтому на +//! русской раскладке физическая `q` всё равно приходит как `"q"`, а +//! напечатанная `й` — только в `key_char`; +//! * на macOS GPUI отдаёт символ раскладки, поэтому там привязки следуют +//! раскладке (ограничение самого GPUI, не этого модуля). +//! +//! Отдельного поля с физическим кодом в публичном `Keystroke`/`KeyDownEvent` +//! у gpui-kit 0.8.1 нет, но для Linux/Windows он и не нужен: ASCII-имя клавиши +//! уже восстановлено по keycode. -use eframe::egui; +use gpui_kit::Keystroke; /// Модификаторы, которые учитываются при совпадении привязки. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] @@ -23,16 +34,23 @@ pub struct Modifiers { impl Modifiers { /// Все три модификатора должны совпасть точно: `` не сработает, /// если вместе с Ctrl зажат ещё и Shift. - fn matches(self, pressed: &egui::Modifiers) -> bool { - self.shift == pressed.shift && self.ctrl == pressed.ctrl && self.alt == pressed.alt + /// + /// `platform` (Cmd/Super) и `function` в записи привязки не выражаются, + /// поэтому события с ними не совпадают ни с одной привязкой. + fn matches(self, pressed: &gpui_kit::Modifiers) -> bool { + self.shift == pressed.shift + && self.ctrl == pressed.control + && self.alt == pressed.alt + && !pressed.platform + && !pressed.function } } /// Разобранная привязка клавиши. #[derive(Clone, Debug, PartialEq, Eq)] pub struct KeyBinding { - /// Физическая клавиша (не зависит от раскладки и Caps Lock). - pub key: egui::Key, + /// Каноническое имя клавиши в нижнем регистре (`a`, `1`, `pageup`, `f5`). + pub key: String, pub modifiers: Modifiers, /// `true` — обработчик вызывается при отпускании клавиши. pub on_release: bool, @@ -95,9 +113,25 @@ impl KeyBinding { }) } - /// Совпадает ли привязка с конкретным событием клавиатуры. - fn matches(&self, key: egui::Key, pressed: bool, modifiers: &egui::Modifiers) -> bool { - self.key == key && self.on_release == !pressed && self.modifiers.matches(modifiers) + /// Совпадает ли привязка с событием клавиатуры. + /// + /// `pressed` — `true` для нажатия и `false` для отпускания. + pub fn matches(&self, keystroke: &Keystroke, pressed: bool) -> bool { + self.on_release == !pressed + && self.modifiers.matches(&keystroke.modifiers) + && self.key_matches(keystroke) + } + + /// Клавиша события совпадает с привязкой. + /// + /// Помимо `key` проверяется `key_char`: на части раскладок GPUI кладёт + /// в `key` не-ASCII символ, а печатаемый символ — в `key_char`. + fn key_matches(&self, keystroke: &Keystroke) -> bool { + canonical_key(&keystroke.key) == self.key + || keystroke + .key_char + .as_deref() + .is_some_and(|key_char| canonical_key(key_char) == self.key) } } @@ -109,52 +143,67 @@ fn split_release(token: &str) -> (bool, &str) { } } -/// Превращает имя клавиши из привязки в [`egui::Key`]. -fn parse_key(token: &str) -> Result { +/// Приводит имя клавиши из привязки к каноническому виду. +fn parse_key(token: &str) -> Result { let token = token.trim(); if token.is_empty() { return Err("не указана клавиша".to_owned()); } - // Односимвольные клавиши (`a`, `1`, `-`) и точные имена (`F1`, `Space`). - if let Some(key) = egui::Key::from_name(token) { - return Ok(key); + match canonical_key(token).as_str() { + // Одиночный символ уже канонизирован (`A` → `a`). + canonical if canonical.chars().count() == 1 => Ok(canonical.to_owned()), + canonical if canonical.starts_with('f') && canonical[1..].parse::().is_ok() => { + Ok(canonical.to_owned()) + } + canonical + if matches!( + canonical, + "space" + | "tab" + | "enter" + | "escape" + | "backspace" + | "delete" + | "insert" + | "home" + | "end" + | "pageup" + | "pagedown" + | "up" + | "down" + | "left" + | "right" + ) => + { + Ok(canonical.to_owned()) + } + _ => Err(format!("неизвестная клавиша: {token}")), } - - // Регистронезависимые имена: `space`, `enter`, `esc`, `pgup` и т. п. - if let Some(key) = alias_key(token) { - return Ok(key); - } - - // `f1` → `F1`. - if let Some(key) = egui::Key::from_name(&token.to_ascii_uppercase()) { - return Ok(key); - } - - Err(format!("неизвестная клавиша: {token}")) } -/// Имена клавиш в нижнем регистре, которых нет в [`egui::Key::from_name`]. -fn alias_key(token: &str) -> Option { - let name = match token.to_ascii_lowercase().as_str() { - "space" => "Space", - "tab" => "Tab", - "enter" | "return" | "cr" => "Enter", - "esc" | "escape" => "Escape", - "backspace" | "bs" => "Backspace", - "delete" | "del" => "Delete", - "insert" => "Insert", - "home" => "Home", - "end" => "End", - "pageup" | "pgup" => "PageUp", - "pagedown" | "pgdn" => "PageDown", - "up" | "arrowup" => "ArrowUp", - "down" | "arrowdown" => "ArrowDown", - "left" | "arrowleft" => "ArrowLeft", - "right" | "arrowright" => "ArrowRight", - _ => return None, - }; - egui::Key::from_name(name) +/// Каноническое имя клавиши: нижний регистр, псевдонимы приведены к одному виду. +/// +/// Функция используется и при разборе записи привязки, и при сравнении с +/// событием GPUI, поэтому обе стороны всегда говорят на одном языке. +fn canonical_key(key: &str) -> String { + let lower = key.trim().to_lowercase(); + match lower.as_str() { + " " => return "space".to_owned(), + "return" | "cr" => return "enter".to_owned(), + "esc" => return "escape".to_owned(), + "bs" => return "backspace".to_owned(), + "del" => return "delete".to_owned(), + "ins" => return "insert".to_owned(), + "pgup" | "page_up" => return "pageup".to_owned(), + "pgdn" | "page_down" => return "pagedown".to_owned(), + "arrowup" => return "up".to_owned(), + "arrowdown" => return "down".to_owned(), + "arrowleft" => return "left".to_owned(), + "arrowright" => return "right".to_owned(), + _ => {} + } + lower } /// Привязка вместе с Lua-функцией, которую нужно выполнить. @@ -184,46 +233,17 @@ impl KeyMap { } } - /// Собирает обработчики, которые нужно вызвать для событий текущего кадра. + /// Собирает обработчики, которые нужно вызвать для одного события. /// /// Заём `KeyMap` здесь заканчивается: вызывать колбэки нужно уже после /// возврата из метода, потому что обработчик может сам менять привязки /// через `app:map_key`. - pub fn callbacks_for(&self, ctx: &egui::Context) -> Vec { - let key_events: Vec<(egui::Key, bool, egui::Modifiers)> = ctx.input(|input| { - input - .events - .iter() - .filter_map(|event| { - let egui::Event::Key { - key, - physical_key, - pressed, - modifiers, - .. - } = event - else { - return None; - }; - - // Физический код не зависит от раскладки и Caps Lock. - // Логическая клавиша — запасной вариант для платформ, - // где physical_key не заполняется. - Some((physical_key.unwrap_or(*key), *pressed, *modifiers)) - }) - .collect() - }); - - let mut callbacks = Vec::new(); - for (key, pressed, modifiers) in key_events { - for binding in &self.bindings { - if binding.binding.matches(key, pressed, &modifiers) { - callbacks.push(binding.callback.clone()); - } - } - } - - callbacks + pub fn callbacks_for(&self, keystroke: &Keystroke, pressed: bool) -> Vec { + self.bindings + .iter() + .filter(|binding| binding.binding.matches(keystroke, pressed)) + .map(|binding| binding.callback.clone()) + .collect() } } @@ -231,6 +251,15 @@ impl KeyMap { mod tests { use super::*; + /// Событие без символа ввода: для проверки совпадения этого достаточно. + fn stroke(key: &str, modifiers: gpui_kit::Modifiers) -> Keystroke { + Keystroke { + modifiers, + key: key.to_owned(), + key_char: None, + } + } + fn parse(spec: &str) -> KeyBinding { KeyBinding::parse(spec).expect("привязка должна разбираться") } @@ -240,7 +269,7 @@ mod tests { assert_eq!( parse("a"), KeyBinding { - key: egui::Key::A, + key: "a".to_owned(), modifiers: Modifiers::default(), on_release: false, } @@ -248,7 +277,7 @@ mod tests { assert_eq!( parse("1"), KeyBinding { - key: egui::Key::Num1, + key: "1".to_owned(), modifiers: Modifiers::default(), on_release: false, } @@ -256,7 +285,7 @@ mod tests { assert_eq!( parse("!a"), KeyBinding { - key: egui::Key::A, + key: "a".to_owned(), modifiers: Modifiers::default(), on_release: true, } @@ -268,7 +297,7 @@ mod tests { assert_eq!( parse(""), KeyBinding { - key: egui::Key::C, + key: "c".to_owned(), modifiers: Modifiers { shift: true, ..Default::default() @@ -279,7 +308,7 @@ mod tests { assert_eq!( parse(""), KeyBinding { - key: egui::Key::Z, + key: "z".to_owned(), modifiers: Modifiers { ctrl: true, ..Default::default() @@ -290,7 +319,7 @@ mod tests { assert_eq!( parse(""), KeyBinding { - key: egui::Key::R, + key: "r".to_owned(), modifiers: Modifiers { alt: true, ..Default::default() @@ -301,7 +330,7 @@ mod tests { assert_eq!( parse(""), KeyBinding { - key: egui::Key::X, + key: "x".to_owned(), modifiers: Modifiers { shift: true, ctrl: true, @@ -314,7 +343,7 @@ mod tests { #[test] fn invalid_bindings_are_rejected() { - for spec in ["", " ", "<", "", "!"] { + for spec in ["", " ", "<", "", "!", ""] { assert!( KeyBinding::parse(spec).is_err(), "строка {spec:?} должна быть отклонена" @@ -324,29 +353,90 @@ mod tests { #[test] fn named_keys_are_case_insensitive() { - assert_eq!(parse("").key, egui::Key::Space); - assert_eq!(parse("").key, egui::Key::Enter); - assert_eq!(parse("").key, egui::Key::Escape); - assert_eq!(parse("").key, egui::Key::F1); - assert_eq!(parse("").key, egui::Key::PageDown); + assert_eq!(parse("").key, "space"); + assert_eq!(parse("").key, "enter"); + assert_eq!(parse("").key, "escape"); + assert_eq!(parse("").key, "f1"); + assert_eq!(parse("").key, "pagedown"); + assert_eq!(parse("").key, "f5"); } #[test] fn matching_requires_exact_modifiers() { let binding = parse(""); - let shift = egui::Modifiers { + let shift = gpui_kit::Modifiers { shift: true, ..Default::default() }; - let shift_ctrl = egui::Modifiers { + let shift_ctrl = gpui_kit::Modifiers { shift: true, - ctrl: true, + control: true, ..Default::default() }; - assert!(binding.matches(egui::Key::C, true, &shift)); - assert!(!binding.matches(egui::Key::C, true, &shift_ctrl)); - assert!(!binding.matches(egui::Key::C, false, &shift)); - assert!(!binding.matches(egui::Key::V, true, &shift)); + assert!(binding.matches(&stroke("c", shift), true)); + assert!(!binding.matches(&stroke("c", shift_ctrl), true)); + assert!(!binding.matches(&stroke("c", shift), false)); + assert!(!binding.matches(&stroke("v", shift), true)); + } + + #[test] + fn caps_lock_and_key_char_do_not_break_plain_keys() { + let binding = parse("a"); + + // Caps Lock: GPUI сообщает напечатанный символ `A`, привязка — `a`. + assert!(binding.matches(&stroke("A", gpui_kit::Modifiers::default()), true)); + + // Символ, который напечатала бы клавиша, может отличаться от имени + // клавиши (композиция, Option на macOS): GPUI кладёт его в key_char. + let mut event = stroke("x", gpui_kit::Modifiers::default()); + event.key_char = Some("a".to_owned()); + assert!(binding.matches(&event, true)); + + // А вот Shift+A — уже другое событие. + let shift = gpui_kit::Modifiers { + shift: true, + ..Default::default() + }; + assert!(!binding.matches(&stroke("a", shift), true)); + } + + #[test] + fn cyrillic_layout_uses_the_key_name_gpui_reports() { + let binding = parse(""); + let ctrl = gpui_kit::Modifiers { + control: true, + ..Default::default() + }; + + // Linux/Windows: GPUI восстанавливает ASCII-клавишу по аппаратному + // keycode, поэтому при русской раскладке key уже "q", а напечатанная + // "й" лежит только в key_char. Таблица соответствий не нужна. + let mut event = stroke("q", ctrl); + event.key_char = Some("й".to_owned()); + assert!(binding.matches(&event, true)); + + // Соседняя физическая клавиша по-прежнему не подходит. + event.key = "w".to_owned(); + event.key_char = Some("ц".to_owned()); + assert!(!binding.matches(&event, true)); + } + + #[test] + fn release_bindings_match_only_key_up() { + let binding = parse(""); + let plain = gpui_kit::Modifiers::default(); + assert!(!binding.matches(&stroke("a", plain), true)); + assert!(binding.matches(&stroke("a", plain), false)); + + // Alt зажат: обычная привязка отпускания больше не совпадает. + let alt = gpui_kit::Modifiers { + alt: true, + ..Default::default() + }; + assert!(!binding.matches(&stroke("a", alt), false)); + + // А привязка вида `` — совпадает. + assert!(parse("").matches(&stroke("a", alt), false)); } } diff --git a/src/main.rs b/src/main.rs index 9bfb84b..ff42312 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,55 @@ +//! Точка входа приложения. +//! +//! Окно создаётся средствами GPUI (gpui-kit). Заголовок рисует компонент +//! `TitleBar`: он же отвечает за перетаскивание окна, двойной клик и кнопки +//! свернуть/развернуть/закрыть, поэтому отдельные зоны изменения размера +//! больше не нужны. + mod api; mod app; mod constants; mod editor; mod keymap; mod script; -mod syntax; -mod ui; #[cfg(test)] mod tests; +use gpui_kit::component::TitleBar; +use gpui_kit::*; + use app::MyApp; -use eframe::egui; +use constants::{MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, WINDOW_WIDTH}; -fn main() -> eframe::Result<()> { - let options = eframe::NativeOptions { - viewport: egui::ViewportBuilder::default() - .with_inner_size([900.0, 600.0]) - .with_min_inner_size([420.0, 280.0]) - .with_decorations(false) // Отключаем стандартные рамки ОС - .with_transparent(true), // Прозрачность для скругления углов - // Аппаратный MSAA (сглаживание на уровне GPU): 0 — выключен, - // дальше степень двойки. Для плоского 2D-интерфейса egui разница - // почти незаметна, но если внутри появится 3D/сложные меши, - // это единственный «настоящий» переключатель сглаживания. - multisampling: 4, - // Дизеринг убирает полосы (banding) на градиентах и полупрозрачных - // заливках. Он включён по умолчанию, здесь оставлен явно. - dithering: true, - ..Default::default() - }; +fn main() { + application().with_assets(assets::Assets).run(|cx| { + // Инициализация темы, шрифтов и компонентов обязательна до создания окон. + init(cx); - eframe::run_native( - "Custom Window 0.37", - options, - Box::new(|cc| Ok(Box::new(MyApp::new(cc)))), - ) + open_window(window_options(), cx, |window, cx| { + cx.new(|cx| MyApp::new(window, cx).with_startup_script()) + }) + .expect("не удалось открыть окно"); + }); +} + +/// Параметры окна в стиле исходного приложения: размер 900×600, минимум +/// 420×280 и собственный заголовок вместо системного. +fn window_options() -> WindowOptions { + WindowOptions { + window_bounds: Some(WindowBounds::Windowed(Bounds::new( + point(px(100.), px(100.)), + size(px(WINDOW_WIDTH), px(WINDOW_HEIGHT)), + ))), + window_min_size: Some(size(px(MIN_WINDOW_WIDTH), px(MIN_WINDOW_HEIGHT))), + // На Linux системный заголовок включается на уровне оконного менеджера. + // `Client` просит отдать оформление приложению — это аналог + // `with_decorations(false)` из прошлой версии. + window_decorations: Some(WindowDecorations::Client), + titlebar: Some(TitlebarOptions { + title: Some(WINDOW_TITLE.into()), + ..TitleBar::title_bar_options() + }), + ..TitleBar::window_options() + } } diff --git a/src/syntax.rs b/src/syntax.rs deleted file mode 100644 index 2beca30..0000000 --- a/src/syntax.rs +++ /dev/null @@ -1,522 +0,0 @@ -//! Интеграция tree-sitter: разбор текста и подсветка синтаксиса. -//! -//! Модуль не зависит от UI-кода: [`SyntaxState::parse`] возвращает обычное -//! дерево tree-sitter, поэтому его можно использовать не только для цветов, -//! но и для навигации по структуре кода, поиска узлов и проверки ошибок. -//! -//! Подсветка — это список байтовых диапазонов с [`HighlightStyle`]. Как именно -//! их раскрашивать, решает редактор (см. `ui::code_editor`). -//! -//! Поддерживаемые языки: Rust, Go, JavaScript, JSON, Python. Подсветка -//! выключена, пока для документа явно не выбран язык (см. `AppApi::set_language`). - -use std::collections::hash_map::DefaultHasher; -use std::hash::{Hash, Hasher}; -use std::sync::OnceLock; - -use tree_sitter::{Parser, Query, QueryCursor, StreamingIterator, Tree}; - -/// Язык, для которого подключена грамматика tree-sitter. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum Language { - Rust, - Go, - JavaScript, - Json, - Python, -} - -impl Language { - /// Все поддерживаемые языки. - #[allow(dead_code)] - // Часть публичного интерфейса модуля: удобно для перебора языков снаружи. - pub const ALL: [Self; 5] = [ - Self::Rust, - Self::Go, - Self::JavaScript, - Self::Json, - Self::Python, - ]; - - /// Разбирает название языка из API/сценария. - /// - /// Основные имена — `rust`, `go`, `js`, `json`, `python`; короткие - /// (`rs`, `golang`, `javascript`, `py`) и регистр тоже принимаются. - pub fn from_name(name: &str) -> Option { - match name.trim().to_ascii_lowercase().as_str() { - "rust" | "rs" => Some(Self::Rust), - "go" | "golang" => Some(Self::Go), - "js" | "javascript" | "node" => Some(Self::JavaScript), - "json" => Some(Self::Json), - "python" | "py" => Some(Self::Python), - _ => None, - } - } - - /// Каноническое имя языка (то, что возвращает `AppApi::language`). - pub fn name(self) -> &'static str { - match self { - Self::Rust => "rust", - Self::Go => "go", - Self::JavaScript => "js", - Self::Json => "json", - Self::Python => "python", - } - } - - /// Грамматика tree-sitter для языка. - fn grammar(self) -> tree_sitter::Language { - match self { - Self::Rust => tree_sitter_rust::LANGUAGE.into(), - Self::Go => tree_sitter_go::LANGUAGE.into(), - Self::JavaScript => tree_sitter_javascript::LANGUAGE.into(), - Self::Json => tree_sitter_json::LANGUAGE.into(), - Self::Python => tree_sitter_python::LANGUAGE.into(), - } - } - - /// Запрос подсветки для языка. - fn query_source(self) -> &'static str { - match self { - Self::Rust => RUST_QUERY, - Self::Go => GO_QUERY, - Self::JavaScript => JS_QUERY, - Self::Json => JSON_QUERY, - Self::Python => PYTHON_QUERY, - } - } -} - -/// Семантическая категория участка кода. -/// -/// Редактор сам выбирает цвет для каждой категории, поэтому тема оформления -/// не зависит от грамматик. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum HighlightStyle { - Keyword, - String, - Escape, - Number, - Comment, - Function, - Type, - Property, - Constant, - Operator, - Punctuation, - Variable, -} - -impl HighlightStyle { - /// Числовая метка для компактного буфера при разборе пересечений. - fn tag(self) -> u8 { - match self { - Self::Keyword => 1, - Self::String => 2, - Self::Escape => 3, - Self::Number => 4, - Self::Comment => 5, - Self::Function => 6, - Self::Type => 7, - Self::Property => 8, - Self::Constant => 9, - Self::Operator => 10, - Self::Punctuation => 11, - Self::Variable => 12, - } - } - - fn from_tag(tag: u8) -> Option { - Some(match tag { - 1 => Self::Keyword, - 2 => Self::String, - 3 => Self::Escape, - 4 => Self::Number, - 5 => Self::Comment, - 6 => Self::Function, - 7 => Self::Type, - 8 => Self::Property, - 9 => Self::Constant, - 10 => Self::Operator, - 11 => Self::Punctuation, - 12 => Self::Variable, - _ => return None, - }) - } - - /// Приоритет при совпадении диапазонов: более специфичная категория - /// должна перекрывать более общую (например, имя функции — свойство). - fn priority(self) -> u8 { - match self { - Self::Variable | Self::Punctuation | Self::Operator | Self::String => 1, - Self::Number | Self::Constant | Self::Property => 2, - Self::Escape | Self::Type => 3, - Self::Function => 4, - Self::Keyword | Self::Comment => 5, - } - } -} - -/// Участок текста с назначенным стилем (байтовые смещения, `end` не включён). -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct HighlightSpan { - pub start: usize, - pub end: usize, - pub style: HighlightStyle, -} - -/// Состояние разбора одного документа: переиспользуемый парсер и кэш подсветки. -/// -/// Кэш сравнивает язык и хеш текста, поэтому при наборе текста подсветка -/// пересчитывается, а в остальные кадры берётся готовый результат. -#[derive(Default)] -pub struct SyntaxState { - parser: Option, - cache: Option, -} - -impl SyntaxState { - /// Разбирает текст в дерево tree-sitter. - /// - /// Это универсальная точка входа: дерево можно обходить для поиска - /// определений, проверки ошибок и любых других задач, не связанных с - /// подсветкой. Возвращает `None`, если грамматика не установилась. - pub fn parse(&mut self, language: Language, text: &str) -> Option { - let parser = self.parser.get_or_insert_with(Parser::new); - if let Err(err) = parser.set_language(&language.grammar()) { - eprintln!("tree-sitter: не удалось установить язык {language:?}: {err}"); - return None; - } - parser.parse(text, None) - } - - /// Подсвеченные участки текста для языка. - /// - /// Результат кэшируется по языку и содержимому, поэтому вызывать метод - /// каждый кадр дёшево, пока текст не изменился. - pub fn spans(&mut self, language: Language, text: &str) -> &[HighlightSpan] { - let signature = Signature { - language, - len: text.len(), - hash: hash_text(text), - }; - - let fresh = self - .cache - .as_ref() - .is_some_and(|cache| cache.signature == signature); - - if !fresh { - // Подсветка строится поверх того же дерева, которое отдаёт `parse`, - // поэтому разбор всегда один. - let spans = self - .parse(language, text) - .map(|tree| highlight_tree(language, text, &tree)) - .unwrap_or_default(); - self.cache = Some(HighlightCache { signature, spans }); - } - - &self - .cache - .as_ref() - .expect("кэш заполняется выше при промахе") - .spans - } -} - -/// Ключ кэша подсветки. -#[derive(Clone, Copy, PartialEq, Eq)] -struct Signature { - language: Language, - len: usize, - hash: u64, -} - -struct HighlightCache { - signature: Signature, - spans: Vec, -} - -/// Сырой захват запроса до разрешения пересечений. -struct RawSpan { - start: usize, - end: usize, - style: HighlightStyle, -} - -impl RawSpan { - fn priority(&self) -> u8 { - self.style.priority() - } -} - -/// Считает участки подсветки по готовому дереву tree-sitter. -fn highlight_tree(language: Language, text: &str, tree: &Tree) -> Vec { - let Some(query) = query(language) else { - return Vec::new(); - }; - - let capture_names = query.capture_names(); - let mut cursor = QueryCursor::new(); - let mut matches = cursor.matches(query, tree.root_node(), text.as_bytes()); - - let mut raw = Vec::new(); - while let Some(matched) = matches.next() { - for capture in matched.captures { - let Some(style) = style_for_capture(capture_names[capture.index as usize]) else { - continue; - }; - let range = capture.node.byte_range(); - if range.start < range.end && range.end <= text.len() { - raw.push(RawSpan { - start: range.start, - end: range.end, - style, - }); - } - } - } - drop(matches); - - resolve_overlaps(text, raw) -} - -/// Раскрашивает байты «сверху вниз»: сначала крупные участки, затем более -/// мелкие и приоритетные. Так вложенные escape-последовательности попадают -/// внутрь строк, а имя функции перекрывает свойство с тем же диапазоном. -fn resolve_overlaps(text: &str, mut raw: Vec) -> Vec { - raw.sort_by(|a, b| { - (b.end - b.start) - .cmp(&(a.end - a.start)) - .then(a.priority().cmp(&b.priority())) - }); - - let mut cells = vec![0u8; text.len()]; - for span in raw { - cells[span.start..span.end].fill(span.style.tag()); - } - - let mut spans = Vec::new(); - let mut index = 0; - while index < cells.len() { - let tag = cells[index]; - let start = index; - while index < cells.len() && cells[index] == tag { - index += 1; - } - if let Some(style) = HighlightStyle::from_tag(tag) { - spans.push(HighlightSpan { - start, - end: index, - style, - }); - } - } - spans -} - -/// Сопоставляет имя захвата запроса (`@function.method`, `@string`, ...) -/// с категорией стиля. -fn style_for_capture(name: &str) -> Option { - // Ключи JSON-объекта грамматика помечает как строки — рисуем их как свойства. - if name == "string.special.key" { - return Some(HighlightStyle::Property); - } - - let head = name.split('.').next().unwrap_or(name); - Some(match head { - "keyword" => HighlightStyle::Keyword, - "string" | "text" => HighlightStyle::String, - "escape" => HighlightStyle::Escape, - "number" => HighlightStyle::Number, - "comment" => HighlightStyle::Comment, - "function" | "method" | "attribute" | "decorator" => HighlightStyle::Function, - "type" | "constructor" => HighlightStyle::Type, - "property" => HighlightStyle::Property, - "constant" | "boolean" => HighlightStyle::Constant, - "operator" => HighlightStyle::Operator, - "punctuation" => HighlightStyle::Punctuation, - "variable" | "parameter" => HighlightStyle::Variable, - _ => return None, - }) -} - -fn hash_text(text: &str) -> u64 { - let mut hasher = DefaultHasher::new(); - text.hash(&mut hasher); - hasher.finish() -} - -/// Скомпилированный запрос подсветки (один на язык, создаётся при первом обращении). -fn query(language: Language) -> Option<&'static Query> { - static RUST: OnceLock> = OnceLock::new(); - static GO: OnceLock> = OnceLock::new(); - static JS: OnceLock> = OnceLock::new(); - static JSON: OnceLock> = OnceLock::new(); - static PYTHON: OnceLock> = OnceLock::new(); - - let slot = match language { - Language::Rust => &RUST, - Language::Go => &GO, - Language::JavaScript => &JS, - Language::Json => &JSON, - Language::Python => &PYTHON, - }; - - slot.get_or_init( - || match Query::new(&language.grammar(), language.query_source()) { - Ok(query) => Some(query), - Err(err) => { - eprintln!("tree-sitter: запрос подсветки для {language:?}: {err}"); - None - } - }, - ) - .as_ref() -} - -// Запросы намеренно не используют предикаты `#match?`: они не нужны для -// базовой подсветки и не должны зависеть от конкретной реализации tree-sitter. - -const RUST_QUERY: &str = r#" -(line_comment) @comment -(block_comment) @comment -(doc_comment) @comment - -(string_literal) @string -(raw_string_literal) @string -(char_literal) @string -(escape_sequence) @escape - -(integer_literal) @number -(float_literal) @number -(boolean_literal) @constant - -(type_identifier) @type -(primitive_type) @type -(field_identifier) @property -(lifetime) @type - -(function_item name: (identifier) @function) -(function_signature_item name: (identifier) @function) -(macro_invocation macro: (identifier) @function) -(call_expression function: (identifier) @function) -(call_expression function: (field_expression field: (field_identifier) @function)) -(metavariable) @variable - -[ - "as" "async" "await" "break" "const" "continue" "default" "dyn" "else" - "enum" "extern" "fn" "for" "gen" "if" "impl" "in" "let" "loop" "match" - "mod" "move" "pub" "raw" "ref" "return" "static" "struct" "trait" "type" - "union" "unsafe" "use" "where" "while" "yield" -] @keyword -(crate) @keyword -(mutable_specifier) @keyword -(self) @keyword -(super) @keyword -"#; - -const GO_QUERY: &str = r#" -(comment) @comment - -(interpreted_string_literal) @string -(raw_string_literal) @string -(rune_literal) @string -(escape_sequence) @escape - -(int_literal) @number -(float_literal) @number -(imaginary_literal) @number -(true) @constant -(false) @constant -(nil) @constant -(iota) @constant - -(type_identifier) @type -(field_identifier) @property - -(function_declaration name: (identifier) @function) -(method_declaration name: (field_identifier) @function) -(call_expression function: (identifier) @function) -(call_expression function: (selector_expression field: (field_identifier) @function)) - -[ - "break" "case" "chan" "const" "continue" "default" "defer" "else" - "fallthrough" "for" "func" "go" "goto" "if" "import" "interface" "map" - "package" "range" "return" "select" "struct" "switch" "type" "var" -] @keyword -"#; - -const JS_QUERY: &str = r#" -(comment) @comment - -(string) @string -(template_string) @string -(regex) @string -(escape_sequence) @escape -(number) @number -(true) @constant -(false) @constant -(null) @constant -(undefined) @constant - -(property_identifier) @property - -(function_declaration name: (identifier) @function) -(generator_function_declaration name: (identifier) @function) -(method_definition name: (property_identifier) @function) -(class_declaration name: (identifier) @type) -(call_expression function: (identifier) @function) -(call_expression function: (member_expression property: (property_identifier) @function)) - -[ - "as" "async" "await" "break" "case" "catch" "class" "const" "continue" - "debugger" "default" "delete" "do" "else" "export" "extends" "finally" - "for" "from" "function" "get" "if" "import" "in" "instanceof" "let" - "new" "of" "return" "set" "static" "switch" "target" "throw" "try" - "typeof" "var" "void" "while" "with" "yield" -] @keyword -(this) @keyword -(super) @keyword -"#; - -const JSON_QUERY: &str = r#" -(comment) @comment -(escape_sequence) @escape - -(pair key: (string) @string.special.key) -(string) @string -(number) @number -(true) @constant -(false) @constant -(null) @constant -"#; - -const PYTHON_QUERY: &str = r#" -(comment) @comment - -(string) @string -(concatenated_string) @string -(escape_sequence) @escape -(integer) @number -(float) @number -(none) @constant -(true) @constant -(false) @constant - -(attribute attribute: (identifier) @property) -(type (identifier) @type) - -(function_definition name: (identifier) @function) -(class_definition name: (identifier) @type) -(decorator) @function -(call function: (identifier) @function) -(call function: (attribute attribute: (identifier) @function)) - -[ - "and" "as" "assert" "async" "await" "break" "class" "continue" "def" - "del" "elif" "else" "except" "finally" "for" "from" "global" "if" - "import" "in" "is" "lambda" "match" "nonlocal" "not" "or" "pass" - "raise" "return" "try" "while" "with" "yield" -] @keyword -"#; diff --git a/src/tests.rs b/src/tests.rs index 533b933..6cfaa26 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,196 +1,29 @@ -//! Проверки UI-логики на «сырых» событиях egui (без реального окна). +//! Тесты доменной модели, Lua-интеграции и клавиатурных привязок. +//! +//! UI-часть (заголовок, перетаскивание, изменение размера) теперь принадлежит +//! gpui-kit, поэтому её отдельно не проверяем. Остаются тесты, которые +//! фиксируют поведение самого приложения: документы, API, Lua и KeyMap. use std::cell::RefCell; use std::rc::Rc; -use eframe::egui; +use gpui_kit::{Keystroke, Modifiers, TestAppContext}; -use crate::api::AppApi; +use crate::api::{AppApi, WindowCommand, drain_window_commands}; use crate::app::MyApp; -use crate::editor::EditorState; -use crate::keymap::KeyMap; +use crate::editor::{Language, Workspace}; +use crate::keymap::{KeyBinding, KeyMap, Modifiers as KeyModifiers}; use crate::script::ScriptEngine; -use crate::syntax::{HighlightStyle, Language, SyntaxState}; -use crate::ui::title_bar::TitleBarResponses; -const SCREEN: egui::Vec2 = egui::vec2(600.0, 400.0); - -/// Один проход кадра для данного экземпляра приложения: -/// возвращает ответы заголовка и команды окна. -fn step_app( - ctx: &egui::Context, - app: &mut MyApp, - events: Vec, -) -> (TitleBarResponses, Vec) { - let raw = egui::RawInput { - screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, SCREEN)), - events, - ..Default::default() - }; - - let mut bar = None; - let mut out = ctx.run_ui(raw, |ui| { - bar = Some(app.show(ui)); - }); - - let commands = out - .viewport_output - .get(&egui::ViewportId::ROOT) - .map(|output| output.commands.clone()) - .unwrap_or_default(); - out.textures_delta.clear(); - - (bar.expect("заголовок отрисован"), commands) -} - -/// Один проход кадра на свежем приложении. -fn step( - ctx: &egui::Context, - events: Vec, -) -> (TitleBarResponses, Vec) { - let mut app = MyApp::default(); - step_app(ctx, &mut app, events) -} - -fn button_event(pos: egui::Pos2, pressed: bool) -> egui::Event { - egui::Event::PointerButton { - pos, - button: egui::PointerButton::Primary, - pressed, - modifiers: egui::Modifiers::default(), - } -} - -fn click_at(ctx: &egui::Context, pos: egui::Pos2) -> Vec { - let mut commands = Vec::new(); - commands.extend(step(ctx, vec![egui::Event::PointerMoved(pos)]).1); - commands.extend(step(ctx, vec![button_event(pos, true)]).1); - commands.extend(step(ctx, vec![]).1); - commands.extend(step(ctx, vec![button_event(pos, false)]).1); - commands.extend(step(ctx, vec![]).1); - commands -} - -fn press_at(ctx: &egui::Context, pos: egui::Pos2) -> Vec { - let mut commands = step(ctx, vec![egui::Event::PointerMoved(pos)]).1; - commands.extend(step(ctx, vec![button_event(pos, true)]).1); - commands -} - -/// Событие клавиатуры, у которого логическая клавиша может отличаться от -/// физической (как при смене раскладки). -fn key_event( - physical: egui::Key, - logical: egui::Key, - pressed: bool, - modifiers: egui::Modifiers, -) -> egui::Event { - egui::Event::Key { - key: logical, - physical_key: Some(physical), - pressed, - repeat: false, - modifiers, - } +fn install_api(workspace: Rc>) -> (AppApi, Rc>) { + let keymap = Rc::new(RefCell::new(KeyMap::default())); + let api = AppApi::install(workspace, keymap.clone()); + (api, keymap) } #[test] -fn title_bar_buttons_are_hoverable_and_clickable() { - let ctx = egui::Context::default(); - // прогреваем: egui считает раскладку по предыдущему кадру - step(&ctx, vec![]); - let (bar, _) = step(&ctx, vec![]); - - let close_pos = bar.close.rect.center(); - let maximize_pos = bar.maximize.rect.center(); - let minimize_pos = bar.minimize.rect.center(); - - // Кнопки должны находиться в заголовке, а не где-то ещё - assert!(bar.drag.rect.contains(close_pos)); - - // Наведение даёт подсветку - step(&ctx, vec![egui::Event::PointerMoved(close_pos)]); - let (hovered, _) = step(&ctx, vec![]); - assert!( - hovered.close.hovered(), - "кнопка «закрыть» не подсвечивается" - ); - - let close_cmds = click_at(&ctx, close_pos); - assert!( - close_cmds.contains(&egui::ViewportCommand::Close), - "клик по «закрыть» не отправил Close: {close_cmds:?}" - ); - - let max_cmds = click_at(&ctx, maximize_pos); - assert!( - max_cmds.contains(&egui::ViewportCommand::Maximized(true)), - "клик по «развернуть» не отправил Maximized: {max_cmds:?}" - ); - - let min_cmds = click_at(&ctx, minimize_pos); - assert!( - min_cmds.contains(&egui::ViewportCommand::Minimized(true)), - "клик по «свернуть» не отправил Minimized: {min_cmds:?}" - ); -} - -#[test] -fn dragging_title_bar_starts_window_drag_even_over_the_text() { - for (name, x_offset) in [("по тексту", 40.0), ("по пустому месту", 300.0)] - { - let ctx = egui::Context::default(); - step(&ctx, vec![]); - let (bar, _) = step(&ctx, vec![]); - - let start = egui::pos2(bar.drag.rect.left() + x_offset, bar.drag.rect.center().y); - let moved = start + egui::vec2(24.0, 12.0); - - step(&ctx, vec![egui::Event::PointerMoved(start)]); - let mut commands = step(&ctx, vec![button_event(start, true)]).1; - commands.extend(step(&ctx, vec![egui::Event::PointerMoved(moved)]).1); - - assert!( - commands.contains(&egui::ViewportCommand::StartDrag), - "драг заголовка {name} не инициировал перемещение окна: {commands:?}" - ); - } -} - -#[test] -fn edges_and_corners_start_resize() { - use egui::viewport::ResizeDirection as Dir; - - let cases = [ - (egui::pos2(300.0, 2.0), Dir::North), - (egui::pos2(300.0, SCREEN.y - 2.0), Dir::South), - (egui::pos2(2.0, 200.0), Dir::West), - (egui::pos2(SCREEN.x - 2.0, 200.0), Dir::East), - (egui::pos2(2.0, 2.0), Dir::NorthWest), - (egui::pos2(SCREEN.x - 2.0, 2.0), Dir::NorthEast), - (egui::pos2(SCREEN.x - 2.0, SCREEN.y - 2.0), Dir::SouthEast), - (egui::pos2(2.0, SCREEN.y - 2.0), Dir::SouthWest), - ]; - - for (pos, expected) in cases { - let ctx = egui::Context::default(); - step(&ctx, vec![]); - step(&ctx, vec![]); - let commands = press_at(&ctx, pos); - assert!( - commands.contains(&egui::ViewportCommand::BeginResize(expected)), - "в точке {pos:?} ожидался BeginResize({expected:?}), получено: {commands:?}" - ); - assert!( - !commands.contains(&egui::ViewportCommand::StartDrag), - "в точке {pos:?} вместо ресайза началось перемещение окна" - ); - } -} - -#[test] -fn editor_state_keeps_at_least_one_tab() { - let mut state = EditorState::default(); +fn workspace_keeps_at_least_one_tab() { + let mut state = Workspace::default(); assert_eq!(state.documents().len(), 2); assert_eq!(state.active().name, "main.rs"); @@ -213,58 +46,51 @@ fn editor_state_keeps_at_least_one_tab() { #[test] fn closing_tab_before_active_keeps_the_same_document_active() { - let mut state = EditorState::default(); + let mut state = Workspace::default(); state.open_new(); - let name = state.active().name.clone(); + let id = state.active().id; state.close(0); - assert_eq!(state.active().name, name); + assert_eq!(state.active().id, id); assert_eq!(state.active_index(), 1); } #[test] fn editing_marks_document_dirty_and_saving_clears_it() { - let mut state = EditorState::default(); + let mut state = Workspace::default(); assert!(!state.active().is_dirty()); - state.active_mut().content.push_str("\n// правка\n"); + state.set_active_text("// правка\n"); assert!(state.active().is_dirty()); - state.active_mut().mark_saved(); + state.mark_active_saved(); assert!(!state.active().is_dirty()); } #[test] -fn typing_into_editor_updates_active_document() { - let ctx = egui::Context::default(); - let mut app = MyApp::default(); +fn revision_changes_only_for_external_edits() { + let mut state = Workspace::default(); + let revision = state.revision(); - // Прогреваем раскладку и кликаем в область редактора ниже панели вкладок. - step_app(&ctx, &mut app, vec![]); - let editor_pos = egui::pos2(SCREEN.x / 2.0, SCREEN.y - 80.0); - step_app(&ctx, &mut app, vec![egui::Event::PointerMoved(editor_pos)]); - step_app(&ctx, &mut app, vec![button_event(editor_pos, true)]); - step_app(&ctx, &mut app, vec![button_event(editor_pos, false)]); + // Набор текста в виджете ревизию не двигает: редактор уже показывает текст. + state.replace_active_content("typed".to_owned()); + assert_eq!(state.revision(), revision); - step_app(&ctx, &mut app, vec![egui::Event::Text("ZZZ".to_owned())]); + // Внешняя замена (Lua) — двигает. + state.set_active_text("from lua"); + assert_ne!(state.revision(), revision); - let editor = app.editor(); - let doc = editor.active(); - assert!( - doc.content.contains("ZZZ"), - "введённый текст не попал в документ: {:?}", - doc.content - ); - assert!(doc.is_dirty(), "правка должна помечать документ изменённым"); + // Переключение вкладки — тоже. + let before_switch = state.revision(); + state.set_active(1); + assert_ne!(state.revision(), before_switch); } #[test] fn api_lists_tabs_and_closes_them_by_number() { - let ctx = egui::Context::default(); - let mut app = MyApp::default(); - step_app(&ctx, &mut app, vec![]); + let workspace = Rc::new(RefCell::new(Workspace::default())); + let (api, _keymap) = install_api(workspace.clone()); - let api = AppApi::global(); let tabs = api.tabs(); assert_eq!( tabs.iter() @@ -279,52 +105,44 @@ fn api_lists_tabs_and_closes_them_by_number() { assert!(api.close_tab(1)); assert_eq!(api.tabs().len(), 1); - assert_eq!(app.editor().documents().len(), 1); + assert_eq!(workspace.borrow().documents().len(), 1); } #[test] fn api_save_writes_active_tab_to_file_named_after_it() { // Тест пишет во временный файл, а не в каталог проекта. - let mut state = EditorState::default(); + let workspace = Rc::new(RefCell::new(Workspace::default())); let path = std::env::temp_dir().join(format!( - "egui-rust-test-save-{}-{}.rs", + "gpui-editor-test-save-{}-{}.rs", std::process::id(), - state.active().id + workspace.borrow().active().id )); let _ = std::fs::remove_file(&path); { + let mut state = workspace.borrow_mut(); let doc = state.active_mut(); doc.name = path.to_string_lossy().into_owned(); doc.content = "fn main() {}\n".to_owned(); } - assert!(state.active().is_dirty()); + assert!(workspace.borrow().active().is_dirty()); - let editor = Rc::new(RefCell::new(state)); - let api = AppApi::install( - egui::Context::default(), - editor.clone(), - Rc::new(RefCell::new(KeyMap::default())), - ); + let (api, _keymap) = install_api(workspace.clone()); api.save().expect("сохранение должно удаться"); assert_eq!( std::fs::read_to_string(&path).expect("файл должен существовать"), "fn main() {}\n" ); - assert!(!editor.borrow().active().is_dirty()); + assert!(!workspace.borrow().active().is_dirty()); let _ = std::fs::remove_file(&path); } #[test] fn api_switches_tabs_forward_and_back_in_a_cycle() { - let editor = Rc::new(RefCell::new(EditorState::default())); - let api = AppApi::install( - egui::Context::default(), - editor.clone(), - Rc::new(RefCell::new(KeyMap::default())), - ); + let workspace = Rc::new(RefCell::new(Workspace::default())); + let (api, _keymap) = install_api(workspace.clone()); assert_eq!(api.active_tab_index(), 0); @@ -337,18 +155,39 @@ fn api_switches_tabs_forward_and_back_in_a_cycle() { // С первой вкладки предыдущая — последняя. assert_eq!(api.previous_tab(), 1); assert_eq!(api.previous_tab(), 0); - assert_eq!(editor.borrow().active_index(), 0); + assert_eq!(workspace.borrow().active_index(), 0); } #[test] -fn lua_script_can_include_files_and_control_the_app() { - let ctx = egui::Context::default(); - let mut app = MyApp::default(); - // Первый кадр публикует AppApi, который использует сценарий. - step_app(&ctx, &mut app, vec![]); +fn window_commands_are_queued_for_the_view() { + let workspace = Rc::new(RefCell::new(Workspace::default())); + let (api, _keymap) = install_api(workspace); + // Очередь могла остаться от другого теста на этом потоке — очищаем. + let _ = drain_window_commands(); + + api.minimize(); + api.toggle_maximize(); + api.set_maximized(false); + api.close(); + + assert_eq!( + drain_window_commands(), + vec![ + WindowCommand::Minimize, + WindowCommand::ToggleMaximize, + WindowCommand::SetMaximized(false), + WindowCommand::Close, + ] + ); + // Повторное чтение пустой очереди ничего не возвращает. + assert!(drain_window_commands().is_empty()); +} + +/// Временный каталог с уникальным именем для Lua-сценариев. +fn temp_script_dir(prefix: &str) -> std::path::PathBuf { let dir = std::env::temp_dir().join(format!( - "egui-rust-test-lua-{}-{}", + "gpui-editor-test-{prefix}-{}-{}", std::process::id(), std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) @@ -356,7 +195,15 @@ fn lua_script_can_include_files_and_control_the_app() { .as_nanos() )); std::fs::create_dir_all(&dir).expect("временный каталог сценариев"); + dir +} +#[test] +fn lua_script_can_include_files_and_control_the_app() { + let workspace = Rc::new(RefCell::new(Workspace::default())); + let (api, _keymap) = install_api(workspace.clone()); + + let dir = temp_script_dir("lua"); let helper = dir.join("helper.lua"); let main = dir.join("main.lua"); std::fs::write( @@ -373,22 +220,22 @@ fn lua_script_can_include_files_and_control_the_app() { ) .expect("main.lua"); - let engine = ScriptEngine::new(AppApi::global()).expect("движок Lua"); + let engine = ScriptEngine::new(api).expect("движок Lua"); engine.run_file(&main).expect("сценарий должен выполниться"); - let editor = app.editor(); + let state = workspace.borrow(); assert_eq!( - editor.documents()[0].content, + state.documents()[0].content, "from lua", "include должен выполнить подключённый файл в общем окружении" ); assert_eq!( - editor.active_index(), + state.active_index(), 1, "app:next_tab() не переключил вкладку" ); assert_eq!( - editor.documents()[1].language, + state.documents()[1].language, Some(Language::Python), "app:set_language() не включил подсветку из Lua" ); @@ -397,22 +244,11 @@ fn lua_script_can_include_files_and_control_the_app() { } #[test] -fn lua_key_bindings_use_physical_keys_and_modifiers() { - let ctx = egui::Context::default(); - let mut app = MyApp::default(); - // Первый кадр публикует AppApi с картой клавиш приложения. - step_app(&ctx, &mut app, vec![]); - - let dir = std::env::temp_dir().join(format!( - "egui-rust-test-keys-{}-{}", - std::process::id(), - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .expect("системные часы") - .as_nanos() - )); - std::fs::create_dir_all(&dir).expect("временный каталог сценариев"); +fn lua_key_bindings_match_press_release_and_modifiers() { + let workspace = Rc::new(RefCell::new(Workspace::default())); + let (api, keymap) = install_api(workspace.clone()); + let dir = temp_script_dir("keys"); let script = dir.join("keys.lua"); std::fs::write( &script, @@ -426,100 +262,80 @@ fn lua_key_bindings_use_physical_keys_and_modifiers() { ) .expect("keys.lua"); - let engine = ScriptEngine::new(AppApi::global()).expect("движок Lua"); + let engine = ScriptEngine::new(api).expect("движок Lua"); engine .run_file(&script) .expect("привязки должны назначиться"); - let text = |app: &MyApp| app.editor().active().content.clone(); + let text = || workspace.borrow().active().content.clone(); + let stroke = |key: &str, modifiers: gpui_kit::Modifiers| Keystroke { + modifiers, + key: key.to_owned(), + key_char: None, + }; + let fire = |keystroke: &Keystroke, pressed: bool| { + for callback in keymap.borrow().callbacks_for(keystroke, pressed) { + callback.call::<()>(()).expect("Lua-обработчик"); + } + }; - // Логическая клавиша Z, физическая A: срабатывает именно физическая. - step_app( - &ctx, - &mut app, - vec![key_event( - egui::Key::A, - egui::Key::Z, - true, - egui::Modifiers::default(), - )], - ); - assert_eq!(text(&app), "a pressed"); + // Нажатие A. + fire(&stroke("a", Modifiers::default()), true); + assert_eq!(text(), "a pressed"); // Shift+A не должна срабатывать как обычная A. - step_app( - &ctx, - &mut app, - vec![key_event( - egui::Key::A, - egui::Key::A, - true, - egui::Modifiers { + fire( + &stroke( + "a", + Modifiers { shift: true, ..Default::default() }, - )], + ), + true, ); - assert_eq!(text(&app), "a pressed"); + assert_eq!(text(), "a pressed"); - // Отпускание цифры 1, логическая клавиша при этом другая. - step_app( - &ctx, - &mut app, - vec![key_event( - egui::Key::Num1, - egui::Key::Num2, - false, - egui::Modifiers::default(), - )], - ); - assert_eq!(text(&app), "1 released"); + // Отпускание цифры 1. + fire(&stroke("1", Modifiers::default()), false); + assert_eq!(text(), "1 released"); - step_app( - &ctx, - &mut app, - vec![key_event( - egui::Key::C, - egui::Key::C, - true, - egui::Modifiers { + fire( + &stroke( + "c", + Modifiers { shift: true, ..Default::default() }, - )], + ), + true, ); - assert_eq!(text(&app), "shift c"); + assert_eq!(text(), "shift c"); - step_app( - &ctx, - &mut app, - vec![key_event( - egui::Key::Z, - egui::Key::Z, - true, - egui::Modifiers { - ctrl: true, + fire( + &stroke( + "z", + Modifiers { + control: true, ..Default::default() }, - )], + ), + true, ); - assert_eq!(text(&app), "ctrl z"); + assert_eq!(text(), "ctrl z"); // Отпускание R при зажатом Alt. - step_app( - &ctx, - &mut app, - vec![key_event( - egui::Key::R, - egui::Key::R, - false, - egui::Modifiers { + fire( + &stroke( + "r", + Modifiers { alt: true, ..Default::default() }, - )], + ), + false, ); - assert_eq!(text(&app), "alt r released"); + assert_eq!(text(), "alt r released"); let _ = std::fs::remove_dir_all(&dir); } @@ -528,119 +344,151 @@ fn lua_key_bindings_use_physical_keys_and_modifiers() { fn language_names_cover_all_supported_grammars() { for (name, expected) in [ ("rust", Language::Rust), + ("rs", Language::Rust), + ("Rust", Language::Rust), ("go", Language::Go), + ("golang", Language::Go), ("js", Language::JavaScript), + ("javascript", Language::JavaScript), ("json", Language::Json), ("python", Language::Python), + ("py", Language::Python), ] { - assert_eq!(Language::from_name(name), Some(expected), "язык {name}"); - assert_eq!(Language::from_name(&name.to_uppercase()), Some(expected)); + assert_eq!(Language::from_name(name), Some(expected), "язык {name:?}"); } - // Распространённые короткие имена. - assert_eq!(Language::from_name("rs"), Some(Language::Rust)); - assert_eq!(Language::from_name("golang"), Some(Language::Go)); - assert_eq!( - Language::from_name("javascript"), - Some(Language::JavaScript) - ); - assert_eq!(Language::from_name("py"), Some(Language::Python)); + assert_eq!(Language::from_name("unknown"), None); + assert_eq!(Language::from_name(""), None); - assert_eq!(Language::from_name("cobol"), None); -} - -#[test] -fn tree_sitter_highlights_all_supported_languages() { - let samples = [ - ( - Language::Rust, - "fn main() {\n let x = 42; // комментарий\n println!(\"hi\");\n}\n", - HighlightStyle::Keyword, - ), - ( - Language::Go, - "package main\n\nfunc main() {\n\tx := 42 // комментарий\n\t_ = x\n}\n", - HighlightStyle::Keyword, - ), - ( - Language::JavaScript, - "function main() {\n const x = 42; // comment\n console.log(\"hi\");\n}\n", - HighlightStyle::Keyword, - ), - ( - Language::Json, - "{\"name\": \"value\", \"count\": 42, \"ok\": true}\n", - HighlightStyle::Property, - ), - ( - Language::Python, - "def main():\n x = 42 # comment\n print(\"hi\")\n", - HighlightStyle::Keyword, - ), - ]; - - for (language, source, expected) in samples { - let mut syntax = SyntaxState::default(); - let styles: Vec<_> = syntax - .spans(language, source) - .iter() - .map(|span| span.style) - .collect(); - - assert!(!styles.is_empty(), "{language:?}: подсветка пуста"); - assert!( - styles.contains(&expected), - "{language:?}: нет стиля {expected:?} в {styles:?}" - ); - } -} - -#[test] -fn syntax_tree_is_available_for_tasks_beyond_highlighting() { - let mut syntax = SyntaxState::default(); - let tree = syntax - .parse(Language::Rust, "fn main() {}\n") - .expect("дерево должно разобраться"); - - let root = tree.root_node(); - assert_eq!(root.kind(), "source_file"); - - let mut cursor = root.walk(); - assert!( - root.children(&mut cursor) - .any(|node| node.kind() == "function_item"), - "в дереве должна находиться функция — его можно обходить, а не только красить" - ); + // Канонические имена, которые возвращает API и Lua. + assert_eq!(Language::Rust.name(), "rust"); + assert_eq!(Language::JavaScript.name(), "js"); + assert_eq!(Language::Python.name(), "python"); } #[test] fn highlighting_is_off_by_default_and_enabled_through_api() { - let ctx = egui::Context::default(); - let mut app = MyApp::default(); - step_app(&ctx, &mut app, vec![]); + let workspace = Rc::new(RefCell::new(Workspace::default())); + let (api, _keymap) = install_api(workspace.clone()); - assert!( - app.editor() - .documents() - .iter() - .all(|doc| doc.language.is_none()), - "подсветка должна быть выключена по умолчанию" + assert_eq!(api.language(0), None); + assert_eq!(workspace.borrow().documents()[0].language, None); + + assert!(api.set_language(0, "rs")); + assert_eq!(api.language(0), Some("rust".to_owned())); + assert_eq!( + workspace.borrow().documents()[0].language, + Some(Language::Rust) ); - let api = AppApi::global(); - assert!(api.set_language(0, "rust")); - assert_eq!(api.language(0).as_deref(), Some("rust")); - assert_eq!(app.editor().documents()[0].language, Some(Language::Rust)); - - // Неизвестный язык и несуществующая вкладка не меняют состояние. + // Неизвестный язык и несуществующая вкладка. assert!(!api.set_language(0, "cobol")); assert!(!api.set_language(99, "rust")); - assert_eq!(api.language(0).as_deref(), Some("rust")); - - // Кадр с включённой подсветкой должен отрисовываться без паники. - step_app(&ctx, &mut app, vec![]); assert!(api.clear_language(0)); assert_eq!(api.language(0), None); - assert!(!api.clear_language(99)); +} + +#[test] +fn keymap_bindings_are_parsed_and_replaced() { + let plain = KeyBinding::parse("a").expect("a"); + let ctrl = KeyBinding::parse("").expect("ctrl-s"); + assert_eq!(plain.modifiers, KeyModifiers::default()); + assert!(ctrl.modifiers.ctrl); + assert!(!ctrl.on_release); + + // Повторное назначение той же клавиши не увеличивает число привязок: + // проверить это можно только через KeyMap, поэтому создаём пару функций. + let lua = mlua::Lua::new(); + let mut keymap = KeyMap::default(); + let first = lua + .load("return function() end") + .eval::() + .unwrap(); + let second = lua + .load("return function() end") + .eval::() + .unwrap(); + keymap.bind(plain.clone(), first); + keymap.bind(plain, second); + + let stroke = Keystroke { + modifiers: Modifiers::default(), + key: "a".to_owned(), + key_char: None, + }; + assert_eq!(keymap.callbacks_for(&stroke, true).len(), 1); +} + +#[gpui_kit::test] +fn lua_key_bindings_receive_keys_while_editor_is_focused(cx: &mut TestAppContext) { + cx.update(gpui_kit::init); + + let mut workspace = None; + let (app, visual) = cx.add_window_view(|window, cx| { + let app = MyApp::new(window, cx); + workspace = Some(app.workspace_handle()); + app + }); + let workspace = workspace.expect("вид создан"); + + // Регистрируем привязку через Lua — так же, как это делает init.lua. + let dir = temp_script_dir("ui-keys"); + let script = dir.join("keys.lua"); + std::fs::write( + &script, + r#"app:map_key("", function() app:set_active_text("alt r pressed") end)"#, + ) + .expect("keys.lua"); + let engine = ScriptEngine::new(AppApi::global()).expect("движок Lua"); + engine.run_file(&script).expect("привязка"); + + visual.update(|window, cx| { + app.update(cx, |this, cx| { + this.editor_handle() + .update(cx, |state, cx| state.focus(window, cx)); + }); + }); + + // Событие клавиатуры идёт через фокус редактора вверх до корня вида, + // где его видит KeyMap. + visual.simulate_keystrokes("alt-r"); + visual.run_until_parked(); + + assert_eq!(workspace.borrow().active().content, "alt r pressed"); + + drop(engine); + let _ = std::fs::remove_dir_all(&dir); +} + +#[gpui_kit::test] +fn typing_into_editor_updates_active_document(cx: &mut TestAppContext) { + cx.update(gpui_kit::init); + + let mut workspace = None; + let (app, visual) = cx.add_window_view(|window, cx| { + let app = MyApp::new(window, cx); + workspace = Some(app.workspace_handle()); + app + }); + let workspace = workspace.expect("вид создан"); + + // Фокус нужен до первого ввода: simulate_input отправляет текст в + // сфокусированный ввод. + visual.update(|window, cx| { + app.update(cx, |this, cx| { + this.editor_handle() + .update(cx, |state, cx| state.focus(window, cx)); + }); + }); + visual.simulate_input("ZZZ"); + + let state = workspace.borrow(); + let doc = state.active(); + assert!( + doc.content.contains("ZZZ"), + "введённый текст не попал в документ: {:?}", + doc.content + ); + assert!(doc.is_dirty(), "правка должна помечать документ изменённым"); } diff --git a/src/ui/code_editor.rs b/src/ui/code_editor.rs deleted file mode 100644 index aeb6a4b..0000000 --- a/src/ui/code_editor.rs +++ /dev/null @@ -1,298 +0,0 @@ -//! Область редактирования кода: нумерация строк и многострочное поле ввода. - -use eframe::egui; - -use crate::constants::CORNER_RADIUS; -use crate::editor::Document; -use crate::syntax::{HighlightStyle, Language, SyntaxState}; - -const FONT_SIZE: f32 = 13.0; -/// Отступы текста от краёв области (как у обычного `TextEdit`). -const MARGIN_X: i8 = 10; -const MARGIN_Y: i8 = 8; -/// Отступ номера строки от текста справа и минимальная ширина колонки. -const GUTTER_PADDING: f32 = 12.0; - -/// Рисует редактор активного документа. -/// -/// `focus` — запросить фокус у поля ввода (например, сразу после переключения вкладки). -pub fn render(ui: &mut egui::Ui, doc: &mut Document, focus: bool) { - let area = ui.available_rect_before_wrap(); - - // Фон на всю оставшуюся область; нижние углы повторяют скругление окна. - ui.painter().rect_filled( - area, - egui::CornerRadius { - nw: 0, - ne: 0, - sw: CORNER_RADIUS, - se: CORNER_RADIUS, - }, - ui.visuals().extreme_bg_color, - ); - - let font_id = egui::FontId::monospace(FONT_SIZE); - let char_width = ui.fonts_mut(|fonts| fonts.glyph_width(&font_id, '0')); - let line_height = - ui.fonts_mut(|fonts| fonts.row_height(&font_id)) + ui.spacing().extra_text_line_spacing; - - let line_count = doc.content.split('\n').count(); - let gutter_width = - (line_count.to_string().len() as f32 * char_width + GUTTER_PADDING * 2.0).max(30.0); - - // Сколько строк нужно, чтобы поле ввода заполнило пустую область целиком: - // клик ниже последней строки должен ставить курсор, а не попадать в пустоту. - let rows_to_fill = - (((area.height() - 2.0 * f32::from(MARGIN_Y)) / line_height).floor() as usize).max(1); - - let doc_id = doc.id; - let language = doc.language; - // Поля берём по отдельности: `content` нужен `TextEdit`, а `syntax` — - // подсветке, и это разные заимствования одного документа. - let content = &mut doc.content; - let syntax = &mut doc.syntax; - - egui::ScrollArea::vertical() - .id_salt(("code_scroll", doc_id)) - .auto_shrink([false, false]) - .show(ui, |ui| { - // Без отступов между гуттером и текстом: строка должна быть единой. - ui.spacing_mut().item_spacing = egui::Vec2::ZERO; - - let gutter_left = ui.cursor().left(); - - let output = ui - .horizontal_top(|ui| { - ui.add_space(gutter_width); - - let text_edit = egui::TextEdit::multiline(&mut *content) - .id_salt(("code_edit", doc_id)) - .font(font_id.clone()) - .frame(egui::Frame::NONE.inner_margin(egui::Margin { - left: MARGIN_X, - right: MARGIN_X, - top: MARGIN_Y, - bottom: MARGIN_Y, - })) - .desired_width(f32::INFINITY) - .desired_rows(rows_to_fill.max(line_count)); - - // Подсветка включается только для документов с выбранным - // языком; без него используется стандартный layouter. - if let Some(language) = language { - let theme = SyntaxTheme::from_visuals(ui.visuals()); - let mut layouter = - |ui: &egui::Ui, text: &dyn egui::TextBuffer, wrap_width: f32| { - let job = highlighted_layout_job( - text.as_str(), - language, - syntax, - &theme, - &font_id, - line_height, - wrap_width, - ); - ui.fonts_mut(|fonts| fonts.layout_job(job)) - }; - text_edit.layouter(&mut layouter).show(ui) - } else { - text_edit.show(ui) - } - }) - .inner; - - if focus { - output.response.response.request_focus(); - } - - paint_line_numbers( - ui, - &output, - content.as_str(), - &font_id, - gutter_left, - gutter_width, - ); - }); -} - -/// Собирает `LayoutJob` для подсвеченного текста. -/// -/// Форматирование повторяет стандартный layouter `TextEdit`, чтобы курсор, -/// перенос строк и номера строк работали так же, как без подсветки. -fn highlighted_layout_job( - text: &str, - language: Language, - syntax: &mut SyntaxState, - theme: &SyntaxTheme, - font_id: &egui::FontId, - line_height: f32, - wrap_width: f32, -) -> egui::text::LayoutJob { - let mut job = egui::text::LayoutJob::default(); - job.wrap.max_width = wrap_width; - job.keep_trailing_whitespace = true; - - let format = |color: egui::Color32| egui::TextFormat { - font_id: font_id.clone(), - color, - line_height: Some(line_height), - ..Default::default() - }; - - let mut cursor = 0; - for span in syntax.spans(language, text) { - if span.start > cursor { - job.append( - text.get(cursor..span.start).unwrap_or_default(), - 0.0, - format(theme.default), - ); - } - job.append( - text.get(span.start..span.end).unwrap_or_default(), - 0.0, - format(theme.color(span.style)), - ); - cursor = span.end; - } - if cursor < text.len() { - job.append( - text.get(cursor..).unwrap_or_default(), - 0.0, - format(theme.default), - ); - } - if text.is_empty() { - // Пустой абзац нужен, чтобы у поля была строка для курсора. - job.append("", 0.0, format(theme.default)); - } - - job -} - -/// Цвета подсветки, подобранные под текущую тему egui. -#[derive(Clone, Copy)] -struct SyntaxTheme { - default: egui::Color32, - keyword: egui::Color32, - string: egui::Color32, - escape: egui::Color32, - number: egui::Color32, - comment: egui::Color32, - function: egui::Color32, - type_: egui::Color32, - property: egui::Color32, - constant: egui::Color32, - operator: egui::Color32, - punctuation: egui::Color32, - variable: egui::Color32, -} - -impl SyntaxTheme { - fn from_visuals(visuals: &egui::Visuals) -> Self { - let default = visuals.text_color(); - - if visuals.dark_mode { - Self { - default, - keyword: egui::Color32::from_rgb(0xC6, 0x78, 0xDD), - string: egui::Color32::from_rgb(0x98, 0xC3, 0x79), - escape: egui::Color32::from_rgb(0x56, 0xB6, 0xC2), - number: egui::Color32::from_rgb(0xD1, 0x9A, 0x66), - comment: egui::Color32::from_rgb(0x7F, 0x84, 0x8E), - function: egui::Color32::from_rgb(0x61, 0xAF, 0xEF), - type_: egui::Color32::from_rgb(0xE5, 0xC0, 0x7B), - property: egui::Color32::from_rgb(0xE0, 0x6C, 0x75), - constant: egui::Color32::from_rgb(0xD1, 0x9A, 0x66), - operator: egui::Color32::from_rgb(0x56, 0xB6, 0xC2), - punctuation: egui::Color32::from_rgb(0xAB, 0xB2, 0xBF), - variable: default, - } - } else { - Self { - default, - keyword: egui::Color32::from_rgb(0xA6, 0x26, 0xA4), - string: egui::Color32::from_rgb(0x50, 0xA1, 0x4F), - escape: egui::Color32::from_rgb(0x01, 0x84, 0xBC), - number: egui::Color32::from_rgb(0x98, 0x68, 0x01), - comment: egui::Color32::from_rgb(0xA0, 0xA1, 0xA7), - function: egui::Color32::from_rgb(0x40, 0x78, 0xF2), - type_: egui::Color32::from_rgb(0xC1, 0x84, 0x01), - property: egui::Color32::from_rgb(0xE4, 0x56, 0x49), - constant: egui::Color32::from_rgb(0x98, 0x68, 0x01), - operator: egui::Color32::from_rgb(0x01, 0x84, 0xBC), - punctuation: egui::Color32::from_rgb(0x38, 0x3A, 0x42), - variable: default, - } - } - } - - fn color(&self, style: HighlightStyle) -> egui::Color32 { - match style { - HighlightStyle::Keyword => self.keyword, - HighlightStyle::String => self.string, - HighlightStyle::Escape => self.escape, - HighlightStyle::Number => self.number, - HighlightStyle::Comment => self.comment, - HighlightStyle::Function => self.function, - HighlightStyle::Type => self.type_, - HighlightStyle::Property => self.property, - HighlightStyle::Constant => self.constant, - HighlightStyle::Operator => self.operator, - HighlightStyle::Punctuation => self.punctuation, - HighlightStyle::Variable => self.variable, - } - } -} - -/// Рисует номера строк вдоль гуттера. -/// -/// Строки берутся из галереи `TextEdit`, поэтому номера совпадают с текстом даже -/// при переносе длинных строк: у перенесённой строки номер не повторяется. -fn paint_line_numbers( - ui: &egui::Ui, - output: &egui::widgets::text_edit::TextEditOutput, - content: &str, - font_id: &egui::FontId, - gutter_left: f32, - gutter_width: f32, -) { - let visuals = ui.visuals(); - let number_color = visuals.weak_text_color(); - let current_line_color = visuals.strong_text_color(); - - // Индекс курсора — в символах, а не в байтах. - let current_line = output.cursor_range.map(|range| { - content - .chars() - .take(range.primary.index.into()) - .filter(|&c| c == '\n') - .count() - }); - let has_focus = output.response.response.has_focus(); - - let right = gutter_left + gutter_width - GUTTER_PADDING; - let painter = ui.painter(); - - let mut line_number = 1; - let mut starts_new_line = true; - for row in &output.galley.rows { - if starts_new_line { - let is_current = has_focus && current_line == Some(line_number - 1); - painter.text( - egui::pos2(right, output.galley_pos.y + row.rect().center().y), - egui::Align2::RIGHT_CENTER, - line_number, - font_id.clone(), - if is_current { - current_line_color - } else { - number_color - }, - ); - line_number += 1; - } - starts_new_line = row.ends_with_newline; - } -} diff --git a/src/ui/icons.rs b/src/ui/icons.rs deleted file mode 100644 index 49a33f7..0000000 --- a/src/ui/icons.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! Векторные иконки кнопок заголовка (без шрифтов — рисуются через `Painter`). - -use eframe::egui; - -/// Тип иконки, отображаемой на кнопке заголовка. -pub enum IconType { - Minimize, - Maximize, - Restore, - Close, - Plus, -} - -/// Кнопка с векторной иконкой внутри. -pub fn custom_icon_button(ui: &mut egui::Ui, size: egui::Vec2, icon: IconType) -> egui::Response { - let (rect, response) = ui.allocate_exact_size(size, egui::Sense::click()); - - if response.hovered() { - ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); - } - - let visuals = ui.style().interact(&response); - - // Подсветка кнопки при наведении мыши - if response.hovered() || response.is_pointer_button_down_on() { - ui.painter().rect_filled(rect, 4.0, visuals.bg_fill); - } - - let stroke = egui::Stroke::new(1.5, visuals.fg_stroke.color); - let center = rect.center(); - let r = 5.0; // Размер иконки относительно центра - - match icon { - IconType::Minimize => { - ui.painter().line_segment( - [center - egui::vec2(r, 0.0), center + egui::vec2(r, 0.0)], - stroke, - ); - } - IconType::Maximize => { - ui.painter().rect_stroke( - egui::Rect::from_center_size(center, egui::vec2(r * 2.0, r * 2.0)), - 0.0, - stroke, - egui::StrokeKind::Middle, - ); - } - IconType::Restore => { - // Два перекрывающихся квадрата — символ «восстановить» - let back = egui::Rect::from_center_size( - center + egui::vec2(2.0, -2.0), - egui::vec2(r * 2.0, r * 2.0), - ); - let front = egui::Rect::from_center_size( - center + egui::vec2(-2.0, 2.0), - egui::vec2(r * 2.0, r * 2.0), - ); - // Заливаем «передний» квадрат фоном, чтобы задний не просвечивал сквозь него - let fill = if response.hovered() || response.is_pointer_button_down_on() { - visuals.bg_fill - } else { - ui.visuals().window_fill() - }; - ui.painter().rect_filled(front, 0.0, fill); - ui.painter() - .rect_stroke(back, 0.0, stroke, egui::StrokeKind::Middle); - ui.painter() - .rect_stroke(front, 0.0, stroke, egui::StrokeKind::Middle); - } - IconType::Close => { - ui.painter().line_segment( - [center - egui::vec2(r, r), center + egui::vec2(r, r)], - stroke, - ); - ui.painter().line_segment( - [center - egui::vec2(-r, r), center + egui::vec2(-r, r)], - stroke, - ); - } - IconType::Plus => { - ui.painter().line_segment( - [center - egui::vec2(4.0, 0.0), center + egui::vec2(4.0, 0.0)], - stroke, - ); - ui.painter().line_segment( - [center - egui::vec2(0.0, 4.0), center + egui::vec2(0.0, 4.0)], - stroke, - ); - } - } - - response -} diff --git a/src/ui/mod.rs b/src/ui/mod.rs deleted file mode 100644 index 7e586e2..0000000 --- a/src/ui/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Виджеты окна: интегрированный заголовок, вкладки, редактор, иконки -//! и зоны изменения размера. - -pub mod code_editor; -pub mod icons; -pub mod resize_handles; -pub mod tabs; -pub mod title_bar; diff --git a/src/ui/resize_handles.rs b/src/ui/resize_handles.rs deleted file mode 100644 index 68a0db5..0000000 --- a/src/ui/resize_handles.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! Невидимые зоны по периметру окна для изменения размера. - -use eframe::egui; - -use crate::api::AppApi; -use crate::constants::RESIZE_BORDER; - -/// Невидимые полосы и уголки по периметру окна: тянут за них — меняется размер окна. -/// -/// Регистрируются последними (в том же слое), поэтому выигрывают hit-test у содержимого. -/// Само изменение размера выполняет оконная система через `ViewportCommand::BeginResize`. -pub fn render(ui: &mut egui::Ui) { - use egui::viewport::ResizeDirection as Dir; - - let api = AppApi::global(); - let ctx = api.context(); - - // Развёрнутое окно уже занимает весь экран — тянуть нечего. - if api.is_maximized() { - return; - } - - let b = RESIZE_BORDER; - let rect = ctx.content_rect(); - if rect.width() <= 2.0 * b || rect.height() <= 2.0 * b { - return; - } - - let north = egui::Rect::from_min_max(rect.left_top(), egui::pos2(rect.right(), rect.top() + b)); - let south = egui::Rect::from_min_max( - egui::pos2(rect.left(), rect.bottom() - b), - rect.right_bottom(), - ); - let west = - egui::Rect::from_min_max(rect.left_top(), egui::pos2(rect.left() + b, rect.bottom())); - let east = egui::Rect::from_min_max( - egui::pos2(rect.right() - b, rect.top()), - rect.right_bottom(), - ); - - let edges = [ - ( - Dir::North, - egui::CursorIcon::ResizeVertical, - north, - "resize_n", - ), - ( - Dir::South, - egui::CursorIcon::ResizeVertical, - south, - "resize_s", - ), - ( - Dir::West, - egui::CursorIcon::ResizeHorizontal, - west, - "resize_w", - ), - ( - Dir::East, - egui::CursorIcon::ResizeHorizontal, - east, - "resize_e", - ), - ]; - - // Углы идут после рёбер: в них должен побеждать диагональный ресайз. - let corners = [ - ( - Dir::NorthWest, - egui::CursorIcon::ResizeNwSe, - egui::Rect::from_min_size(rect.left_top(), egui::Vec2::splat(b)), - "resize_nw", - ), - ( - Dir::NorthEast, - egui::CursorIcon::ResizeNeSw, - egui::Rect::from_min_size( - egui::pos2(rect.right() - b, rect.top()), - egui::Vec2::splat(b), - ), - "resize_ne", - ), - ( - Dir::SouthEast, - egui::CursorIcon::ResizeNwSe, - egui::Rect::from_min_size( - egui::pos2(rect.right() - b, rect.bottom() - b), - egui::Vec2::splat(b), - ), - "resize_se", - ), - ( - Dir::SouthWest, - egui::CursorIcon::ResizeNeSw, - egui::Rect::from_min_size( - egui::pos2(rect.left(), rect.bottom() - b), - egui::Vec2::splat(b), - ), - "resize_sw", - ), - ]; - - for (direction, cursor, handle_rect, id_salt) in edges.into_iter().chain(corners) { - // `Sense::drag()` (без click) — перетаскивание начинается сразу по нажатию, - // а именно этого требует `BeginResize`. - let response = ui.interact( - handle_rect, - ui.scope_id().with(id_salt), - egui::Sense::drag(), - ); - - if response.hovered() { - ctx.set_cursor_icon(cursor); - } - if response.drag_started() { - ctx.send_viewport_cmd(egui::ViewportCommand::BeginResize(direction)); - } - } -} diff --git a/src/ui/tabs.rs b/src/ui/tabs.rs deleted file mode 100644 index 85e90b9..0000000 --- a/src/ui/tabs.rs +++ /dev/null @@ -1,228 +0,0 @@ -//! Полоса вкладок над редактором. - -use eframe::egui; - -use crate::constants::TAB_BAR_HEIGHT; -use crate::editor::Document; -use crate::ui::icons::{IconType, custom_icon_button}; - -/// Действия пользователя с вкладками за текущий кадр. -#[derive(Default)] -pub struct TabBarActions { - /// Клик по вкладке: её нужно сделать активной. - pub clicked_tab: Option, - /// Клик по крестику: вкладку нужно закрыть. - pub closed_tab: Option, - /// Клик по «+»: нужно открыть новый документ. - pub add_clicked: bool, -} - -const TAB_MIN_WIDTH: f32 = 96.0; -const TAB_MAX_WIDTH: f32 = 220.0; -const TAB_PADDING_LEFT: f32 = 12.0; -const TAB_PADDING_RIGHT: f32 = 6.0; -const TAB_LABEL_GAP: f32 = 6.0; -const TAB_CLOSE_SIZE: f32 = 18.0; -const TAB_CORNER_RADIUS: u8 = 6; - -/// Рисует полосу вкладок и возвращает действия пользователя. -pub fn render(ui: &mut egui::Ui, documents: &[Document], active: usize) -> TabBarActions { - let mut actions = TabBarActions::default(); - - let bar_rect = egui::Rect::from_min_size( - ui.cursor().min, - egui::vec2(ui.available_width(), TAB_BAR_HEIGHT), - ); - - let visuals = ui.visuals().clone(); - - // Фон полосы совпадает с фоном заголовка, поэтому она выглядит его продолжением. - ui.painter() - .rect_filled(bar_rect, 0.0, visuals.window_fill()); - - // Тонкая линия-разделитель под вкладками. Активная вкладка перекрывает её - // и сливается с фоном редактора. - let separator = egui::Rect::from_min_max( - egui::pos2(bar_rect.left(), bar_rect.bottom() - 1.0), - bar_rect.right_bottom(), - ); - ui.painter().rect_filled( - separator, - 0.0, - visuals.widgets.noninteractive.bg_stroke.color, - ); - - ui.allocate_ui_with_layout( - egui::vec2(bar_rect.width(), TAB_BAR_HEIGHT), - egui::Layout::left_to_right(egui::Align::Center), - |ui| { - ui.spacing_mut().item_spacing.x = 2.0; - ui.add_space(6.0); - - for (index, doc) in documents.iter().enumerate() { - let tab = tab(ui, doc, index == active); - if tab.close_clicked { - actions.closed_tab = Some(index); - } else if tab.clicked { - actions.clicked_tab = Some(index); - } - } - - ui.add_space(4.0); - let add = custom_icon_button(ui, egui::vec2(20.0, 20.0), IconType::Plus); - if add.on_hover_text("Новая вкладка").clicked() { - actions.add_clicked = true; - } - }, - ); - - actions -} - -struct TabResponse { - clicked: bool, - close_clicked: bool, -} - -/// Одна вкладка: фон, название и кнопка закрытия. -fn tab(ui: &mut egui::Ui, doc: &Document, is_active: bool) -> TabResponse { - let font_id = egui::FontId::proportional(12.5); - let label_width = ui.fonts_mut(|fonts| { - fonts - .layout_no_wrap(doc.name.clone(), font_id.clone(), egui::Color32::WHITE) - .size() - .x - }); - let width = - (label_width + TAB_PADDING_LEFT + TAB_LABEL_GAP + TAB_CLOSE_SIZE + TAB_PADDING_RIGHT) - .clamp(TAB_MIN_WIDTH, TAB_MAX_WIDTH); - - let (rect, response) = - ui.allocate_exact_size(egui::vec2(width, TAB_BAR_HEIGHT), egui::Sense::click()); - if response.hovered() { - ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); - } - - let visuals = ui.visuals().clone(); - let corner = egui::CornerRadius { - nw: TAB_CORNER_RADIUS, - ne: TAB_CORNER_RADIUS, - sw: 0, - se: 0, - }; - - let fill = if is_active { - visuals.extreme_bg_color - } else if response.hovered() { - // Полтона от цвета hover-виджетов: вкладка должна подсвечиваться мягко. - visuals - .window_fill() - .lerp_to_gamma(visuals.widgets.hovered.weak_bg_fill, 0.5) - } else { - egui::Color32::TRANSPARENT - }; - ui.painter().rect_filled(rect, corner, fill); - - // Акцентная полоска у активной вкладки. - if is_active { - let stripe = egui::Rect::from_min_size(rect.left_top(), egui::vec2(rect.width(), 2.0)); - ui.painter() - .rect_filled(stripe, corner, visuals.selection.bg_fill); - } - - let close_rect = egui::Rect::from_center_size( - egui::pos2( - rect.right() - TAB_PADDING_RIGHT - TAB_CLOSE_SIZE / 2.0, - rect.center().y, - ), - egui::Vec2::splat(TAB_CLOSE_SIZE), - ); - - let text_color = if is_active { - visuals.strong_text_color() - } else if response.hovered() { - visuals.text_color() - } else { - visuals.weak_text_color() - }; - - // Название рисуем через `LayoutJob`, чтобы длинные имена обрезались многоточием. - let mut job = egui::text::LayoutJob::single_section( - doc.name.clone(), - egui::TextFormat::simple(font_id, text_color), - ); - job.wrap = egui::text::TextWrapping { - max_width: (close_rect.left() - TAB_LABEL_GAP - (rect.left() + TAB_PADDING_LEFT)).max(0.0), - max_rows: 1, - break_anywhere: true, - overflow_character: Some('…'), - }; - let galley = ui.fonts_mut(|fonts| fonts.layout_job(job)); - ui.painter().galley( - egui::pos2( - rect.left() + TAB_PADDING_LEFT, - rect.center().y - galley.size().y / 2.0, - ), - galley, - text_color, - ); - - // Кнопка закрытия регистрируется после вкладки, поэтому выигрывает у неё hit-test - // в своей области (так же, как кнопки заголовка регистрируются после drag-зоны). - let close = close_button( - ui, - close_rect, - ui.scope_id().with(("tab_close", doc.id)), - is_active || response.hovered(), - doc.is_dirty(), - ); - - TabResponse { - clicked: response.clicked(), - close_clicked: close.clicked(), - } -} - -/// Маленький крестик вкладки; у изменённого документа вместо него — точка. -fn close_button( - ui: &mut egui::Ui, - rect: egui::Rect, - id: egui::Id, - show_cross: bool, - dirty: bool, -) -> egui::Response { - // Невидимый крестик не должен ловить клики: иначе клик по пустому месту - // закрывал бы вкладку. - let sense = if show_cross { - egui::Sense::click() - } else { - egui::Sense::hover() - }; - let response = ui.interact(rect, id, sense); - - let visuals = ui.visuals(); - let painter = ui.painter(); - - if response.hovered() { - ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); - painter.rect_filled(rect, 4.0, visuals.widgets.hovered.bg_fill); - } - - let center = rect.center(); - if dirty && !response.hovered() { - painter.circle_filled(center, 3.0, visuals.selection.bg_fill); - } else if show_cross { - let stroke = egui::Stroke::new(1.2, visuals.weak_text_color()); - let r = 3.5; - painter.line_segment( - [center + egui::vec2(-r, r), center + egui::vec2(r, -r)], - stroke, - ); - painter.line_segment( - [center + egui::vec2(-r, -r), center + egui::vec2(r, r)], - stroke, - ); - } - - response -} diff --git a/src/ui/title_bar.rs b/src/ui/title_bar.rs deleted file mode 100644 index 312a74a..0000000 --- a/src/ui/title_bar.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! Интегрированный в окно заголовок: перетаскивание и кнопки управления. - -use eframe::egui; - -use crate::api::AppApi; -use crate::constants::TITLE_BAR_HEIGHT; -use crate::ui::icons::{IconType, custom_icon_button}; - -/// Ответы виджетов заголовка: нужны, чтобы отличать клик по кнопке от драга окна. -pub struct TitleBarResponses { - pub close: egui::Response, - pub maximize: egui::Response, - pub minimize: egui::Response, - pub drag: egui::Response, -} - -impl TitleBarResponses { - fn any_button_hovered(&self) -> bool { - self.close.hovered() || self.maximize.hovered() || self.minimize.hovered() - } -} - -/// Рисует заголовок окна с именем активного документа и применяет действия -/// кнопок через [`AppApi`]. -pub fn render(ui: &mut egui::Ui, document_name: &str) -> TitleBarResponses { - let api = AppApi::global(); - let ctx = api.context(); - let is_maximized = api.is_maximized(); - - let bar_rect = egui::Rect::from_min_size( - ui.cursor().min, - egui::vec2(ui.available_width(), TITLE_BAR_HEIGHT), - ); - - // ВАЖНО: зона перетаскивания регистрируется ПЕРВОЙ. - // В egui hit-test побеждает виджет, добавленный последним, а `Response::hovered()` - // получают только виджеты из `hits.click` / `hits.drag`. Если зарегистрировать - // drag-зону после кнопок, она станет и клик-, и drag-целью — кнопки перестанут - // получать и клики, и подсветку при наведении. - let drag = ui.interact( - bar_rect, - ui.scope_id().with("title_bar_drag"), - egui::Sense::click_and_drag(), - ); - - let mut close = None; - let mut maximize = None; - let mut minimize = None; - - ui.allocate_ui_with_layout( - egui::vec2(ui.available_width(), TITLE_BAR_HEIGHT), - egui::Layout::left_to_right(egui::Align::Center), - |ui| { - ui.spacing_mut().item_spacing = egui::vec2(4.0, 0.0); - - // Текст заголовка (слева). - // `selectable(false)` обязателен: иначе лейбл получает Sense::click_and_drag, - // регистрируется поверх drag-зоны и перехватывает перетаскивание окна, - // а текст начинает выделяться мышкой. - ui.add_space(12.0); - ui.add( - egui::Label::new( - egui::RichText::new(format!("{document_name} — Custom Window App")) - .size(13.0) - .strong(), - ) - .selectable(false), - ); - - // Блок кнопок управления окном (смещаем в правый край через right_to_left) - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - ui.add_space(8.0); // Отступ справа от крайней кнопки - - let button_size = egui::vec2(24.0, 24.0); - - // Порядок важен: в right_to_left первая добавленная кнопка — крайняя правая. - close = Some(custom_icon_button(ui, button_size, IconType::Close)); - let max_icon = if is_maximized { - IconType::Restore - } else { - IconType::Maximize - }; - maximize = Some(custom_icon_button(ui, button_size, max_icon)); - minimize = Some(custom_icon_button(ui, button_size, IconType::Minimize)); - }); - }, - ); - - let responses = TitleBarResponses { - close: close.expect("кнопка закрытия создаётся всегда"), - maximize: maximize.expect("кнопка разворота создаётся всегда"), - minimize: minimize.expect("кнопка сворачивания создаётся всегда"), - drag, - }; - - // Действия кнопок — только через глобальный API. - if responses.close.clicked() { - api.close(); - } - if responses.maximize.clicked() { - api.toggle_maximize(); - } - if responses.minimize.clicked() { - api.minimize(); - } - - // Перетаскивать окно можно за любую свободную часть заголовка (включая текст). - if !is_maximized - && !responses.any_button_hovered() - && responses.drag.drag_started_by(egui::PointerButton::Primary) - { - ctx.send_viewport_cmd(egui::ViewportCommand::StartDrag); - } - - // Двойной клик по заголовку — стандартное разворачивание/восстановление - if responses.drag.double_clicked() && !responses.any_button_hovered() { - api.toggle_maximize(); - } - - responses -}