From b1a581e81b6eaa951a7ca195cb0c46c335d0d5c7 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Tue, 13 Aug 2024 13:18:25 -0400 Subject: [PATCH] Copy/paste images into editors (Mac only) (#15782) For future reference: WIP branch of copy/pasting a mixture of images and text: https://github.com/zed-industries/zed/tree/copy-paste-images - we'll come back to that one after landing this one. Release Notes: - You can now paste images into the Assistant Panel to include them as context. Currently works only on Mac, and with Anthropic models. Future support is planned for more models, operating systems, and image clipboard operations. --------- Co-authored-by: Antonio Co-authored-by: Mikayla Co-authored-by: Jason Co-authored-by: Kyle --- Cargo.lock | 2254 +++++++++-------- crates/assistant/Cargo.toml | 1 + crates/assistant/src/assistant_panel.rs | 139 +- crates/assistant/src/context.rs | 247 +- crates/assistant/src/inline_assistant.rs | 2 +- crates/assistant/src/prompt_library.rs | 2 +- .../src/terminal_inline_assistant.rs | 2 +- crates/collab_ui/src/channel_view.rs | 2 +- crates/collab_ui/src/chat_panel.rs | 2 +- crates/collab_ui/src/collab_panel.rs | 4 +- .../src/collab_panel/channel_modal.rs | 3 +- crates/copilot/src/sign_in.rs | 4 +- crates/editor/src/blame_entry_tooltip.rs | 14 +- crates/editor/src/editor.rs | 60 +- crates/editor/src/editor_tests.rs | 5 +- crates/editor/src/element.rs | 6 +- crates/feedback/src/feedback.rs | 2 +- crates/gpui/Cargo.toml | 1 + crates/gpui/src/app.rs | 47 +- crates/gpui/src/asset_cache.rs | 50 +- crates/gpui/src/assets.rs | 22 +- crates/gpui/src/elements/img.rs | 241 +- crates/gpui/src/elements/mod.rs | 2 + crates/gpui/src/elements/surface.rs | 111 + crates/gpui/src/geometry.rs | 18 +- crates/gpui/src/platform.rs | 233 +- .../src/platform/linux/wayland/clipboard.rs | 16 +- crates/gpui/src/platform/linux/x11/client.rs | 14 +- crates/gpui/src/platform/mac.rs | 1 + .../src/platform/mac/attributed_string.rs | 122 + .../gpui/src/platform/mac/metal_renderer.rs | 6 +- crates/gpui/src/platform/mac/platform.rs | 353 ++- crates/gpui/src/platform/windows/platform.rs | 32 +- crates/gpui/src/scene.rs | 20 +- crates/gpui/src/style.rs | 123 +- crates/gpui/src/window.rs | 99 +- crates/language_model/Cargo.toml | 3 + .../language_model/src/provider/anthropic.rs | 50 +- .../src/provider/copilot_chat.rs | 4 +- crates/language_model/src/provider/ollama.rs | 8 +- crates/language_model/src/provider/open_ai.rs | 2 +- crates/language_model/src/request.rs | 255 +- crates/live_kit_client/src/test.rs | 4 +- crates/markdown/src/markdown.rs | 4 +- crates/outline_panel/src/outline_panel.rs | 4 +- crates/paths/src/paths.rs | 6 + crates/project_panel/src/project_panel.rs | 6 +- crates/repl/src/outputs.rs | 6 +- crates/terminal/src/terminal.rs | 24 +- crates/terminal_view/src/terminal_view.rs | 4 +- crates/vim/src/normal/paste.rs | 8 +- crates/vim/src/state.rs | 20 +- .../src/test/neovim_backed_test_context.rs | 7 +- crates/vim/src/vim.rs | 4 +- crates/vim/src/visual.rs | 2 +- crates/workspace/src/notifications.rs | 2 +- crates/workspace/src/pane.rs | 4 +- crates/workspace/src/shared_screen.rs | 4 +- 58 files changed, 2983 insertions(+), 1708 deletions(-) create mode 100644 crates/gpui/src/elements/surface.rs create mode 100644 crates/gpui/src/platform/mac/attributed_string.rs diff --git a/Cargo.lock b/Cargo.lock index fd11771ae5..9f79f1863e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -65,7 +65,7 @@ checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "const-random", - "getrandom 0.2.10", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -93,8 +93,8 @@ dependencies = [ "miow", "parking_lot", "piper", - "polling 3.3.2", - "regex-automata 0.4.5", + "polling 3.7.2", + "regex-automata 0.4.7", "rustix-openpty", "serde", "signal-hook", @@ -117,20 +117,19 @@ checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alsa" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2562ad8dcf0f789f65c6fdaad8a8a9708ed6b488e649da28c01656ad66b8b47" +checksum = "37fe60779335388a88c01ac6c3be40304d1e349de3ada3b15f7808bb90fa9dce" dependencies = [ "alsa-sys", - "bitflags 1.3.2", + "bitflags 2.6.0", "libc", - "nix 0.24.3", ] [[package]] @@ -170,20 +169,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" -[[package]] -name = "anstream" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon 2.1.0", - "colorchoice", - "utf8parse", -] - [[package]] name = "anstream" version = "0.6.15" @@ -193,7 +178,7 @@ dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", - "anstyle-wincon 3.0.4", + "anstyle-wincon", "colorchoice", "is_terminal_polyfill", "utf8parse", @@ -201,36 +186,26 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" -dependencies = [ - "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -294,14 +269,14 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -327,7 +302,7 @@ version = "0.38.0+1.3.281" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "libloading 0.8.0", + "libloading", ] [[package]] @@ -337,7 +312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52bca67b61cb81e5553babde81b8211f713cb6db79766f80168f3e5f40ea6c82" dependencies = [ "ash", - "raw-window-handle 0.6.0", + "raw-window-handle", "raw-window-metal", ] @@ -347,7 +322,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfe7e0dd0ac5a401dc116ed9f9119cf9decc625600474cb41f0fc0a0050abc9a" dependencies = [ - "async-fs 2.1.1", + "async-fs 2.1.2", "async-net 2.0.0", "enumflags2", "futures-channel", @@ -422,13 +397,14 @@ dependencies = [ "serde_json", "serde_json_lenient", "settings", + "smallvec", "smol", "telemetry_events", "terminal", "terminal_view", "text", "theme", - "toml 0.8.16", + "toml 0.8.19", "ui", "unindent", "util", @@ -467,8 +443,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" dependencies = [ - "event-listener 5.1.0", - "event-listener-strategy 0.5.0", + "event-listener 5.3.1", + "event-listener-strategy", "futures-core", "pin-project-lite", ] @@ -486,13 +462,12 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 5.1.0", - "event-listener-strategy 0.5.0", + "event-listener-strategy", "futures-core", "pin-project-lite", ] @@ -536,15 +511,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.5.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ - "async-lock 2.8.0", "async-task", "concurrent-queue", - "fastrand 1.9.0", - "futures-lite 1.13.0", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] @@ -562,27 +536,27 @@ dependencies = [ [[package]] name = "async-fs" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc19683171f287921f2405677dd2ed2549c3b3bda697a563ebc3a121ace2aba1" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "blocking", - "futures-lite 2.2.0", + "futures-lite 2.3.0", ] [[package]] name = "async-global-executor" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 1.9.0", + "async-channel 2.3.1", "async-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io 2.3.3", + "async-lock 3.4.0", "blocking", - "futures-lite 1.13.0", + "futures-lite 2.3.0", "once_cell", ] @@ -602,24 +576,24 @@ dependencies = [ "polling 2.8.0", "rustix 0.37.27", "slab", - "socket2 0.4.9", + "socket2 0.4.10", "waker-fn", ] [[package]] name = "async-io" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "parking", - "polling 3.3.2", - "rustix 0.38.32", + "polling 3.7.2", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -636,12 +610,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", + "event-listener 5.3.1", + "event-listener-strategy", "pin-project-lite", ] @@ -659,12 +633,11 @@ dependencies = [ [[package]] name = "async-net" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" +checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" dependencies = [ "async-io 1.13.0", - "autocfg", "blocking", "futures-lite 1.13.0", ] @@ -675,9 +648,9 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ - "async-io 2.3.1", + "async-io 2.3.3", "blocking", - "futures-lite 2.2.0", + "futures-lite 2.3.0", ] [[package]] @@ -691,37 +664,38 @@ dependencies = [ [[package]] name = "async-process" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ "async-io 1.13.0", "async-lock 2.8.0", - "autocfg", + "async-signal", "blocking", "cfg-if", - "event-listener 2.5.3", + "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.37.27", - "signal-hook", + "rustix 0.38.34", "windows-sys 0.48.0", ] [[package]] name = "async-process" -version = "2.1.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451e3cf68011bd56771c79db04a9e333095ab6349f7e47592b788e9b98720cc8" +checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" dependencies = [ - "async-channel 2.2.0", - "async-io 2.3.1", - "async-lock 3.3.0", + "async-channel 2.3.1", + "async-io 2.3.3", + "async-lock 3.4.0", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 5.1.0", - "futures-lite 2.2.0", - "rustix 0.38.32", + "event-listener 5.3.1", + "futures-lite 2.3.0", + "rustix 0.38.34", + "tracing", "windows-sys 0.52.0", ] @@ -738,31 +712,31 @@ dependencies = [ [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" dependencies = [ - "async-io 2.3.1", - "async-lock 2.8.0", + "async-io 2.3.3", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.32", + "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -776,7 +750,7 @@ dependencies = [ "async-global-executor", "async-io 1.13.0", "async-lock 2.8.0", - "async-process 1.7.0", + "async-process 1.8.1", "crossbeam-utils", "futures-channel", "futures-core", @@ -812,7 +786,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -864,7 +838,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -899,7 +873,7 @@ checksum = "00b9f7252833d5ed4b00aa9604b563529dd5e11de9c23615de2dcdf91eb87b52" dependencies = [ "async-compression", "crc32fast", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "pin-project", "thiserror", ] @@ -910,7 +884,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "futures-sink", "futures-util", "memchr", @@ -934,9 +908,9 @@ checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" [[package]] name = "atomic-waker" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "audio" @@ -980,9 +954,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "av1-grain" @@ -1009,9 +983,9 @@ dependencies = [ [[package]] name = "aws-config" -version = "1.1.5" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7af266887e24cd5f6d2ea7433cacd25dcd4773b7f70e488701968a7cdf51df57" +checksum = "caf6cfe2881cb1fcbba9ae946fb9a6480d3b7a714ca84c74925014a89ef3387a" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1025,23 +999,24 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.5.0", - "fastrand 2.0.0", + "bytes 1.7.1", + "fastrand 2.1.0", "hex", - "http 0.2.9", + "http 0.2.12", "hyper", "ring", "time", "tokio", "tracing", + "url", "zeroize", ] [[package]] name = "aws-credential-types" -version = "1.1.5" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d56f287a9e65e4914bfedb5b22c056b65e4c232fca512d5509a9df36386759f" +checksum = "e16838e6c9e12125face1c1eff1343c75e3ff540de98ff7ebd61874a89bcfeb9" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -1051,9 +1026,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.1.5" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6a29eca8ea8982028a4df81883e7001e250a21d323b86418884b5345950a4b" +checksum = "87c5f920ffd1e0526ec9e70e50bf444db50b204395a0fa7016bbf9e31ea1698f" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -1063,10 +1038,10 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.5.0", - "fastrand 2.0.0", - "http 0.2.9", - "http-body", + "bytes 1.7.1", + "fastrand 2.1.0", + "http 0.2.12", + "http-body 0.4.6", "percent-encoding", "pin-project-lite", "tracing", @@ -1075,10 +1050,11 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.15.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c977e92277652aefb9a76a0fca652b26757d6845dce0d7bf4426da80f13d85b0" +checksum = "558bbcec8db82a1a8af1610afcb3b10d00652d25ad366a0558eecdff2400a1d1" dependencies = [ + "ahash 0.8.11", "aws-credential-types", "aws-runtime", "aws-sigv4", @@ -1092,21 +1068,26 @@ dependencies = [ "aws-smithy-types", "aws-smithy-xml", "aws-types", - "bytes 1.5.0", - "http 0.2.9", - "http-body", + "bytes 1.7.1", + "fastrand 2.1.0", + "hex", + "hmac", + "http 0.2.12", + "http-body 0.4.6", + "lru", "once_cell", "percent-encoding", "regex-lite", + "sha2", "tracing", "url", ] [[package]] name = "aws-sdk-sso" -version = "1.13.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d7f527c7b28af1a641f7d89f9e6a4863e8ec00f39d2b731b056fc5ec5ce829" +checksum = "6acca681c53374bf1d9af0e317a41d12a44902ca0f2d1e10e5cb5bb98ed74f35" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1117,8 +1098,8 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.5.0", - "http 0.2.9", + "bytes 1.7.1", + "http 0.2.12", "once_cell", "regex-lite", "tracing", @@ -1126,9 +1107,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.13.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0be3224cd574ee8ab5fd7c32087876f25c134c27ac603fcb38669ed8d346b0" +checksum = "b79c6bdfe612503a526059c05c9ccccbf6bd9530b003673cb863e547fd7c0c9a" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1139,8 +1120,8 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.5.0", - "http 0.2.9", + "bytes 1.7.1", + "http 0.2.12", "once_cell", "regex-lite", "tracing", @@ -1148,9 +1129,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.13.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b3167c60d82a13bbaef569da06041644ff41e85c6377e5dad53fa2526ccfe9d" +checksum = "32e6ecdb2bd756f3b2383e6f0588dc10a4e65f5d551e70a56e0bfe0c884673ce" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1163,7 +1144,7 @@ dependencies = [ "aws-smithy-types", "aws-smithy-xml", "aws-types", - "http 0.2.9", + "http 0.2.12", "once_cell", "regex-lite", "tracing", @@ -1171,22 +1152,22 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.1.5" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b1cbe0eee57a213039088dbdeca7be9352f24e0d72332d961e8a1cb388f82d" +checksum = "5df1b0fa6be58efe9d4ccc257df0a53b89cd8909e86591a13ca54817c87517be" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", "aws-smithy-http", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.5.0", + "bytes 1.7.1", "crypto-bigint 0.5.5", "form_urlencoded", "hex", "hmac", - "http 0.2.9", - "http 1.0.0", + "http 0.2.12", + "http 1.1.0", "once_cell", "p256", "percent-encoding", @@ -1200,9 +1181,9 @@ dependencies = [ [[package]] name = "aws-smithy-async" -version = "1.1.5" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "426a5bc369ca7c8d3686439e46edc727f397a47ab3696b13f3ae8c81b3b36132" +checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" dependencies = [ "futures-util", "pin-project-lite", @@ -1211,18 +1192,18 @@ dependencies = [ [[package]] name = "aws-smithy-checksums" -version = "0.60.5" +version = "0.60.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee554133eca2611b66d23548e48f9b44713befdb025ab76bc00185b878397a1" +checksum = "48c4134cf3adaeacff34d588dbe814200357b0c466d730cf1c0d8054384a2de4" dependencies = [ "aws-smithy-http", "aws-smithy-types", - "bytes 1.5.0", + "bytes 1.7.1", "crc32c", "crc32fast", "hex", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "md-5", "pin-project-lite", "sha1", @@ -1237,24 +1218,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6363078f927f612b970edf9d1903ef5cef9a64d1e8423525ebb1f0a1633c858" dependencies = [ "aws-smithy-types", - "bytes 1.5.0", + "bytes 1.7.1", "crc32fast", ] [[package]] name = "aws-smithy-http" -version = "0.60.5" +version = "0.60.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85d6a0619f7b67183067fa3b558f94f90753da2df8c04aeb7336d673f804b0b8" +checksum = "d9cd0ae3d97daa0a2bf377a4d8e8e1362cae590c4a1aad0d40058ebca18eb91e" dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.5.0", + "bytes 1.7.1", "bytes-utils", "futures-core", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "once_cell", "percent-encoding", "pin-project-lite", @@ -1264,18 +1245,18 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.60.5" +version = "0.60.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1c1b5186b6f5c579bf0de1bcca9dd3d946d6d51361ea1d18131f6a0b64e13ae" +checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" dependencies = [ "aws-smithy-types", ] [[package]] name = "aws-smithy-query" -version = "0.60.5" +version = "0.60.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c0a2ce65882e788d2cf83ff28b9b16918de0460c47bf66c5da4f6c17b4c9694" +checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" dependencies = [ "aws-smithy-types", "urlencoding", @@ -1283,19 +1264,21 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.1.5" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4cb6b3afa5fc9825a75675975dcc3e21764b5476bc91dbc63df4ea3d30a576e" +checksum = "ce87155eba55e11768b8c1afa607f3e864ae82f03caf63258b37455b0ad02537" dependencies = [ "aws-smithy-async", "aws-smithy-http", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.5.0", - "fastrand 2.0.0", + "bytes 1.7.1", + "fastrand 2.1.0", "h2", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", + "http-body 1.0.1", + "httparse", "hyper", "hyper-rustls", "once_cell", @@ -1308,14 +1291,15 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.1.5" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23165433e80c04e8c09cee66d171292ae7234bae05fa9d5636e33095eae416b2" +checksum = "30819352ed0a04ecf6a2f3477e344d2d1ba33d43e0f09ad9047c12e0d923616f" dependencies = [ "aws-smithy-async", "aws-smithy-types", - "bytes 1.5.0", - "http 0.2.9", + "bytes 1.7.1", + "http 0.2.12", + "http 1.1.0", "pin-project-lite", "tokio", "tracing", @@ -1324,16 +1308,19 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.1.5" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94a5bec34850b92c9a054dad57b95c1d47f25125f55973e19f6ad788f0381ff" +checksum = "cfe321a6b21f5d8eabd0ade9c55d3d0335f3c3157fc2b3e87f05f34b539e4df5" dependencies = [ "base64-simd", - "bytes 1.5.0", + "bytes 1.7.1", "bytes-utils", "futures-core", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http 1.1.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", "itoa", "num-integer", "pin-project-lite", @@ -1347,24 +1334,23 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.60.5" +version = "0.60.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16f94c9673412b7a72e3c3efec8de89081c320bf59ea12eed34c417a62ad600" +checksum = "d123fbc2a4adc3c301652ba8e149bf4bc1d1725affb9784eb20c953ace06bf55" dependencies = [ "xmlparser", ] [[package]] name = "aws-types" -version = "1.1.5" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ff7e122ee50ca962e9de91f5850cc37e2184b1219611eef6d44aa85929b54f6" +checksum = "5221b91b3e441e6675310829fd8984801b772cb1546ef6c0e54dec9f1ac13fef" dependencies = [ "aws-credential-types", "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", - "http 0.2.9", "rustc_version", "tracing", ] @@ -1379,11 +1365,11 @@ dependencies = [ "axum-core", "base64 0.21.7", "bitflags 1.3.2", - "bytes 1.5.0", + "bytes 1.7.1", "futures-util", "headers", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "hyper", "itoa", "matchit", @@ -1412,10 +1398,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", - "bytes 1.5.0", + "bytes 1.7.1", "futures-util", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -1429,9 +1415,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9a320103719de37b7b4da4c8eb629d4573f6bcfd3dfe80d3208806895ccf81d" dependencies = [ "axum", - "bytes 1.5.0", + "bytes 1.7.1", "futures-util", - "http 0.2.9", + "http 0.2.12", "mime", "pin-project-lite", "serde", @@ -1518,26 +1504,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 1.0.109", -] - [[package]] name = "bindgen" version = "0.65.1" @@ -1557,10 +1523,30 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.59", + "syn 2.0.72", "which 4.4.2", ] +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.72", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -1614,9 +1600,9 @@ dependencies = [ [[package]] name = "bitstream-io" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c12d1856e42f0d817a835fe55853957c85c8c8a470114029143d3f12671446e" +checksum = "3dcde5f311c85b8ca30c2e4198d4326bc342c76541590106f5fa4a50946ea499" [[package]] name = "bitvec" @@ -1648,13 +1634,13 @@ dependencies = [ "hidden-trait", "js-sys", "khronos-egl", - "libloading 0.8.0", + "libloading", "log", "metal", "mint", "naga", "objc", - "raw-window-handle 0.6.0", + "raw-window-handle", "slab", "wasm-bindgen", "web-sys", @@ -1667,7 +1653,7 @@ source = "git+https://github.com/kvark/blade?rev=ac25c77ed8d86c386a541c935ffe0a0 dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -1707,18 +1693,15 @@ dependencies = [ [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 2.2.0", - "async-lock 3.3.0", + "async-channel 2.3.1", "async-task", - "fastrand 2.0.0", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] @@ -1738,10 +1721,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "syn_derive", ] @@ -1760,26 +1743,26 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.2" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.3.9", + "regex-automata 0.4.7", "serde", ] [[package]] name = "built" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" +checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "by_address" @@ -1789,9 +1772,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -1800,9 +1783,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", @@ -1811,22 +1794,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -1853,9 +1836,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "bytes-utils" @@ -1863,7 +1846,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "either", ] @@ -1899,8 +1882,8 @@ checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ "bitflags 2.6.0", "log", - "polling 3.3.2", - "rustix 0.38.32", + "polling 3.7.2", + "rustix 0.38.34", "slab", "thiserror", ] @@ -1912,7 +1895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", - "rustix 0.38.32", + "rustix 0.38.34", "wayland-backend", "wayland-client", ] @@ -1928,9 +1911,9 @@ dependencies = [ [[package]] name = "cap-fs-ext" -version = "3.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "769f8cd02eb04d57f14e2e371ebb533f96817f9b2525d73a5c72b61ca7973747" +checksum = "eb23061fc1c4ead4e45ca713080fe768e6234e959f5a5c399c39eb41aa34e56e" dependencies = [ "cap-primitives", "cap-std", @@ -1940,21 +1923,21 @@ dependencies = [ [[package]] name = "cap-net-ext" -version = "3.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ff6d3fb274292a9af283417e383afe6ded1fe66f6472d2c781216d3d80c218" +checksum = "f83ae11f116bcbafc5327c6af250341db96b5930046732e1905f7dc65887e0e1" dependencies = [ "cap-primitives", "cap-std", - "rustix 0.38.32", + "rustix 0.38.34", "smallvec", ] [[package]] name = "cap-primitives" -version = "3.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90a0b44fc796b1a84535a63753d50ba3972c4db55c7255c186f79140e63d56d0" +checksum = "6d00bd8d26c4270d950eaaa837387964a2089a1c3c349a690a1fa03221d29531" dependencies = [ "ambient-authority", "fs-set-times", @@ -1962,16 +1945,16 @@ dependencies = [ "io-lifetimes 2.0.3", "ipnet", "maybe-owned", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.52.0", "winx", ] [[package]] name = "cap-rand" -version = "3.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4327f08daac33a99bb03c54ae18c8f32c3ba31c728a33ddf683c6c6a5043de68" +checksum = "dbcb16a619d8b8211ed61f42bd290d2a1ac71277a69cf8417ec0996fa92f5211" dependencies = [ "ambient-authority", "rand 0.8.5", @@ -1979,27 +1962,27 @@ dependencies = [ [[package]] name = "cap-std" -version = "3.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266626ce180cf9709f317d0bf9754e3a5006359d87f4bf792f06c9c5f1b63c0f" +checksum = "19eb8e3d71996828751c1ed3908a439639752ac6bdc874e41469ef7fc15fbd7f" dependencies = [ "cap-primitives", "io-extras", "io-lifetimes 2.0.3", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] name = "cap-time-ext" -version = "3.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1353421ba83c19da60726e35db0a89abef984b3be183ff6f58c5b8084fcd0c5" +checksum = "61142dc51e25b7acc970ca578ce2c3695eac22bbba46c1073f5f583e78957725" dependencies = [ "ambient-authority", "cap-primitives", "iana-time-zone", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", "winx", ] @@ -2033,7 +2016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad639525b1c67b6a298f378417b060fbc04618bea559482a8484381cce27d965" dependencies = [ "serde", - "toml 0.8.16", + "toml 0.8.19", ] [[package]] @@ -2077,13 +2060,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.106" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", - "once_cell", ] [[package]] @@ -2169,9 +2151,9 @@ dependencies = [ [[package]] name = "chunked_transfer" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca491388666e04d7248af3f60f0c40cfb0991c72205595d7c396e3510207d1a" +checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" [[package]] name = "ciborium" @@ -2213,20 +2195,20 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading 0.7.4", + "libloading", ] [[package]] name = "clap" -version = "4.4.4" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", "clap_derive", @@ -2234,33 +2216,33 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ - "anstream 0.5.0", + "anstream", "anstyle", "clap_lex", - "strsim 0.10.0", + "strsim", ] [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "cli" @@ -2289,7 +2271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0875e527e299fc5f4faba42870bf199a39ab0bb2dbba1b8aef0a2151451130f" dependencies = [ "bstr", - "bytes 1.5.0", + "bytes 1.7.1", "clickhouse-derive", "clickhouse-rs-cityhash-sys", "futures 0.3.30", @@ -2312,7 +2294,7 @@ checksum = "18af5425854858c507eec70f7deb4d5d8cec4216fcb086283a78872387281ea5" dependencies = [ "proc-macro2", "quote", - "serde_derive_internals", + "serde_derive_internals 0.26.0", "syn 1.0.109", ] @@ -2514,7 +2496,7 @@ dependencies = [ "thiserror", "time", "tokio", - "toml 0.8.16", + "toml 0.8.19", "tower", "tower-http 0.4.4", "tracing", @@ -2587,17 +2569,17 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "memchr", ] @@ -2640,31 +2622,31 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-random" @@ -2681,7 +2663,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", "once_cell", "tiny-keccak", ] @@ -2748,16 +2730,10 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "core-foundation-sys 0.8.6", + "core-foundation-sys", "libc", ] -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" - [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -2811,22 +2787,22 @@ dependencies = [ [[package]] name = "coreaudio-rs" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb17e2d1795b1996419648915df94bc7103c28f7b48062d7acf4652fc371b2ff" +checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" dependencies = [ "bitflags 1.3.2", - "core-foundation-sys 0.6.2", + "core-foundation-sys", "coreaudio-sys", ] [[package]] name = "coreaudio-sys" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f034b2258e6c4ade2f73bf87b21047567fb913ee9550837c2316d139b0262b24" +checksum = "7f01585027057ff5f0a5bf276174ae4c1594a2c5bde93d5f46a016d76270f5a9" dependencies = [ - "bindgen 0.64.0", + "bindgen 0.69.4", ] [[package]] @@ -2853,27 +2829,25 @@ dependencies = [ [[package]] name = "cpal" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d959d90e938c5493000514b446987c07aed46c668faaa7d34d6c7a67b1a578c" +checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" dependencies = [ "alsa", - "core-foundation-sys 0.8.6", + "core-foundation-sys", "coreaudio-rs", "dasp_sample", - "jni 0.19.0", + "jni", "js-sys", "libc", "mach2", "ndk", "ndk-context", "oboe", - "once_cell", - "parking_lot", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows 0.46.0", + "windows 0.54.0", ] [[package]] @@ -2887,9 +2861,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -2916,7 +2890,7 @@ dependencies = [ "cranelift-control", "cranelift-entity", "cranelift-isle", - "gimli 0.28.0", + "gimli 0.28.1", "hashbrown 0.14.5", "log", "regalloc2", @@ -3006,33 +2980,33 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32c" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89254598aa9b9fa608de44b3ae54c810f0f06d755e24c50177f1f8f31ff50ce2" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" dependencies = [ "rustc_version", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -3075,56 +3049,46 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -3172,7 +3136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -3187,24 +3151,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.9", - "winapi", + "socket2 0.5.7", + "windows-sys 0.52.0", ] [[package]] name = "curl-sys" -version = "0.4.67+curl-8.3.0" +version = "0.4.74+curl-8.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc35d066510b197a0f72de863736641539957628c8a42e70e27c66849e77c34" +checksum = "8af10b986114528fcdc4b63b6f5f021b7057618411046a4de2ba0f0149a097bf" dependencies = [ "cc", "libc", @@ -3212,7 +3176,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3256,9 +3220,9 @@ checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-url" @@ -3286,9 +3250,9 @@ dependencies = [ [[package]] name = "deflate64" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ace6c86376be0b6cdcf3fb41882e81d94b31587573d1cfa9d01cd06bba210d" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" [[package]] name = "der" @@ -3302,9 +3266,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -3342,7 +3306,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -3474,7 +3438,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.0", + "libloading", ] [[package]] @@ -3485,9 +3449,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "doxygen-rs" @@ -3512,9 +3476,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" @@ -3590,9 +3554,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" dependencies = [ "serde", ] @@ -3626,7 +3590,7 @@ dependencies = [ "cc", "memchr", "rustc_version", - "toml 0.8.16", + "toml 0.8.19", "vswhom", "winreg 0.52.0", ] @@ -3654,9 +3618,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -3669,9 +3633,9 @@ checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" [[package]] name = "enumflags2" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", "serde", @@ -3679,13 +3643,13 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -3704,7 +3668,7 @@ version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ - "anstream 0.6.15", + "anstream", "anstyle", "env_filter", "humantime", @@ -3749,9 +3713,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3790,9 +3754,9 @@ dependencies = [ [[package]] name = "euclid" -version = "0.22.9" +version = "0.22.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787" +checksum = "e0f0eb73b934648cd7a4a61f1b15391cd95dab0b4da6e2e66c2a072c144b4a20" dependencies = [ "num-traits", ] @@ -3805,9 +3769,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.3" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", @@ -3816,9 +3780,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.1.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ad6fd685ce13acd6d9541a30f6db6567a7a24c9ffd4ba2955d29e3f22c8b27" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -3827,21 +3791,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" -dependencies = [ - "event-listener 5.1.0", + "event-listener 5.3.1", "pin-project-lite", ] @@ -3907,7 +3861,7 @@ dependencies = [ "snippet_provider", "task", "theme", - "toml 0.8.16", + "toml 0.8.19", "ui", "url", "util", @@ -3936,7 +3890,7 @@ dependencies = [ "serde_json", "theme", "tokio", - "toml 0.8.16", + "toml 0.8.19", "tree-sitter", "wasmtime", ] @@ -4004,9 +3958,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fd-lock" @@ -4015,7 +3969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" dependencies = [ "cfg-if", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -4128,22 +4082,16 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "fixedbitset" version = "0.4.2" @@ -4152,9 +4100,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -4181,7 +4129,7 @@ dependencies = [ "futures-core", "futures-sink", "nanorand", - "spin 0.9.8", + "spin", ] [[package]] @@ -4216,20 +4164,20 @@ dependencies = [ [[package]] name = "font-types" -version = "0.5.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34fd7136aca682873d859ef34494ab1a7d3f57ecd485ed40eb6437ee8c85aa29" +checksum = "8f0189ccb084f77c5523e08288d418cbaa09c451a08515678a0aa265df9a8b60" dependencies = [ "bytemuck", ] [[package]] name = "fontconfig-parser" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a595cb550439a117696039dfc69830492058211b771a2a165379f2a1a53d84d" +checksum = "c1fcfcd44ca6e90c921fee9fa665d530b21ef1327a4c1a6c5250ea44b776ada7" dependencies = [ - "roxmltree", + "roxmltree 0.20.0", ] [[package]] @@ -4273,7 +4221,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -4356,7 +4304,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" dependencies = [ "io-lifetimes 2.0.3", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -4498,11 +4446,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.0", + "fastrand 2.1.0", "futures-core", "futures-io", "parking", @@ -4517,7 +4465,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -4608,9 +4556,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -4631,12 +4579,12 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator", - "indexmap 2.2.6", + "indexmap 2.3.0", "stable_deref_trait", ] @@ -4722,8 +4670,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -4839,7 +4787,7 @@ dependencies = [ "cocoa", "collections", "core-foundation", - "core-foundation-sys 0.8.6", + "core-foundation-sys", "core-graphics", "core-text", "cosmic-text", @@ -4872,7 +4820,7 @@ dependencies = [ "postage", "profiling", "rand 0.8.5", - "raw-window-handle 0.6.0", + "raw-window-handle", "refineable", "resvg", "schemars", @@ -4884,6 +4832,7 @@ dependencies = [ "slotmap", "smallvec", "smol", + "strum", "sum_tree", "taffy", "thiserror", @@ -4938,13 +4887,13 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.9", - "indexmap 2.2.6", + "http 0.2.12", + "indexmap 2.3.0", "slab", "tokio", "tokio-util", @@ -5019,9 +4968,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ "base64 0.21.7", - "bytes 1.5.0", + "bytes 1.7.1", "headers-core", - "http 0.2.9", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -5033,7 +4982,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http 0.2.9", + "http 0.2.12", ] [[package]] @@ -5126,6 +5075,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -5151,9 +5106,9 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -5178,9 +5133,9 @@ dependencies = [ [[package]] name = "hound" -version = "3.5.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d13cdbd5dbb29f9c88095bbdc2590c9cba0d0a1269b983fef6b2cdd7e9f4db1" +checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" [[package]] name = "html5ever" @@ -5193,7 +5148,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -5222,34 +5177,57 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "fnv", "itoa", ] [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "fnv", "itoa", ] [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes 1.5.0", - "http 0.2.9", + "bytes 1.7.1", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes 1.7.1", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes 1.7.1", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -5269,7 +5247,7 @@ dependencies = [ "async-channel 1.9.0", "base64 0.13.1", "futures-lite 1.13.0", - "http 0.2.9", + "http 0.2.12", "infer", "pin-project-lite", "rand 0.7.3", @@ -5288,7 +5266,7 @@ dependencies = [ "derive_more", "futures 0.3.30", "futures-lite 1.13.0", - "http 1.0.0", + "http 1.1.0", "isahc", "log", "serde", @@ -5298,9 +5276,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -5326,13 +5304,13 @@ version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "futures-channel", "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -5351,7 +5329,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http 0.2.9", + "http 0.2.12", "hyper", "log", "rustls", @@ -5366,7 +5344,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "hyper", "native-tls", "tokio", @@ -5375,16 +5353,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", - "core-foundation-sys 0.8.6", + "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows 0.48.0", + "windows-core 0.52.0", ] [[package]] @@ -5422,7 +5400,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.7", "same-file", "walkdir", "winapi-util", @@ -5453,12 +5431,12 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" dependencies = [ "byteorder-lite", - "thiserror", + "quick-error", ] [[package]] @@ -5523,9 +5501,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -5546,13 +5524,13 @@ checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" [[package]] name = "inherent" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce243b1bfa62ffc028f1cc3b6034ec63d649f3031bc8a4fbbb004e1ac17d1f68" +checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -5622,9 +5600,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -5637,14 +5615,14 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "io-extras" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c301e73fb90e8a29e600a9f402d095765f74310d582916a952f618836a1bd1ed" +checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b" dependencies = [ "io-lifetimes 2.0.3", "windows-sys 0.52.0", @@ -5656,7 +5634,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -5697,9 +5675,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-docker" @@ -5716,7 +5694,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.52.0", ] @@ -5751,7 +5729,7 @@ dependencies = [ "encoding_rs", "event-listener 2.5.3", "futures-lite 1.13.0", - "http 0.2.9", + "http 0.2.12", "log", "mime", "once_cell", @@ -5799,30 +5777,18 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni" -version = "0.19.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" -dependencies = [ - "cesu8", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", -] - -[[package]] -name = "jni" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ "cesu8", + "cfg-if", "combine", "jni-sys", "log", "thiserror", "walkdir", + "windows-sys 0.45.0", ] [[package]] @@ -5833,9 +5799,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -5864,9 +5830,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -5893,7 +5859,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1382b16c04aeb821453d6215a3c80ba78f24c6595c5aa85653378aabe0c83e3" dependencies = [ "libc", - "libloading 0.8.0", + "libloading", ] [[package]] @@ -5970,7 +5936,7 @@ dependencies = [ "similar", "smallvec", "smol", - "strsim 0.11.1", + "strsim", "sum_tree", "task", "text", @@ -5996,6 +5962,7 @@ version = "0.1.0" dependencies = [ "anthropic", "anyhow", + "base64 0.22.1", "client", "collections", "copilot", @@ -6007,6 +5974,7 @@ dependencies = [ "google_ai", "gpui", "http_client", + "image", "inline_completion_button", "language", "log", @@ -6103,7 +6071,7 @@ dependencies = [ "task", "text", "theme", - "toml 0.8.16", + "toml 0.8.19", "tree-sitter", "tree-sitter-bash", "tree-sitter-c", @@ -6127,11 +6095,11 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -6183,22 +6151,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "winapi", -] - -[[package]] -name = "libloading" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.6", ] [[package]] @@ -6217,6 +6175,16 @@ dependencies = [ "libc", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + [[package]] name = "libsqlite3-sys" version = "0.26.0" @@ -6230,9 +6198,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -6266,7 +6234,7 @@ checksum = "f8dccda732e04fa3baf2e17cf835bfe2601c7c2edafd64417c627dabae3a8cda" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -6277,9 +6245,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "live_kit_client" @@ -6332,9 +6300,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -6359,6 +6327,15 @@ dependencies = [ "imgref", ] +[[package]] +name = "lru" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "lsp" version = "0.1.0" @@ -6396,9 +6373,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.24.0" +version = "1.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" +checksum = "958b4caa893816eea05507c20cfe47574a43d9a697138a7872990bba8a0ece68" dependencies = [ "libc", "lz4-sys", @@ -6406,9 +6383,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.4" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868" dependencies = [ "cc", "libc", @@ -6464,7 +6441,7 @@ name = "markdown_preview" version = "0.1.0" dependencies = [ "anyhow", - "async-recursion 1.0.5", + "async-recursion 1.1.1", "collections", "editor", "gpui", @@ -6532,15 +6509,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" dependencies = [ "cfg-if", - "rayon", ] [[package]] name = "md-5" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ + "cfg-if", "digest", ] @@ -6558,9 +6535,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memfd" @@ -6568,7 +6545,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] @@ -6582,9 +6559,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -6635,9 +6612,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", "simd-adler32", @@ -6667,7 +6644,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", @@ -6717,9 +6694,9 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "naga" -version = "22.0.0" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09eeccb9b50f4f7839b214aa3e08be467159506a986c18e0702170ccf720a453" +checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" dependencies = [ "arrayvec", "bit-set 0.6.0", @@ -6727,7 +6704,7 @@ dependencies = [ "cfg_aliases 0.1.1", "codespan-reporting", "hexf-parse", - "indexmap 2.2.6", + "indexmap 2.3.0", "log", "rustc-hash", "spirv", @@ -6751,16 +6728,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", ] [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -6774,15 +6750,15 @@ dependencies = [ [[package]] name = "ndk" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "jni-sys", + "log", "ndk-sys", "num_enum", - "raw-window-handle 0.5.2", "thiserror", ] @@ -6794,41 +6770,18 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-sys" -version = "0.4.1+23.1.7779620" +version = "0.5.0+25.2.9519653" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" dependencies = [ "jni-sys", ] [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", -] - -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "libc", - "memoffset", -] +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" @@ -6842,6 +6795,19 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", + "memoffset", +] + [[package]] name = "node_runtime" version = "0.1.0" @@ -6939,9 +6905,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -6953,11 +6919,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -6982,9 +6947,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -6995,17 +6960,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "num-derive" version = "0.4.2" @@ -7014,7 +6968,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -7029,19 +6983,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -7050,11 +7003,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -7062,9 +7014,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -7076,29 +7028,29 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_enum" -version = "0.5.11" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -7112,8 +7064,8 @@ dependencies = [ [[package]] name = "nvim-rs" -version = "0.6.0-pre" -source = "git+https://github.com/KillTheMule/nvim-rs?branch=master#0d2b1c884f3c39a76b5b7aac0b429f4624843954" +version = "0.8.0-pre" +source = "git+https://github.com/KillTheMule/nvim-rs?branch=master#69500bae73b8b3f02a05b7bee621a0d0e633da6c" dependencies = [ "async-trait", "futures 0.3.30", @@ -7123,6 +7075,7 @@ dependencies = [ "rmpv", "tokio", "tokio-util", + "winapi", ] [[package]] @@ -7142,7 +7095,7 @@ checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d" dependencies = [ "crc32fast", "hashbrown 0.14.5", - "indexmap 2.2.6", + "indexmap 2.3.0", "memchr", ] @@ -7157,23 +7110,23 @@ dependencies = [ [[package]] name = "oboe" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8868cc237ee02e2d9618539a23a8d228b9bb3fc2e7a5b11eed3831de77c395d0" +checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" dependencies = [ - "jni 0.20.0", + "jni", "ndk", "ndk-context", - "num-derive 0.3.3", + "num-derive", "num-traits", "oboe-sys", ] [[package]] name = "oboe-sys" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44155e7fb718d3cfddcf70690b2b51ac4412f347cd9e4fbe511abe9cd7b5f2" +checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" dependencies = [ "cc", ] @@ -7204,16 +7157,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc6ce4692fbfd044ce22ca07dcab1a30fa12432ca2aa5b1294eca50d3332a24" dependencies = [ "aes", - "async-fs 2.1.1", - "async-io 2.3.1", - "async-lock 3.3.0", + "async-fs 2.1.2", + "async-io 2.3.3", + "async-lock 3.4.0", "async-net 2.0.0", "blocking", "cbc", "cipher", "digest", "endi", - "futures-lite 2.2.0", + "futures-lite 2.3.0", "futures-util", "hkdf", "hmac", @@ -7232,9 +7185,9 @@ dependencies = [ [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "open" @@ -7284,7 +7237,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -7295,9 +7248,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.0+3.3.0" +version = "300.3.1+3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba8804a1c5765b18c4b3f907e6897ebabeedebc9830e1a0046c4a4cf44663e1" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" dependencies = [ "cc", ] @@ -7332,9 +7285,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "3.9.1" +version = "3.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a54938017eacd63036332b4ae5c8a49fc8c0c1d6d629893057e4f13609edd06" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" dependencies = [ "num-traits", ] @@ -7370,7 +7323,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -7475,7 +7428,7 @@ dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -7510,15 +7463,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -7534,9 +7487,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" @@ -7643,7 +7596,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -7659,12 +7612,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.3.0", ] [[package]] @@ -7717,7 +7670,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -7762,29 +7715,29 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -7794,12 +7747,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", - "fastrand 2.0.0", + "fastrand 2.1.0", "futures-io", ] @@ -7809,7 +7762,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der 0.7.8", + "der 0.7.9", "pkcs8 0.10.2", "spki 0.7.3", ] @@ -7830,15 +7783,15 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", + "der 0.7.9", "spki 0.7.3", ] [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plist" @@ -7847,7 +7800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.2.6", + "indexmap 2.3.0", "quick-xml 0.32.0", "serde", "time", @@ -7855,9 +7808,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -7868,15 +7821,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] @@ -7912,14 +7865,15 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.2" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.32", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] @@ -7966,9 +7920,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "precomputed-hash" @@ -8007,22 +7964,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.59", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "syn 2.0.72", ] [[package]] @@ -8083,7 +8030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" dependencies = [ "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -8140,7 +8087,7 @@ dependencies = [ "unicase", "unindent", "util", - "which 6.0.0", + "which 6.0.2", "worktree", ] @@ -8217,7 +8164,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "prost-derive", ] @@ -8227,7 +8174,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "heck 0.3.3", "itertools 0.10.5", "lazy_static", @@ -8260,7 +8207,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "prost", ] @@ -8323,9 +8270,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.10.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7" +checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ "bitflags 2.6.0", "memchr", @@ -8349,18 +8296,18 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" dependencies = [ "memchr", ] [[package]] name = "quick-xml" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" dependencies = [ "memchr", ] @@ -8456,7 +8403,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", ] [[package]] @@ -8470,9 +8417,9 @@ dependencies = [ [[package]] name = "rangemap" -version = "1.4.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977b1e897f9d764566891689e642653e5ed90c6895106acd005eb4c1d0203991" +checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" [[package]] name = "rav1e" @@ -8495,7 +8442,7 @@ dependencies = [ "maybe-rayon", "new_debug_unreachable", "noop_proc_macro", - "num-derive 0.4.2", + "num-derive", "num-traits", "once_cell", "paste", @@ -8511,30 +8458,23 @@ dependencies = [ [[package]] name = "ravif" -version = "0.11.5" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" +checksum = "5797d09f9bd33604689e87e8380df4951d4912f01b63f71205e2abd4ae25e6b6" dependencies = [ "avif-serialize", "imgref", "loop9", "quick-error", "rav1e", - "rayon", "rgb", ] [[package]] name = "raw-window-handle" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" - -[[package]] -name = "raw-window-handle" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "raw-window-metal" @@ -8545,14 +8485,14 @@ dependencies = [ "cocoa", "core-graphics", "objc", - "raw-window-handle 0.6.0", + "raw-window-handle", ] [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -8560,9 +8500,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -8570,9 +8510,9 @@ dependencies = [ [[package]] name = "read-fonts" -version = "0.19.3" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b8af39d1f23869711ad4cea5e7835a20daa987f80232f7f2a2374d648ca64d" +checksum = "8c141b9980e1150201b2a3a32879001c8f975fe313ec3df5471a9b5c79a880cd" dependencies = [ "bytemuck", "font-types", @@ -8622,15 +8562,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -8641,13 +8572,22 @@ dependencies = [ ] [[package]] -name = "redox_users" -version = "0.4.3" +name = "redox_syscall" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", + "bitflags 2.6.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom 0.2.15", + "libredox", "thiserror", ] @@ -8673,14 +8613,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -8694,26 +8634,20 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.9" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" - -[[package]] -name = "regex-automata" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] name = "regex-lite" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" [[package]] name = "regex-syntax" @@ -8723,9 +8657,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "release_channel" @@ -8779,16 +8713,16 @@ dependencies = [ "settings", "shellexpand 2.1.2", "smol", - "toml 0.8.16", + "toml 0.8.19", "util", "worktree", ] [[package]] name = "rend" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] @@ -8838,18 +8772,18 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", - "bytes 1.5.0", + "bytes 1.7.1", "encoding_rs", "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "hyper", "hyper-tls", "ipnet", @@ -8860,9 +8794,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -8900,9 +8837,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.36" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59" +checksum = "e12bc8d2f72df26a5d3178022df33720fbede0d31d82c7291662eff89836994d" dependencies = [ "bytemuck", ] @@ -8923,26 +8860,28 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", - "getrandom 0.2.10", + "cfg-if", + "getrandom 0.2.15", "libc", - "spin 0.9.8", + "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rkyv" -version = "0.7.42" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", + "bytes 1.7.1", "hashbrown 0.12.3", "ptr_meta", "rend", @@ -8954,9 +8893,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.42" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -8965,9 +8904,9 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" dependencies = [ "byteorder", "num-traits", @@ -8976,9 +8915,9 @@ dependencies = [ [[package]] name = "rmpv" -version = "1.0.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e0e0214a4a2b444ecce41a4025792fc31f77c7bb89c46d253953ea8c65701ec" +checksum = "58450723cd9ee93273ce44a20b6ec4efe17f8ed2e3631474387bfdecf18bb2a9" dependencies = [ "num-traits", "rmp", @@ -8986,9 +8925,9 @@ dependencies = [ [[package]] name = "rodio" -version = "0.17.1" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf1d4dea18dff2e9eb6dca123724f8b60ef44ad74a9ad283cdfe025df7e73fa" +checksum = "3b1bb7b48ee48471f55da122c0044fcc7600cfcc85db88240b89cb832935e611" dependencies = [ "cpal", "hound", @@ -9017,6 +8956,12 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + [[package]] name = "rpc" version = "0.1.0" @@ -9056,7 +9001,7 @@ dependencies = [ "pkcs1", "pkcs8 0.10.2", "rand_core 0.6.4", - "signature 2.1.0", + "signature 2.2.0", "spki 0.7.3", "subtle", "zeroize", @@ -9072,7 +9017,7 @@ dependencies = [ "async-dispatcher", "async-std", "base64 0.22.1", - "bytes 1.5.0", + "bytes 1.7.1", "chrono", "data-encoding", "dirs 5.0.1", @@ -9090,9 +9035,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a" +checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -9101,22 +9046,22 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4" +checksum = "6125dbc8867951125eec87294137f4e9c2c96566e61bf72c45095a7c77761478" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.59", + "syn 2.0.72", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32" +checksum = "2e5347777e9aacb56039b0e1f28785929a8a3b709e87482e7442c72e7c12529d" dependencies = [ "globset", "sha2", @@ -9131,7 +9076,7 @@ checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ "arrayvec", "borsh", - "bytes 1.5.0", + "bytes 1.7.1", "num-traits", "rand 0.8.5", "rkyv", @@ -9167,7 +9112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", - "errno 0.3.8", + "errno 0.3.9", "io-lifetimes 1.0.11", "libc", "linux-raw-sys 0.3.8", @@ -9176,15 +9121,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.6.0", - "errno 0.3.8", + "errno 0.3.9", "itoa", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.14", "once_cell", "windows-sys 0.52.0", ] @@ -9195,9 +9140,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a25c3aad9fc1424eb82c88087789a7d938e1829724f3e4043163baf0d13cfc12" dependencies = [ - "errno 0.3.8", + "errno 0.3.9", "libc", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] @@ -9226,9 +9171,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64 0.21.7", ] @@ -9245,9 +9190,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rustybuzz" @@ -9292,18 +9237,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -9314,14 +9259,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ "proc-macro2", "quote", - "serde_derive_internals", - "syn 1.0.109", + "serde_derive_internals 0.29.1", + "syn 2.0.72", ] [[package]] @@ -9368,7 +9313,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -9409,7 +9354,7 @@ dependencies = [ "proc-macro2", "quote", "sea-bae", - "syn 2.0.59", + "syn 2.0.72", "unicode-ident", ] @@ -9423,7 +9368,7 @@ dependencies = [ "chrono", "derivative", "inherent", - "ordered-float 3.9.1", + "ordered-float 3.9.2", "rust_decimal", "serde_json", "time", @@ -9506,32 +9451,32 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", - "core-foundation-sys 0.8.6", + "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ - "core-foundation-sys 0.8.6", + "core-foundation-sys", "libc", ] [[package]] name = "self_cell" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "semantic_index" @@ -9603,7 +9548,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -9617,6 +9562,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "serde_fmt" version = "1.0.3" @@ -9628,11 +9584,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "itoa", "memchr", "ryu", @@ -9641,11 +9597,11 @@ dependencies = [ [[package]] name = "serde_json_lenient" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26386958a1344003f2b2bcff51a23fbe70461a478ef29247c6c6ab2c1656f53e" +checksum = "dc61c66b53a4035fcce237ef38043f4b2f0ebf918fd0e69541a5166104065581" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "itoa", "ryu", "serde", @@ -9653,9 +9609,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", @@ -9685,13 +9641,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -9781,9 +9737,9 @@ dependencies = [ [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" @@ -9798,9 +9754,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -9847,9 +9803,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -9866,9 +9822,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", "rand_core 0.6.4", @@ -9947,9 +9903,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "skrifa" -version = "0.19.3" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab45fb68b53576a43d4fc0e9ec8ea64e29a4d2cc7f44506964cb75f288222e9" +checksum = "abea4738067b1e628c6ce28b2c216c19e9ea95715cdb332680e821c3bec2ef23" dependencies = [ "bytemuck", "read-fonts", @@ -9972,9 +9928,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "slotmap" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] @@ -10021,8 +9977,8 @@ dependencies = [ "async-fs 1.6.0", "async-io 1.13.0", "async-lock 2.8.0", - "async-net 1.7.0", - "async-process 1.7.0", + "async-net 1.8.0", + "async-process 1.8.1", "blocking", "futures-lite 1.13.0", ] @@ -10062,9 +10018,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -10082,19 +10038,13 @@ dependencies = [ [[package]] name = "spdx" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ef1a0fa1e39ac22972c8db23ff89aea700ab96aa87114e1fb55937a631a0c9" +checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" dependencies = [ "smallvec", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -10130,7 +10080,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der 0.7.9", ] [[package]] @@ -10168,11 +10118,10 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" +checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" dependencies = [ - "itertools 0.11.0", "nom", "unicode_categories", ] @@ -10200,7 +10149,7 @@ dependencies = [ "atoi", "bigdecimal", "byteorder", - "bytes 1.5.0", + "bytes 1.7.1", "chrono", "crc", "crossbeam-queue", @@ -10214,7 +10163,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.2.6", + "indexmap 2.3.0", "log", "memchr", "once_cell", @@ -10288,7 +10237,7 @@ dependencies = [ "bigdecimal", "bitflags 2.6.0", "byteorder", - "bytes 1.5.0", + "bytes 1.7.1", "chrono", "crc", "digest", @@ -10480,21 +10429,15 @@ dependencies = [ [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -10512,22 +10455,22 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" @@ -10583,15 +10526,15 @@ dependencies = [ [[package]] name = "sval" -version = "2.8.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d11eec9fbe2bc8bc71e7349f0e7534db9a96d961fb9f302574275b7880ad06" +checksum = "53eb957fbc79a55306d5d25d87daf3627bc3800681491cda0709eef36c748bfe" [[package]] name = "sval_buffer" -version = "2.8.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7451f69a93c5baf2653d5aa8bb4178934337f16c22830a50b06b386f72d761" +checksum = "96e860aef60e9cbf37888d4953a13445abf523c534640d1f6174d310917c410d" dependencies = [ "sval", "sval_ref", @@ -10599,18 +10542,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.8.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f5a2cc12b4da2adfb59d5eedfd9b174a23cc3fae84cec71dcbcd9302068f5" +checksum = "ea3f2b07929a1127d204ed7cb3905049381708245727680e9139dac317ed556f" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.8.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f578b2301341e246d00b35957f2952c4ec554ad9c7cfaee10bc86bc92896578" +checksum = "c4e188677497de274a1367c4bda15bd2296de4070d91729aac8f0a09c1abf64d" dependencies = [ "itoa", "ryu", @@ -10619,9 +10562,9 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.8.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8346c00f5dc6efe18bea8d13c1f7ca4f112b20803434bf3657ac17c0f74cbc4b" +checksum = "32f456c07dae652744781f2245d5e3b78e6a9ebad70790ac11eb15dbdbce5282" dependencies = [ "itoa", "ryu", @@ -10629,37 +10572,47 @@ dependencies = [ ] [[package]] -name = "sval_ref" -version = "2.8.0" +name = "sval_nested" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6617cc89952f792aebc0f4a1a76bc51e80c70b18c491bd52215c7989c4c3dd06" +checksum = "886feb24709f0476baaebbf9ac10671a50163caa7e439d7a7beb7f6d81d0a6fb" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be2e7fc517d778f44f8cb64140afa36010999565528d48985f55e64d45f369ce" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.8.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3d1e59f023341d9af75d86f3bc148a6704f3f831eef0dd90bbe9cb445fa024" +checksum = "79bf66549a997ff35cd2114a27ac4b0c2843280f2cfa84b240d169ecaa0add46" dependencies = [ "serde", "sval", - "sval_buffer", - "sval_fmt", + "sval_nested", ] [[package]] name = "svg_fmt" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2" +checksum = "20e16a0f46cf5fd675563ef54f26e83e20f2366bcf027bcb3cc3ed2b98aaf2ca" [[package]] name = "svgtypes" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca9a891c9c70da8139ac9d8e8ea36a210fa21bb50eccd75d4a9561c83e87f" +checksum = "fae3064df9b89391c9a76a0425a69d124aee9c5c28455204709e72c39868a43c" dependencies = [ "kurbo", "siphasher 1.0.1", @@ -10667,9 +10620,9 @@ dependencies = [ [[package]] name = "swash" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d7773d67fe3373048cf840bfcc54ec3207cfc1e95c526b287ef2eb5eff9faf6" +checksum = "93cdc334a50fcc2aa3f04761af3b28196280a6aaadb1ef11215c478ae32615ac" dependencies = [ "skrifa", "yazi", @@ -10689,9 +10642,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.59" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -10707,7 +10660,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -10736,12 +10689,12 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.7" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c385888ef380a852a16209afc8cfad22795dd8873d69c9a14d2e2088f118d18" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" dependencies = [ "cfg-if", - "core-foundation-sys 0.8.6", + "core-foundation-sys", "libc", "ntapi", "once_cell", @@ -10749,6 +10702,27 @@ dependencies = [ "windows 0.52.0", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -10758,22 +10732,22 @@ dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml 0.8.16", + "toml 0.8.19", "version-compare", ] [[package]] name = "system-interface" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aef1f9d4c1dbdd1cb3a63be9efd2f04d8ddbc919d46112982c76818ffc2f1a7" +checksum = "b858526d22750088a9b3cf2e3c2aacebd5377f13adeec02860c30d09113010a6" dependencies = [ "bitflags 2.6.0", "cap-fs-ext", "cap-std", "fd-lock", "io-lifetimes 2.0.3", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.52.0", "winx", ] @@ -10802,9 +10776,9 @@ dependencies = [ [[package]] name = "taffy" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2e140b328c6cb5e744bb2c65910b47df86b239afc793ee2c52262569cf9225" +checksum = "9ec17858c2d465b2f734b798b920818a974faf0babb15d7fef81818a4b2d16f1" dependencies = [ "arrayvec", "grid", @@ -10827,9 +10801,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.13" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "task" @@ -10884,15 +10858,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand 2.0.0", - "redox_syscall 0.4.1", - "rustix 0.38.32", - "windows-sys 0.52.0", + "fastrand 2.1.0", + "once_cell", + "rustix 0.38.34", + "windows-sys 0.59.0", ] [[package]] @@ -11064,29 +11038,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -11156,7 +11130,7 @@ name = "time_format" version = "0.1.0" dependencies = [ "core-foundation", - "core-foundation-sys 0.8.6", + "core-foundation-sys", "sys-locale", "time", ] @@ -11272,21 +11246,20 @@ dependencies = [ [[package]] name = "tokio" -version = "1.37.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", - "bytes 1.5.0", + "bytes 1.7.1", "libc", - "mio 0.8.11", - "num_cpus", + "mio 1.0.1", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -11302,13 +11275,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -11333,9 +11306,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -11356,17 +11329,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ - "bytes 1.5.0", + "bytes 1.7.1", "futures-core", "futures-io", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -11392,21 +11364,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.17", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -11417,11 +11389,11 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.5.15", + "winnow 0.5.40", ] [[package]] @@ -11430,22 +11402,22 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "toml_datetime", - "winnow 0.5.15", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.17" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.1", + "winnow 0.6.18", ] [[package]] @@ -11471,11 +11443,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" dependencies = [ "bitflags 1.3.2", - "bytes 1.5.0", + "bytes 1.7.1", "futures-core", "futures-util", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "pin-project-lite", "tower-layer", @@ -11489,11 +11461,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ "bitflags 2.6.0", - "bytes 1.5.0", + "bytes 1.7.1", "futures-core", "futures-util", - "http 0.2.9", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "pin-project-lite", "tower-layer", @@ -11533,7 +11505,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -11812,9 +11784,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ttf-parser" @@ -11829,9 +11801,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", - "bytes 1.5.0", + "bytes 1.7.1", "data-encoding", - "http 0.2.9", + "http 0.2.12", "httparse", "log", "native-tls", @@ -11955,21 +11927,21 @@ checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" [[package]] name = "unicode-script" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc" +checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd" [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -12026,7 +11998,7 @@ dependencies = [ "kurbo", "log", "pico-args", - "roxmltree", + "roxmltree 0.19.0", "simplecss", "siphasher 1.0.1", "strict-num", @@ -12043,9 +12015,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "util" @@ -12077,7 +12049,7 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.15", "serde", "sha1_smol", ] @@ -12163,9 +12135,9 @@ checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vim" @@ -12255,9 +12227,9 @@ dependencies = [ [[package]] name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" dependencies = [ "proc-macro2", "quote", @@ -12327,15 +12299,15 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -12361,7 +12333,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -12397,7 +12369,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fd83062c17b9f4985d438603cde0a5e8c5c8198201a6937f778b607924c7da2" dependencies = [ "anyhow", - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_derive", "serde_json", @@ -12413,7 +12385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" dependencies = [ "bitflags 2.6.0", - "indexmap 2.2.6", + "indexmap 2.3.0", "semver", ] @@ -12426,7 +12398,7 @@ dependencies = [ "ahash 0.8.11", "bitflags 2.6.0", "hashbrown 0.14.5", - "indexmap 2.2.6", + "indexmap 2.3.0", "semver", ] @@ -12453,7 +12425,7 @@ dependencies = [ "cfg-if", "encoding_rs", "hashbrown 0.14.5", - "indexmap 2.2.6", + "indexmap 2.3.0", "libc", "libm", "log", @@ -12465,7 +12437,7 @@ dependencies = [ "paste", "postcard", "psm", - "rustix 0.38.32", + "rustix 0.38.34", "semver", "serde", "serde_derive", @@ -12528,7 +12500,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "wasmtime-component-util", "wasmtime-wit-bindgen", "wit-parser 0.207.0", @@ -12554,7 +12526,7 @@ dependencies = [ "cranelift-frontend", "cranelift-native", "cranelift-wasm", - "gimli 0.28.0", + "gimli 0.28.1", "log", "object 0.33.0", "target-lexicon", @@ -12573,8 +12545,8 @@ dependencies = [ "anyhow", "cpp_demangle", "cranelift-entity", - "gimli 0.28.0", - "indexmap 2.2.6", + "gimli 0.28.1", + "indexmap 2.3.0", "log", "object 0.33.0", "postcard", @@ -12598,7 +12570,7 @@ dependencies = [ "anyhow", "cc", "cfg-if", - "rustix 0.38.32", + "rustix 0.38.34", "wasmtime-asm-macros", "wasmtime-versioned-export-macros", "windows-sys 0.52.0", @@ -12643,7 +12615,7 @@ checksum = "d4cedc5bfef3db2a85522ee38564b47ef3b7fc7c92e94cacbce99808e63cdd47" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -12655,7 +12627,7 @@ dependencies = [ "anyhow", "async-trait", "bitflags 2.6.0", - "bytes 1.5.0", + "bytes 1.7.1", "cap-fs-ext", "cap-net-ext", "cap-rand", @@ -12666,7 +12638,7 @@ dependencies = [ "io-extras", "io-lifetimes 2.0.3", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", "system-interface", "thiserror", "tokio", @@ -12685,7 +12657,7 @@ checksum = "97b27054fed6be4f3800aba5766f7ef435d4220ce290788f021a08d4fa573108" dependencies = [ "anyhow", "cranelift-codegen", - "gimli 0.28.0", + "gimli 0.28.1", "object 0.33.0", "target-lexicon", "wasmparser 0.207.0", @@ -12702,7 +12674,7 @@ checksum = "c936a52ce69c28de2aa3b5fb4f2dbbb2966df304f04cccb7aca4ba56d915fda0" dependencies = [ "anyhow", "heck 0.4.1", - "indexmap 2.2.6", + "indexmap 2.3.0", "wit-parser 0.207.0", ] @@ -12717,13 +12689,13 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.32", + "rustix 0.38.34", "scoped-tls", "smallvec", "wayland-sys", @@ -12731,23 +12703,23 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.2" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" dependencies = [ "bitflags 2.6.0", - "rustix 0.38.32", + "rustix 0.38.34", "wayland-backend", "wayland-scanner", ] [[package]] name = "wayland-cursor" -version = "0.31.1" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" +checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", "wayland-client", "xcursor", ] @@ -12779,20 +12751,20 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" dependencies = [ "proc-macro2", - "quick-xml 0.31.0", + "quick-xml 0.34.0", "quote", ] [[package]] name = "wayland-sys" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" dependencies = [ "dlib", "log", @@ -12802,9 +12774,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -12859,20 +12831,19 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] name = "which" -version = "6.0.0" +version = "6.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c" +checksum = "3d9c5ed668ee1f17edb3b627225343d210006a90bb1e3745ce1f30b1fb115075" dependencies = [ "either", "home", - "once_cell", - "rustix 0.38.32", - "windows-sys 0.52.0", + "rustix 0.38.34", + "winsafe", ] [[package]] @@ -12911,7 +12882,7 @@ dependencies = [ "proc-macro2", "quote", "shellexpand 2.1.2", - "syn 2.0.59", + "syn 2.0.72", "witx", ] @@ -12923,7 +12894,7 @@ checksum = "0b47d2b4442ce93106dba5d1a9c59d5f85b5732878bb3d0598d3c93c0d01b16b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "wiggle-generate", ] @@ -12945,11 +12916,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -12966,7 +12937,7 @@ checksum = "1dc69899ccb2da7daa4df31426dcfd284b104d1a85e1dae35806df0c46187f87" dependencies = [ "anyhow", "cranelift-codegen", - "gimli 0.28.0", + "gimli 0.28.1", "regalloc2", "smallvec", "target-lexicon", @@ -12975,15 +12946,6 @@ dependencies = [ "wasmtime-environ", ] -[[package]] -name = "windows" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows" version = "0.48.0" @@ -13003,6 +12965,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core 0.54.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.58.0" @@ -13022,6 +12994,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.58.0" @@ -13030,7 +13012,7 @@ checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ "windows-implement", "windows-interface", - "windows-result", + "windows-result 0.2.0", "windows-strings", "windows-targets 0.52.6", ] @@ -13043,7 +13025,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -13054,7 +13036,16 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", +] + +[[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]] @@ -13072,7 +13063,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-targets 0.52.6", ] @@ -13103,6 +13094,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -13283,18 +13283,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.1" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d90f4e0f530c4c69f62b80d839e9ef3855edc9cba471a160c4d692deed62b401" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -13329,6 +13329,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + [[package]] name = "winx" version = "0.36.3" @@ -13383,7 +13389,7 @@ checksum = "d8a39a15d1ae2077688213611209849cad40e9e5cccf6e61951a425850677ff3" dependencies = [ "anyhow", "heck 0.4.1", - "indexmap 2.2.6", + "indexmap 2.3.0", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -13398,7 +13404,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -13411,7 +13417,7 @@ checksum = "421c0c848a0660a8c22e2fd217929a0191f14476b68962afd2af89fd22e39825" dependencies = [ "anyhow", "bitflags 2.6.0", - "indexmap 2.2.6", + "indexmap 2.3.0", "log", "serde", "serde_derive", @@ -13430,7 +13436,7 @@ checksum = "196d3ecfc4b759a8573bf86a9b3f8996b304b3732e4c7de81655f875f6efdca6" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.3.0", "log", "semver", "serde", @@ -13448,7 +13454,7 @@ checksum = "78c83dab33a9618d86cfe3563cc864deffd08c17efc5db31a3b7cd1edeffe6e1" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.3.0", "log", "semver", "serde", @@ -13476,7 +13482,7 @@ version = "0.1.0" dependencies = [ "any_vec", "anyhow", - "async-recursion 1.0.5", + "async-recursion 1.1.1", "bincode", "call", "client", @@ -13568,22 +13574,22 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", - "rustix 0.38.32", + "rustix 0.38.34", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" [[package]] name = "xattr" @@ -13596,18 +13602,18 @@ dependencies = [ [[package]] name = "xcursor" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" +checksum = "d491ee231a51ae64a5b762114c3ac2104b967aadba1de45c86ca42cf051513b7" [[package]] name = "xdg-home" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -13652,15 +13658,15 @@ dependencies = [ [[package]] name = "xkeysym" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml5ever" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c376f76ed09df711203e20c3ef5ce556f0166fa03d39590016c0fd625437fad" +checksum = "9bbb26405d8e919bc1547a5aa9abc95cbfa438f04844f5fdd9dc7596b748bf69" dependencies = [ "log", "mac", @@ -13669,9 +13675,9 @@ dependencies = [ [[package]] name = "xmlparser" -version = "0.13.5" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "xmlwriter" @@ -13714,28 +13720,27 @@ dependencies = [ [[package]] name = "zbus" -version = "4.0.1" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" dependencies = [ "async-broadcast", "async-executor", - "async-fs 2.1.1", - "async-io 2.3.1", - "async-lock 3.3.0", - "async-process 2.1.0", - "async-recursion 1.0.5", + "async-fs 2.1.2", + "async-io 2.3.3", + "async-lock 3.4.0", + "async-process 2.2.3", + "async-recursion 1.1.1", "async-task", "async-trait", "blocking", - "derivative", "enumflags2", - "event-listener 5.1.0", + "event-listener 5.3.1", "futures-core", "futures-sink", "futures-util", "hex", - "nix 0.27.1", + "nix 0.29.0", "ordered-stream", "rand 0.8.5", "serde", @@ -13753,15 +13758,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "4.0.1" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a3e850ff1e7217a3b7a07eba90d37fe9bb9e89a310f718afcde5885ca9b6d7" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", - "regex", - "syn 1.0.109", + "syn 2.0.72", "zvariant_utils", ] @@ -14116,29 +14120,30 @@ checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -14151,7 +14156,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -14164,7 +14169,7 @@ dependencies = [ "async-std", "async-trait", "asynchronous-codec", - "bytes 1.5.0", + "bytes 1.7.1", "crossbeam-queue", "dashmap 5.5.3", "futures-channel", @@ -14202,12 +14207,11 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", - "libc", "pkg-config", ] @@ -14228,18 +14232,18 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" dependencies = [ "zune-core", ] [[package]] name = "zvariant" -version = "4.0.2" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b3ca6db667bfada0f1ebfc94b2b1759ba25472ee5373d4551bb892616389a" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" dependencies = [ "endi", "enumflags2", @@ -14251,24 +14255,24 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "4.0.2" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a4b236063316163b69039f77ce3117accb41a09567fd24c168e43491e521bc" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "1.1.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bedb16a193cc12451873fee2a1bc6550225acece0e36f333e68326c73c8172" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] diff --git a/crates/assistant/Cargo.toml b/crates/assistant/Cargo.toml index 6fcf382873..ba39e741e9 100644 --- a/crates/assistant/Cargo.toml +++ b/crates/assistant/Cargo.toml @@ -66,6 +66,7 @@ semantic_index.workspace = true serde.workspace = true serde_json.workspace = true settings.workspace = true +smallvec.workspace = true smol.workspace = true telemetry_events.workspace = true terminal.workspace = true diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index b904e102e3..808ee84849 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -34,12 +34,12 @@ use editor::{ use editor::{display_map::CreaseId, FoldPlaceholder}; use fs::Fs; use gpui::{ - canvas, div, percentage, point, pulsating_between, Action, Animation, AnimationExt, AnyElement, - AnyView, AppContext, AsyncWindowContext, ClipboardItem, Context as _, DismissEvent, Empty, - Entity, EntityId, EventEmitter, FocusHandle, FocusableView, FontWeight, InteractiveElement, - IntoElement, Model, ParentElement, Pixels, ReadGlobal, Render, SharedString, - StatefulInteractiveElement, Styled, Subscription, Task, Transformation, UpdateGlobal, View, - ViewContext, VisualContext, WeakView, WindowContext, + canvas, div, img, percentage, point, pulsating_between, size, Action, Animation, AnimationExt, + AnyElement, AnyView, AppContext, AsyncWindowContext, ClipboardEntry, ClipboardItem, + Context as _, DismissEvent, Empty, Entity, EntityId, EventEmitter, FocusHandle, FocusableView, + FontWeight, InteractiveElement, IntoElement, Model, ParentElement, Pixels, ReadGlobal, Render, + RenderImage, SharedString, Size, StatefulInteractiveElement, Styled, Subscription, Task, + Transformation, UpdateGlobal, View, VisualContext, WeakView, WindowContext, }; use indexed_docs::IndexedDocsStore; use language::{ @@ -1715,6 +1715,7 @@ pub struct ContextEditor { lsp_adapter_delegate: Option>, editor: View, blocks: HashSet, + image_blocks: HashSet, scroll_position: Option, remote_id: Option, pending_slash_command_creases: HashMap, CreaseId>, @@ -1773,6 +1774,7 @@ impl ContextEditor { editor, lsp_adapter_delegate, blocks: Default::default(), + image_blocks: Default::default(), scroll_position: None, remote_id: None, fs, @@ -1789,6 +1791,7 @@ impl ContextEditor { show_accept_terms: false, }; this.update_message_headers(cx); + this.update_image_blocks(cx); this.insert_slash_command_output_sections(sections, cx); this } @@ -2161,6 +2164,7 @@ impl ContextEditor { match event { ContextEvent::MessagesEdited => { self.update_message_headers(cx); + self.update_image_blocks(cx); self.context.update(cx, |context, cx| { context.save(Some(Duration::from_millis(500)), self.fs.clone(), cx); }); @@ -3305,7 +3309,7 @@ impl ContextEditor { } if spanned_messages > 1 { - cx.write_to_clipboard(ClipboardItem::new(copied_text)); + cx.write_to_clipboard(ClipboardItem::new_string(copied_text)); return; } } @@ -3313,6 +3317,102 @@ impl ContextEditor { cx.propagate(); } + fn paste(&mut self, _: &editor::actions::Paste, cx: &mut ViewContext) { + let images = if let Some(item) = cx.read_from_clipboard() { + item.into_entries() + .filter_map(|entry| { + if let ClipboardEntry::Image(image) = entry { + Some(image) + } else { + None + } + }) + .collect() + } else { + Vec::new() + }; + + if images.is_empty() { + // If we didn't find any valid image data to paste, propagate to let normal pasting happen. + cx.propagate(); + } else { + let mut image_positions = Vec::new(); + self.editor.update(cx, |editor, cx| { + editor.transact(cx, |editor, cx| { + let edits = editor + .selections + .all::(cx) + .into_iter() + .map(|selection| (selection.start..selection.end, "\n")); + editor.edit(edits, cx); + + let snapshot = editor.buffer().read(cx).snapshot(cx); + for selection in editor.selections.all::(cx) { + image_positions.push(snapshot.anchor_before(selection.end)); + } + }); + }); + + self.context.update(cx, |context, cx| { + for image in images { + let image_id = image.id(); + context.insert_image(image, cx); + for image_position in image_positions.iter() { + context.insert_image_anchor(image_id, image_position.text_anchor, cx); + } + } + }); + } + } + + fn update_image_blocks(&mut self, cx: &mut ViewContext) { + self.editor.update(cx, |editor, cx| { + let buffer = editor.buffer().read(cx).snapshot(cx); + let excerpt_id = *buffer.as_singleton().unwrap().0; + let old_blocks = std::mem::take(&mut self.image_blocks); + let new_blocks = self + .context + .read(cx) + .images(cx) + .filter_map(|image| { + const MAX_HEIGHT_IN_LINES: u32 = 8; + let anchor = buffer.anchor_in_excerpt(excerpt_id, image.anchor).unwrap(); + let image = image.render_image.clone(); + anchor.is_valid(&buffer).then(|| BlockProperties { + position: anchor, + height: MAX_HEIGHT_IN_LINES, + style: BlockStyle::Sticky, + render: Box::new(move |cx| { + let image_size = size_for_image( + &image, + size( + cx.max_width - cx.gutter_dimensions.full_width(), + MAX_HEIGHT_IN_LINES as f32 * cx.line_height, + ), + ); + h_flex() + .pl(cx.gutter_dimensions.full_width()) + .child( + img(image.clone()) + .object_fit(gpui::ObjectFit::ScaleDown) + .w(image_size.width) + .h(image_size.height), + ) + .into_any_element() + }), + + disposition: BlockDisposition::Above, + priority: 0, + }) + }) + .collect::>(); + + editor.remove_blocks(old_blocks, None, cx); + let ids = editor.insert_blocks(new_blocks, None, cx); + self.image_blocks = HashSet::from_iter(ids); + }); + } + fn split(&mut self, _: &Split, cx: &mut ViewContext) { self.context.update(cx, |context, cx| { let selections = self.editor.read(cx).selections.disjoint_anchors(); @@ -3529,6 +3629,7 @@ impl Render for ContextEditor { .capture_action(cx.listener(ContextEditor::cancel)) .capture_action(cx.listener(ContextEditor::save)) .capture_action(cx.listener(ContextEditor::copy)) + .capture_action(cx.listener(ContextEditor::paste)) .capture_action(cx.listener(ContextEditor::cycle_message_role)) .capture_action(cx.listener(ContextEditor::confirm_command)) .on_action(cx.listener(ContextEditor::assist)) @@ -4556,6 +4657,30 @@ fn token_state(context: &Model, cx: &AppContext) -> Option Some(token_state) } +fn size_for_image(data: &RenderImage, max_size: Size) -> Size { + let image_size = data + .size(0) + .map(|dimension| Pixels::from(u32::from(dimension))); + let image_ratio = image_size.width / image_size.height; + let bounds_ratio = max_size.width / max_size.height; + + if image_size.width > max_size.width || image_size.height > max_size.height { + if bounds_ratio > image_ratio { + size( + image_size.width * (max_size.height / image_size.height), + max_size.height, + ) + } else { + size( + max_size.width, + image_size.height * (max_size.width / image_size.width), + ) + } + } else { + size(image_size.width, image_size.height) + } +} + enum ConfigurationError { NoProvider, ProviderNotAuthenticated, diff --git a/crates/assistant/src/context.rs b/crates/assistant/src/context.rs index 9aa2c257ce..3aa0629848 100644 --- a/crates/assistant/src/context.rs +++ b/crates/assistant/src/context.rs @@ -13,27 +13,31 @@ use editor::Editor; use fs::{Fs, RemoveOptions}; use futures::{ future::{self, Shared}, + stream::FuturesUnordered, FutureExt, StreamExt, }; use gpui::{ - AppContext, Context as _, EventEmitter, Model, ModelContext, Subscription, Task, UpdateGlobal, - View, WeakView, + AppContext, Context as _, EventEmitter, Image, Model, ModelContext, RenderImage, Subscription, + Task, UpdateGlobal, View, WeakView, }; + use language::{ AnchorRangeExt, Bias, Buffer, BufferSnapshot, LanguageRegistry, OffsetRangeExt, ParseStatus, Point, ToOffset, }; use language_model::{ - LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage, LanguageModelTool, - Role, + LanguageModelImage, LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage, + LanguageModelTool, Role, }; use open_ai::Model as OpenAiModel; -use paths::contexts_dir; +use paths::{context_images_dir, contexts_dir}; use project::Project; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use smallvec::SmallVec; use std::{ cmp::{self, Ordering}, + collections::hash_map, fmt::Debug, iter, mem, ops::Range, @@ -319,8 +323,23 @@ pub struct MessageMetadata { timestamp: clock::Lamport, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug)] +pub struct MessageImage { + image_id: u64, + image: Shared>>, +} + +impl PartialEq for MessageImage { + fn eq(&self, other: &Self) -> bool { + self.image_id == other.image_id + } +} + +impl Eq for MessageImage {} + +#[derive(Clone, Debug)] pub struct Message { + pub image_offsets: SmallVec<[(usize, MessageImage); 1]>, pub offset_range: Range, pub index_range: Range, pub id: MessageId, @@ -331,13 +350,55 @@ pub struct Message { impl Message { fn to_request_message(&self, buffer: &Buffer) -> LanguageModelRequestMessage { + let mut content = Vec::new(); + + let mut range_start = self.offset_range.start; + for (image_offset, message_image) in self.image_offsets.iter() { + if *image_offset != range_start { + content.push( + buffer + .text_for_range(range_start..*image_offset) + .collect::() + .into(), + ) + } + + if let Some(image) = message_image.image.clone().now_or_never().flatten() { + content.push(language_model::MessageContent::Image(image)); + } + + range_start = *image_offset; + } + if range_start != self.offset_range.end { + content.push( + buffer + .text_for_range(range_start..self.offset_range.end) + .collect::() + .into(), + ) + } + LanguageModelRequestMessage { role: self.role, - content: buffer.text_for_range(self.offset_range.clone()).collect(), + content, } } } +#[derive(Clone, Debug)] +pub struct ImageAnchor { + pub anchor: language::Anchor, + pub image_id: u64, + pub render_image: Arc, + pub image: Shared>>, +} + +impl PartialEq for ImageAnchor { + fn eq(&self, other: &Self) -> bool { + self.image_id == other.image_id + } +} + struct PendingCompletion { id: usize, _task: Task<()>, @@ -605,6 +666,8 @@ pub struct Context { finished_slash_commands: HashSet, slash_command_output_sections: Vec>, message_anchors: Vec, + images: HashMap, Shared>>)>, + image_anchors: Vec, messages_metadata: HashMap, summary: Option, pending_summary: Task>, @@ -677,6 +740,8 @@ impl Context { pending_ops: Vec::new(), operations: Vec::new(), message_anchors: Default::default(), + image_anchors: Default::default(), + images: Default::default(), messages_metadata: Default::default(), pending_slash_commands: Vec::new(), finished_slash_commands: HashSet::default(), @@ -736,6 +801,11 @@ impl Context { id: message.id, start: message.offset_range.start, metadata: self.messages_metadata[&message.id].clone(), + image_offsets: message + .image_offsets + .iter() + .map(|image_offset| (image_offset.0, image_offset.1.image_id)) + .collect(), }) .collect(), summary: self @@ -1339,7 +1409,7 @@ impl Context { request.messages.push(LanguageModelRequestMessage { role: Role::User, - content: prompt, + content: vec![prompt.into()], }); // Invoke the model to get its edit suggestions for this workflow step. @@ -1743,13 +1813,15 @@ impl Context { } pub fn to_completion_request(&self, cx: &AppContext) -> LanguageModelRequest { - let messages = self + let buffer = self.buffer.read(cx); + let request_messages = self .messages(cx) - .filter(|message| matches!(message.status, MessageStatus::Done)) - .map(|message| message.to_request_message(self.buffer.read(cx))); + .filter(|message| message.status == MessageStatus::Done) + .map(|message| message.to_request_message(&buffer)) + .collect(); LanguageModelRequest { - messages: messages.collect(), + messages: request_messages, stop: vec![], temperature: 1.0, } @@ -1847,6 +1919,55 @@ impl Context { } } + pub fn insert_image(&mut self, image: Image, cx: &mut ModelContext) -> Option<()> { + if let hash_map::Entry::Vacant(entry) = self.images.entry(image.id()) { + entry.insert(( + image.to_image_data(cx).log_err()?, + LanguageModelImage::from_image(image, cx).shared(), + )); + } + + Some(()) + } + + pub fn insert_image_anchor( + &mut self, + image_id: u64, + anchor: language::Anchor, + cx: &mut ModelContext, + ) -> bool { + cx.emit(ContextEvent::MessagesEdited); + + let buffer = self.buffer.read(cx); + let insertion_ix = match self + .image_anchors + .binary_search_by(|existing_anchor| anchor.cmp(&existing_anchor.anchor, buffer)) + { + Ok(ix) => ix, + Err(ix) => ix, + }; + + if let Some((render_image, image)) = self.images.get(&image_id) { + self.image_anchors.insert( + insertion_ix, + ImageAnchor { + anchor, + image_id, + image: image.clone(), + render_image: render_image.clone(), + }, + ); + + true + } else { + false + } + } + + pub fn images<'a>(&'a self, _cx: &'a AppContext) -> impl 'a + Iterator { + self.image_anchors.iter().cloned() + } + pub fn split_message( &mut self, range: Range, @@ -1865,7 +1986,10 @@ impl Context { let mut edited_buffer = false; let mut suffix_start = None; - if range.start > message.offset_range.start && range.end < message.offset_range.end - 1 + + // TODO: why did this start panicking? + if range.start > message.offset_range.start + && range.end < message.offset_range.end.saturating_sub(1) { if self.buffer.read(cx).chars_at(range.end).next() == Some('\n') { suffix_start = Some(range.end + 1); @@ -2007,7 +2131,9 @@ impl Context { .map(|message| message.to_request_message(self.buffer.read(cx))) .chain(Some(LanguageModelRequestMessage { role: Role::User, - content: "Summarize the context into a short title without punctuation.".into(), + content: vec![ + "Summarize the context into a short title without punctuation.".into(), + ], })); let request = LanguageModelRequest { messages: messages.collect(), @@ -2109,25 +2235,55 @@ impl Context { pub fn messages<'a>(&'a self, cx: &'a AppContext) -> impl 'a + Iterator { let buffer = self.buffer.read(cx); - let mut message_anchors = self.message_anchors.iter().enumerate().peekable(); + let messages = self.message_anchors.iter().enumerate(); + let images = self.image_anchors.iter(); + + Self::messages_from_iters(buffer, &self.messages_metadata, messages, images) + } + + pub fn messages_from_iters<'a>( + buffer: &'a Buffer, + metadata: &'a HashMap, + messages: impl Iterator + 'a, + images: impl Iterator + 'a, + ) -> impl 'a + Iterator { + let mut messages = messages.peekable(); + let mut images = images.peekable(); + iter::from_fn(move || { - if let Some((start_ix, message_anchor)) = message_anchors.next() { - let metadata = self.messages_metadata.get(&message_anchor.id)?; + if let Some((start_ix, message_anchor)) = messages.next() { + let metadata = metadata.get(&message_anchor.id)?; + let message_start = message_anchor.start.to_offset(buffer); let mut message_end = None; let mut end_ix = start_ix; - while let Some((_, next_message)) = message_anchors.peek() { + while let Some((_, next_message)) = messages.peek() { if next_message.start.is_valid(buffer) { message_end = Some(next_message.start); break; } else { end_ix += 1; - message_anchors.next(); + messages.next(); + } + } + let message_end_anchor = message_end.unwrap_or(language::Anchor::MAX); + let message_end = message_end_anchor.to_offset(buffer); + + let mut image_offsets = SmallVec::new(); + while let Some(image_anchor) = images.peek() { + if image_anchor.anchor.cmp(&message_end_anchor, buffer).is_lt() { + image_offsets.push(( + image_anchor.anchor.to_offset(buffer), + MessageImage { + image_id: image_anchor.image_id, + image: image_anchor.image.clone(), + }, + )); + images.next(); + } else { + break; } } - let message_end = message_end - .unwrap_or(language::Anchor::MAX) - .to_offset(buffer); return Some(Message { index_range: start_ix..end_ix, @@ -2136,6 +2292,7 @@ impl Context { anchor: message_anchor.start, role: metadata.role, status: metadata.status.clone(), + image_offsets, }); } None @@ -2173,6 +2330,9 @@ impl Context { })?; if let Some(summary) = summary { + this.read_with(&cx, |this, cx| this.serialize_images(fs.clone(), cx))? + .await; + let context = this.read_with(&cx, |this, cx| this.serialize(cx))?; let mut discriminant = 1; let mut new_path; @@ -2212,6 +2372,45 @@ impl Context { }); } + pub fn serialize_images(&self, fs: Arc, cx: &AppContext) -> Task<()> { + let mut images_to_save = self + .images + .iter() + .map(|(id, (_, llm_image))| { + let fs = fs.clone(); + let llm_image = llm_image.clone(); + let id = *id; + async move { + if let Some(llm_image) = llm_image.await { + let path: PathBuf = + context_images_dir().join(&format!("{}.png.base64", id)); + if fs + .metadata(path.as_path()) + .await + .log_err() + .flatten() + .is_none() + { + fs.atomic_write(path, llm_image.source.to_string()) + .await + .log_err(); + } + } + } + }) + .collect::>(); + cx.background_executor().spawn(async move { + if fs + .create_dir(context_images_dir().as_ref()) + .await + .log_err() + .is_some() + { + while let Some(_) = images_to_save.next().await {} + } + }) + } + pub(crate) fn custom_summary(&mut self, custom_summary: String, cx: &mut ModelContext) { let timestamp = self.next_timestamp(); let summary = self.summary.get_or_insert(ContextSummary::default()); @@ -2265,6 +2464,9 @@ pub struct SavedMessage { pub id: MessageId, pub start: usize, pub metadata: MessageMetadata, + #[serde(default)] + // This is defaulted for backwards compatibility with JSON files created before August 2024. We didn't always have this field. + pub image_offsets: Vec<(usize, u64)>, } #[derive(Serialize, Deserialize)] @@ -2447,6 +2649,7 @@ impl SavedContextV0_3_0 { status: metadata.status.clone(), timestamp, }, + image_offsets: Vec::new(), }) }) .collect(), diff --git a/crates/assistant/src/inline_assistant.rs b/crates/assistant/src/inline_assistant.rs index b26abb84f0..bda92f25d5 100644 --- a/crates/assistant/src/inline_assistant.rs +++ b/crates/assistant/src/inline_assistant.rs @@ -2377,7 +2377,7 @@ impl Codegen { messages.push(LanguageModelRequestMessage { role: Role::User, - content: prompt, + content: vec![prompt.into()], }); Ok(LanguageModelRequest { diff --git a/crates/assistant/src/prompt_library.rs b/crates/assistant/src/prompt_library.rs index a0b25bf679..7cde30a805 100644 --- a/crates/assistant/src/prompt_library.rs +++ b/crates/assistant/src/prompt_library.rs @@ -775,7 +775,7 @@ impl PromptLibrary { LanguageModelRequest { messages: vec![LanguageModelRequestMessage { role: Role::System, - content: body.to_string(), + content: vec![body.to_string().into()], }], stop: Vec::new(), temperature: 1., diff --git a/crates/assistant/src/terminal_inline_assistant.rs b/crates/assistant/src/terminal_inline_assistant.rs index 1805f810e7..bf464de382 100644 --- a/crates/assistant/src/terminal_inline_assistant.rs +++ b/crates/assistant/src/terminal_inline_assistant.rs @@ -276,7 +276,7 @@ impl TerminalInlineAssistant { messages.push(LanguageModelRequestMessage { role: Role::User, - content: prompt, + content: vec![prompt.into()], }); Ok(LanguageModelRequest { diff --git a/crates/collab_ui/src/channel_view.rs b/crates/collab_ui/src/channel_view.rs index c77d4b5782..58e8b49ec0 100644 --- a/crates/collab_ui/src/channel_view.rs +++ b/crates/collab_ui/src/channel_view.rs @@ -280,7 +280,7 @@ impl ChannelView { }; let link = channel.notes_link(closest_heading.map(|heading| heading.text), cx); - cx.write_to_clipboard(ClipboardItem::new(link)); + cx.write_to_clipboard(ClipboardItem::new_string(link)); self.workspace .update(cx, |workspace, cx| { struct CopyLinkForPositionToast; diff --git a/crates/collab_ui/src/chat_panel.rs b/crates/collab_ui/src/chat_panel.rs index 4cede4e12b..ad465ef460 100644 --- a/crates/collab_ui/src/chat_panel.rs +++ b/crates/collab_ui/src/chat_panel.rs @@ -710,7 +710,7 @@ impl ChatPanel { active_chat.read(cx).find_loaded_message(message_id) }) { let text = message.body.clone(); - cx.write_to_clipboard(ClipboardItem::new(text)) + cx.write_to_clipboard(ClipboardItem::new_string(text)) } }), ) diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index d5cf56654d..0ff1131e67 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -2042,7 +2042,7 @@ impl CollabPanel { let Some(channel) = channel_store.channel_for_id(channel_id) else { return; }; - let item = ClipboardItem::new(channel.link(cx)); + let item = ClipboardItem::new_string(channel.link(cx)); cx.write_to_clipboard(item) } @@ -2261,7 +2261,7 @@ impl CollabPanel { .size(ButtonSize::None) .visible_on_hover("section-header") .on_click(move |_, cx| { - let item = ClipboardItem::new(channel_link_copy.clone()); + let item = ClipboardItem::new_string(channel_link_copy.clone()); cx.write_to_clipboard(item) }) .tooltip(|cx| Tooltip::text("Copy channel link", cx)) diff --git a/crates/collab_ui/src/collab_panel/channel_modal.rs b/crates/collab_ui/src/collab_panel/channel_modal.rs index 4e943d31f7..aa6b521798 100644 --- a/crates/collab_ui/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui/src/collab_panel/channel_modal.rs @@ -175,7 +175,8 @@ impl Render for ChannelModal { .read(cx) .channel_for_id(channel_id) { - let item = ClipboardItem::new(channel.link(cx)); + let item = + ClipboardItem::new_string(channel.link(cx)); cx.write_to_clipboard(item); } })), diff --git a/crates/copilot/src/sign_in.rs b/crates/copilot/src/sign_in.rs index 41c6ee833e..79b79e980e 100644 --- a/crates/copilot/src/sign_in.rs +++ b/crates/copilot/src/sign_in.rs @@ -55,7 +55,7 @@ impl CopilotCodeVerification { ) -> impl IntoElement { let copied = cx .read_from_clipboard() - .map(|item| item.text() == &data.user_code) + .map(|item| item.text().as_ref() == Some(&data.user_code)) .unwrap_or(false); h_flex() .w_full() @@ -68,7 +68,7 @@ impl CopilotCodeVerification { .on_mouse_down(gpui::MouseButton::Left, { let user_code = data.user_code.clone(); move |_, cx| { - cx.write_to_clipboard(ClipboardItem::new(user_code.clone())); + cx.write_to_clipboard(ClipboardItem::new_string(user_code.clone())); cx.refresh(); } }) diff --git a/crates/editor/src/blame_entry_tooltip.rs b/crates/editor/src/blame_entry_tooltip.rs index e7b8215a49..13d3d64236 100644 --- a/crates/editor/src/blame_entry_tooltip.rs +++ b/crates/editor/src/blame_entry_tooltip.rs @@ -2,8 +2,8 @@ use futures::Future; use git::blame::BlameEntry; use git::Oid; use gpui::{ - Asset, ClipboardItem, Element, ParentElement, Render, ScrollHandle, StatefulInteractiveElement, - WeakView, WindowContext, + AppContext, Asset, ClipboardItem, Element, ParentElement, Render, ScrollHandle, + StatefulInteractiveElement, WeakView, }; use settings::Settings; use std::hash::Hash; @@ -35,7 +35,7 @@ impl<'a> CommitAvatar<'a> { let avatar_url = CommitAvatarAsset::new(remote.clone(), self.sha); - let element = match cx.use_cached_asset::(&avatar_url) { + let element = match cx.use_asset::(&avatar_url) { // Loading or no avatar found None | Some(None) => Icon::new(IconName::Person) .color(Color::Muted) @@ -73,7 +73,7 @@ impl Asset for CommitAvatarAsset { fn load( source: Self::Source, - cx: &mut WindowContext, + cx: &mut AppContext, ) -> impl Future + Send + 'static { let client = cx.http_client(); @@ -242,9 +242,9 @@ impl Render for BlameEntryTooltip { .icon_color(Color::Muted) .on_click(move |_, cx| { cx.stop_propagation(); - cx.write_to_clipboard(ClipboardItem::new( - full_sha.clone(), - )) + cx.write_to_clipboard( + ClipboardItem::new_string(full_sha.clone()), + ) }), ), ), diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 431310ca1e..d07fc83820 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -69,13 +69,13 @@ use git::blame::GitBlame; use git::diff_hunk_to_display; use gpui::{ div, impl_actions, point, prelude::*, px, relative, size, uniform_list, Action, AnyElement, - AppContext, AsyncWindowContext, AvailableSpace, BackgroundExecutor, Bounds, ClipboardItem, - Context, DispatchPhase, ElementId, EntityId, EventEmitter, FocusHandle, FocusOutEvent, - FocusableView, FontId, FontWeight, HighlightStyle, Hsla, InteractiveText, KeyContext, - ListSizingBehavior, Model, MouseButton, PaintQuad, ParentElement, Pixels, Render, SharedString, - Size, StrikethroughStyle, Styled, StyledText, Subscription, Task, TextStyle, UnderlineStyle, - UniformListScrollHandle, View, ViewContext, ViewInputHandler, VisualContext, WeakFocusHandle, - WeakView, WindowContext, + AppContext, AsyncWindowContext, AvailableSpace, BackgroundExecutor, Bounds, ClipboardEntry, + ClipboardItem, Context, DispatchPhase, ElementId, EntityId, EventEmitter, FocusHandle, + FocusOutEvent, FocusableView, FontId, FontWeight, HighlightStyle, Hsla, InteractiveText, + KeyContext, ListSizingBehavior, Model, MouseButton, PaintQuad, ParentElement, Pixels, Render, + SharedString, Size, StrikethroughStyle, Styled, StyledText, Subscription, Task, TextStyle, + UnderlineStyle, UniformListScrollHandle, View, ViewContext, ViewInputHandler, VisualContext, + WeakFocusHandle, WeakView, WindowContext, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; use hover_popover::{hide_hover, HoverState}; @@ -2304,7 +2304,7 @@ impl Editor { } if !text.is_empty() { - cx.write_to_primary(ClipboardItem::new(text)); + cx.write_to_primary(ClipboardItem::new_string(text)); } } @@ -6585,7 +6585,10 @@ impl Editor { s.select(selections); }); this.insert("", cx); - cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections)); + cx.write_to_clipboard(ClipboardItem::new_string_with_json_metadata( + text, + clipboard_selections, + )); }); } @@ -6624,7 +6627,10 @@ impl Editor { } } - cx.write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections)); + cx.write_to_clipboard(ClipboardItem::new_string_with_json_metadata( + text, + clipboard_selections, + )); } pub fn do_paste( @@ -6708,13 +6714,21 @@ impl Editor { pub fn paste(&mut self, _: &Paste, cx: &mut ViewContext) { if let Some(item) = cx.read_from_clipboard() { - self.do_paste( - item.text(), - item.metadata::>(), - true, - cx, - ) - }; + let entries = item.entries(); + + match entries.first() { + // For now, we only support applying metadata if there's one string. In the future, we can incorporate all the selections + // of all the pasted entries. + Some(ClipboardEntry::String(clipboard_string)) if entries.len() == 1 => self + .do_paste( + clipboard_string.text(), + clipboard_string.metadata_json::>(), + true, + cx, + ), + _ => self.do_paste(&item.text().unwrap_or_default(), None, true, cx), + } + } } pub fn undo(&mut self, _: &Undo, cx: &mut ViewContext) { @@ -10535,7 +10549,7 @@ impl Editor { if let Some(buffer) = self.buffer().read(cx).as_singleton() { if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) { if let Some(path) = file.abs_path(cx).to_str() { - cx.write_to_clipboard(ClipboardItem::new(path.to_string())); + cx.write_to_clipboard(ClipboardItem::new_string(path.to_string())); } } } @@ -10545,7 +10559,7 @@ impl Editor { if let Some(buffer) = self.buffer().read(cx).as_singleton() { if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) { if let Some(path) = file.path().to_str() { - cx.write_to_clipboard(ClipboardItem::new(path.to_string())); + cx.write_to_clipboard(ClipboardItem::new_string(path.to_string())); } } } @@ -10735,7 +10749,7 @@ impl Editor { match permalink { Ok(permalink) => { - cx.write_to_clipboard(ClipboardItem::new(permalink.to_string())); + cx.write_to_clipboard(ClipboardItem::new_string(permalink.to_string())); } Err(err) => { let message = format!("Failed to copy permalink: {err}"); @@ -11671,7 +11685,7 @@ impl Editor { let Some(lines) = serde_json::to_string_pretty(&lines).log_err() else { return; }; - cx.write_to_clipboard(ClipboardItem::new(lines)); + cx.write_to_clipboard(ClipboardItem::new_string(lines)); } pub fn inlay_hint_cache(&self) -> &InlayHintCache { @@ -12938,7 +12952,9 @@ pub fn diagnostic_block_renderer( .visible_on_hover(group_id.clone()) .on_click({ let message = diagnostic.message.clone(); - move |_click, cx| cx.write_to_clipboard(ClipboardItem::new(message.clone())) + move |_click, cx| { + cx.write_to_clipboard(ClipboardItem::new_string(message.clone())) + } }) .tooltip(|cx| Tooltip::text("Copy diagnostic message", cx)), ) diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 7e194cac21..091eca5e8e 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -3956,8 +3956,9 @@ async fn test_clipboard(cx: &mut gpui::TestAppContext) { the lazy dog"}); cx.update_editor(|e, cx| e.copy(&Copy, cx)); assert_eq!( - cx.read_from_clipboard().map(|item| item.text().to_owned()), - Some("fox jumps over\n".to_owned()) + cx.read_from_clipboard() + .and_then(|item| item.text().as_deref().map(str::to_string)), + Some("fox jumps over\n".to_string()) ); // Paste with three selections, noticing how the copied full-line selection is inserted diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 44076193c1..bba95094b1 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -642,7 +642,7 @@ impl EditorElement { } #[cfg(target_os = "linux")] - if let Some(item) = cx.read_from_primary() { + if let Some(text) = cx.read_from_primary().and_then(|item| item.text()) { let point_for_position = position_map.point_for_position(text_hitbox.bounds, event.position); let position = point_for_position.previous_valid; @@ -655,7 +655,7 @@ impl EditorElement { }, cx, ); - editor.insert(item.text(), cx); + editor.insert(&text, cx); } cx.stop_propagation() } @@ -4290,7 +4290,7 @@ fn deploy_blame_entry_context_menu( let sha = format!("{}", blame_entry.sha); menu.on_blur_subscription(Subscription::new(|| {})) .entry("Copy commit SHA", None, move |cx| { - cx.write_to_clipboard(ClipboardItem::new(sha.clone())); + cx.write_to_clipboard(ClipboardItem::new_string(sha.clone())); }) .when_some( details.and_then(|details| details.permalink.clone()), diff --git a/crates/feedback/src/feedback.rs b/crates/feedback/src/feedback.rs index e6d8ef973e..564a8199b0 100644 --- a/crates/feedback/src/feedback.rs +++ b/crates/feedback/src/feedback.rs @@ -44,7 +44,7 @@ pub fn init(cx: &mut AppContext) { cx.spawn(|_, mut cx| async move { let specs = specs.await.to_string(); - cx.update(|cx| cx.write_to_clipboard(ClipboardItem::new(specs.clone()))) + cx.update(|cx| cx.write_to_clipboard(ClipboardItem::new_string(specs.clone()))) .log_err(); cx.prompt( diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 293bfafff3..f4b95b4d9a 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -65,6 +65,7 @@ serde_json.workspace = true slotmap = "1.0.6" smallvec.workspace = true smol.workspace = true +strum.workspace = true sum_tree.workspace = true taffy = "0.4.3" thiserror.workspace = true diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index a00b8cc652..5e3922061d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -11,9 +11,12 @@ use std::{ use anyhow::{anyhow, Result}; use derive_more::{Deref, DerefMut}; -use futures::{channel::oneshot, future::LocalBoxFuture, Future}; +use futures::{ + channel::oneshot, + future::{LocalBoxFuture, Shared}, + Future, FutureExt, +}; use slotmap::SlotMap; -use smol::future::FutureExt; pub use async_context::*; use collections::{FxHashMap, FxHashSet, VecDeque}; @@ -25,8 +28,8 @@ pub use test_context::*; use util::ResultExt; use crate::{ - current_platform, init_app_menus, Action, ActionRegistry, Any, AnyView, AnyWindowHandle, - AssetCache, AssetSource, BackgroundExecutor, ClipboardItem, Context, DispatchPhase, DisplayId, + current_platform, hash, init_app_menus, Action, ActionRegistry, Any, AnyView, AnyWindowHandle, + Asset, AssetSource, BackgroundExecutor, ClipboardItem, Context, DispatchPhase, DisplayId, Entity, EventEmitter, ForegroundExecutor, Global, KeyBinding, Keymap, Keystroke, LayoutId, Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels, Platform, PlatformDisplay, Point, PromptBuilder, PromptHandle, PromptLevel, Render, RenderablePromptHandle, Reservation, @@ -220,7 +223,6 @@ pub struct AppContext { pub(crate) background_executor: BackgroundExecutor, pub(crate) foreground_executor: ForegroundExecutor, pub(crate) loading_assets: FxHashMap<(TypeId, u64), Box>, - pub(crate) asset_cache: AssetCache, asset_source: Arc, pub(crate) svg_renderer: SvgRenderer, http_client: Arc, @@ -276,7 +278,6 @@ impl AppContext { background_executor: executor, foreground_executor, svg_renderer: SvgRenderer::new(asset_source.clone()), - asset_cache: AssetCache::new(), loading_assets: Default::default(), asset_source, http_client, @@ -1267,6 +1268,40 @@ impl AppContext { ) { self.prompt_builder = Some(PromptBuilder::Custom(Box::new(renderer))) } + + /// Remove an asset from GPUI's cache + pub fn remove_cached_asset(&mut self, source: &A::Source) { + let asset_id = (TypeId::of::(), hash(source)); + self.loading_assets.remove(&asset_id); + } + + /// Asynchronously load an asset, if the asset hasn't finished loading this will return None. + /// + /// Note that the multiple calls to this method will only result in one `Asset::load` call at a + /// time, and the results of this call will be cached + /// + /// This asset will not be cached by default, see [Self::use_cached_asset] + pub fn fetch_asset( + &mut self, + source: &A::Source, + ) -> (Shared>, bool) { + let asset_id = (TypeId::of::(), hash(source)); + let mut is_first = false; + let task = self + .loading_assets + .remove(&asset_id) + .map(|boxed_task| *boxed_task.downcast::>>().unwrap()) + .unwrap_or_else(|| { + is_first = true; + let future = A::load(source.clone(), self); + let task = self.background_executor().spawn(future).shared(); + task + }); + + self.loading_assets.insert(asset_id, Box::new(task.clone())); + + (task, is_first) + } } impl Context for AppContext { diff --git a/crates/gpui/src/asset_cache.rs b/crates/gpui/src/asset_cache.rs index e8b101f560..0c6e5f2f90 100644 --- a/crates/gpui/src/asset_cache.rs +++ b/crates/gpui/src/asset_cache.rs @@ -1,17 +1,14 @@ -use crate::{SharedString, SharedUri, WindowContext}; -use collections::FxHashMap; +use crate::{AppContext, SharedString, SharedUri}; use futures::Future; -use parking_lot::Mutex; -use std::any::TypeId; use std::hash::{Hash, Hasher}; +use std::path::PathBuf; use std::sync::Arc; -use std::{any::Any, path::PathBuf}; #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub(crate) enum UriOrPath { Uri(SharedUri), Path(Arc), - Asset(SharedString), + Embedded(SharedString), } impl From for UriOrPath { @@ -37,7 +34,7 @@ pub trait Asset { /// Load the asset asynchronously fn load( source: Self::Source, - cx: &mut WindowContext, + cx: &mut AppContext, ) -> impl Future + Send + 'static; } @@ -47,42 +44,3 @@ pub fn hash(data: &T) -> u64 { data.hash(&mut hasher); hasher.finish() } - -/// A cache for assets. -#[derive(Clone)] -pub struct AssetCache { - assets: Arc>>>, -} - -impl AssetCache { - pub(crate) fn new() -> Self { - Self { - assets: Default::default(), - } - } - - /// Get the asset from the cache, if it exists. - pub fn get(&self, source: &A::Source) -> Option { - self.assets - .lock() - .get(&(TypeId::of::(), hash(&source))) - .and_then(|task| task.downcast_ref::()) - .cloned() - } - - /// Insert the asset into the cache. - pub fn insert(&mut self, source: A::Source, output: A::Output) { - self.assets - .lock() - .insert((TypeId::of::(), hash(&source)), Box::new(output)); - } - - /// Remove an entry from the asset cache - pub fn remove(&mut self, source: &A::Source) -> Option { - self.assets - .lock() - .remove(&(TypeId::of::(), hash(&source))) - .and_then(|any| any.downcast::().ok()) - .map(|boxed| *boxed) - } -} diff --git a/crates/gpui/src/assets.rs b/crates/gpui/src/assets.rs index 0a05fb5adc..9769e3a5c9 100644 --- a/crates/gpui/src/assets.rs +++ b/crates/gpui/src/assets.rs @@ -38,14 +38,22 @@ pub(crate) struct RenderImageParams { pub(crate) frame_index: usize, } -/// A cached and processed image. -pub struct ImageData { +/// A cached and processed image, in BGRA format +pub struct RenderImage { /// The ID associated with this image pub id: ImageId, data: SmallVec<[Frame; 1]>, } -impl ImageData { +impl PartialEq for RenderImage { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl Eq for RenderImage {} + +impl RenderImage { /// Create a new image from the given data. pub fn new(data: impl Into>) -> Self { static NEXT_ID: AtomicUsize = AtomicUsize::new(0); @@ -57,8 +65,10 @@ impl ImageData { } /// Convert this image into a byte slice. - pub fn as_bytes(&self, frame_index: usize) -> &[u8] { - &self.data[frame_index].buffer() + pub fn as_bytes(&self, frame_index: usize) -> Option<&[u8]> { + self.data + .get(frame_index) + .map(|frame| frame.buffer().as_raw().as_slice()) } /// Get the size of this image, in pixels. @@ -78,7 +88,7 @@ impl ImageData { } } -impl fmt::Debug for ImageData { +impl fmt::Debug for RenderImage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ImageData") .field("id", &self.id) diff --git a/crates/gpui/src/elements/img.rs b/crates/gpui/src/elements/img.rs index 5213597a32..89fffd054e 100644 --- a/crates/gpui/src/elements/img.rs +++ b/crates/gpui/src/elements/img.rs @@ -1,16 +1,14 @@ use crate::{ - point, px, size, AbsoluteLength, Asset, Bounds, DefiniteLength, DevicePixels, Element, - ElementId, GlobalElementId, Hitbox, ImageData, InteractiveElement, Interactivity, IntoElement, - LayoutId, Length, Pixels, SharedString, SharedUri, Size, StyleRefinement, Styled, SvgSize, - UriOrPath, WindowContext, + px, AbsoluteLength, AppContext, Asset, Bounds, DefiniteLength, Element, ElementId, + GlobalElementId, Hitbox, Image, InteractiveElement, Interactivity, IntoElement, LayoutId, + Length, ObjectFit, Pixels, RenderImage, SharedString, SharedUri, Size, StyleRefinement, Styled, + SvgSize, UriOrPath, WindowContext, }; use futures::{AsyncReadExt, Future}; use http_client; use image::{ codecs::gif::GifDecoder, AnimationDecoder, Frame, ImageBuffer, ImageError, ImageFormat, }; -#[cfg(target_os = "macos")] -use media::core_video::CVImageBuffer; use smallvec::SmallVec; use std::{ fs, @@ -23,20 +21,18 @@ use thiserror::Error; use util::ResultExt; /// A source of image content. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum ImageSource { /// Image content will be loaded from provided URI at render time. Uri(SharedUri), /// Image content will be loaded from the provided file at render time. File(Arc), /// Cached image data - Data(Arc), + Render(Arc), + /// Cached image data + Image(Arc), /// Image content will be loaded from Asset at render time. - Asset(SharedString), - // TODO: move surface definitions into mac platform module - /// A CoreVideo image buffer - #[cfg(target_os = "macos")] - Surface(CVImageBuffer), + Embedded(SharedString), } fn is_uri(uri: &str) -> bool { @@ -54,7 +50,7 @@ impl From<&'static str> for ImageSource { if is_uri(&s) { Self::Uri(s.into()) } else { - Self::Asset(s.into()) + Self::Embedded(s.into()) } } } @@ -64,7 +60,7 @@ impl From for ImageSource { if is_uri(&s) { Self::Uri(s.into()) } else { - Self::Asset(s.into()) + Self::Embedded(s.into()) } } } @@ -74,7 +70,7 @@ impl From for ImageSource { if is_uri(&s) { Self::Uri(s.into()) } else { - Self::Asset(s) + Self::Embedded(s) } } } @@ -91,16 +87,9 @@ impl From for ImageSource { } } -impl From> for ImageSource { - fn from(value: Arc) -> Self { - Self::Data(value) - } -} - -#[cfg(target_os = "macos")] -impl From for ImageSource { - fn from(value: CVImageBuffer) -> Self { - Self::Surface(value) +impl From> for ImageSource { + fn from(value: Arc) -> Self { + Self::Render(value) } } @@ -122,121 +111,6 @@ pub fn img(source: impl Into) -> Img { } } -/// How to fit the image into the bounds of the element. -pub enum ObjectFit { - /// The image will be stretched to fill the bounds of the element. - Fill, - /// The image will be scaled to fit within the bounds of the element. - Contain, - /// The image will be scaled to cover the bounds of the element. - Cover, - /// The image will be scaled down to fit within the bounds of the element. - ScaleDown, - /// The image will maintain its original size. - None, -} - -impl ObjectFit { - /// Get the bounds of the image within the given bounds. - pub fn get_bounds( - &self, - bounds: Bounds, - image_size: Size, - ) -> Bounds { - let image_size = image_size.map(|dimension| Pixels::from(u32::from(dimension))); - let image_ratio = image_size.width / image_size.height; - let bounds_ratio = bounds.size.width / bounds.size.height; - - let result_bounds = match self { - ObjectFit::Fill => bounds, - ObjectFit::Contain => { - let new_size = if bounds_ratio > image_ratio { - size( - image_size.width * (bounds.size.height / image_size.height), - bounds.size.height, - ) - } else { - size( - bounds.size.width, - image_size.height * (bounds.size.width / image_size.width), - ) - }; - - Bounds { - origin: point( - bounds.origin.x + (bounds.size.width - new_size.width) / 2.0, - bounds.origin.y + (bounds.size.height - new_size.height) / 2.0, - ), - size: new_size, - } - } - ObjectFit::ScaleDown => { - // Check if the image is larger than the bounds in either dimension. - if image_size.width > bounds.size.width || image_size.height > bounds.size.height { - // If the image is larger, use the same logic as Contain to scale it down. - let new_size = if bounds_ratio > image_ratio { - size( - image_size.width * (bounds.size.height / image_size.height), - bounds.size.height, - ) - } else { - size( - bounds.size.width, - image_size.height * (bounds.size.width / image_size.width), - ) - }; - - Bounds { - origin: point( - bounds.origin.x + (bounds.size.width - new_size.width) / 2.0, - bounds.origin.y + (bounds.size.height - new_size.height) / 2.0, - ), - size: new_size, - } - } else { - // If the image is smaller than or equal to the container, display it at its original size, - // centered within the container. - let original_size = size(image_size.width, image_size.height); - Bounds { - origin: point( - bounds.origin.x + (bounds.size.width - original_size.width) / 2.0, - bounds.origin.y + (bounds.size.height - original_size.height) / 2.0, - ), - size: original_size, - } - } - } - ObjectFit::Cover => { - let new_size = if bounds_ratio > image_ratio { - size( - bounds.size.width, - image_size.height * (bounds.size.width / image_size.width), - ) - } else { - size( - image_size.width * (bounds.size.height / image_size.height), - bounds.size.height, - ) - }; - - Bounds { - origin: point( - bounds.origin.x + (bounds.size.width - new_size.width) / 2.0, - bounds.origin.y + (bounds.size.height - new_size.height) / 2.0, - ), - size: new_size, - } - } - ObjectFit::None => Bounds { - origin: bounds.origin, - size: image_size, - }, - }; - - result_bounds - } -} - impl Img { /// A list of all format extensions currently supported by this img element pub fn extensions() -> &'static [&'static str] { @@ -291,7 +165,7 @@ impl Element for Img { let layout_id = self .interactivity .request_layout(global_id, cx, |mut style, cx| { - if let Some(data) = self.source.data(cx) { + if let Some(data) = self.source.use_data(cx) { if let Some(state) = &mut state { let frame_count = data.frame_count(); if frame_count > 1 { @@ -363,7 +237,7 @@ impl Element for Img { .paint(global_id, bounds, hitbox.as_ref(), cx, |style, cx| { let corner_radii = style.corner_radii.to_pixels(bounds.size, cx.rem_size()); - if let Some(data) = source.data(cx) { + if let Some(data) = source.use_data(cx) { let new_bounds = self.object_fit.get_bounds(bounds, data.size(*frame_index)); cx.paint_image( new_bounds, @@ -374,17 +248,6 @@ impl Element for Img { ) .log_err(); } - - match source { - #[cfg(target_os = "macos")] - ImageSource::Surface(surface) => { - let size = size(surface.width().into(), surface.height().into()); - let new_bounds = self.object_fit.get_bounds(bounds, size); - // TODO: Add support for corner_radii and grayscale. - cx.paint_surface(new_bounds, surface); - } - _ => {} - } }) } } @@ -410,39 +273,74 @@ impl InteractiveElement for Img { } impl ImageSource { - fn data(&self, cx: &mut WindowContext) -> Option> { + pub(crate) fn use_data(&self, cx: &mut WindowContext) -> Option> { match self { - ImageSource::Uri(_) | ImageSource::Asset(_) | ImageSource::File(_) => { + ImageSource::Uri(_) | ImageSource::Embedded(_) | ImageSource::File(_) => { let uri_or_path: UriOrPath = match self { ImageSource::Uri(uri) => uri.clone().into(), ImageSource::File(path) => path.clone().into(), - ImageSource::Asset(path) => UriOrPath::Asset(path.clone()), + ImageSource::Embedded(path) => UriOrPath::Embedded(path.clone()), _ => unreachable!(), }; - cx.use_cached_asset::(&uri_or_path)?.log_err() + cx.use_asset::(&uri_or_path)?.log_err() } - ImageSource::Data(data) => Some(data.to_owned()), - #[cfg(target_os = "macos")] - ImageSource::Surface(_) => None, + ImageSource::Render(data) => Some(data.to_owned()), + ImageSource::Image(data) => cx.use_asset::(data)?.log_err(), + } + } + + /// Fetch the data associated with this source, using GPUI's asset caching + pub async fn data(&self, cx: &mut AppContext) -> Option> { + match self { + ImageSource::Uri(_) | ImageSource::Embedded(_) | ImageSource::File(_) => { + let uri_or_path: UriOrPath = match self { + ImageSource::Uri(uri) => uri.clone().into(), + ImageSource::File(path) => path.clone().into(), + ImageSource::Embedded(path) => UriOrPath::Embedded(path.clone()), + _ => unreachable!(), + }; + + cx.fetch_asset::(&uri_or_path).0.await.log_err() + } + + ImageSource::Render(data) => Some(data.to_owned()), + ImageSource::Image(data) => cx.fetch_asset::(data).0.await.log_err(), } } } #[derive(Clone)] -enum Image {} +enum ImageDecoder {} -impl Asset for Image { - type Source = UriOrPath; - type Output = Result, ImageCacheError>; +impl Asset for ImageDecoder { + type Source = Arc; + type Output = Result, Arc>; fn load( source: Self::Source, - cx: &mut WindowContext, + cx: &mut AppContext, + ) -> impl Future + Send + 'static { + let result = source.to_image_data(cx).map_err(Arc::new); + async { result } + } +} + +#[derive(Clone)] +enum ImageAsset {} + +impl Asset for ImageAsset { + type Source = UriOrPath; + type Output = Result, ImageCacheError>; + + fn load( + source: Self::Source, + cx: &mut AppContext, ) -> impl Future + Send + 'static { let client = cx.http_client(); - let scale_factor = cx.scale_factor(); + // TODO: Can we make SVGs always rescale? + // let scale_factor = cx.scale_factor(); let svg_renderer = cx.svg_renderer(); let asset_source = cx.asset_source().clone(); async move { @@ -461,7 +359,7 @@ impl Asset for Image { } body } - UriOrPath::Asset(path) => { + UriOrPath::Embedded(path) => { let data = asset_source.load(&path).ok().flatten(); if let Some(data) = data { data.to_vec() @@ -503,15 +401,16 @@ impl Asset for Image { } }; - ImageData::new(data) + RenderImage::new(data) } else { let pixmap = - svg_renderer.render_pixmap(&bytes, SvgSize::ScaleFactor(scale_factor))?; + // TODO: Can we make svgs always rescale? + svg_renderer.render_pixmap(&bytes, SvgSize::ScaleFactor(1.0))?; let buffer = ImageBuffer::from_raw(pixmap.width(), pixmap.height(), pixmap.take()).unwrap(); - ImageData::new(SmallVec::from_elem(Frame::new(buffer), 1)) + RenderImage::new(SmallVec::from_elem(Frame::new(buffer), 1)) }; Ok(Arc::new(data)) diff --git a/crates/gpui/src/elements/mod.rs b/crates/gpui/src/elements/mod.rs index 88f0297bba..3387034180 100644 --- a/crates/gpui/src/elements/mod.rs +++ b/crates/gpui/src/elements/mod.rs @@ -5,6 +5,7 @@ mod deferred; mod div; mod img; mod list; +mod surface; mod svg; mod text; mod uniform_list; @@ -16,6 +17,7 @@ pub use deferred::*; pub use div::*; pub use img::*; pub use list::*; +pub use surface::*; pub use svg::*; pub use text::*; pub use uniform_list::*; diff --git a/crates/gpui/src/elements/surface.rs b/crates/gpui/src/elements/surface.rs new file mode 100644 index 0000000000..3a52618106 --- /dev/null +++ b/crates/gpui/src/elements/surface.rs @@ -0,0 +1,111 @@ +use crate::{ + Bounds, Element, ElementId, GlobalElementId, IntoElement, LayoutId, ObjectFit, Pixels, Style, + StyleRefinement, Styled, WindowContext, +}; +#[cfg(target_os = "macos")] +use media::core_video::CVImageBuffer; +use refineable::Refineable; + +/// A source of a surface's content. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum SurfaceSource { + /// A macOS image buffer from CoreVideo + #[cfg(target_os = "macos")] + Surface(CVImageBuffer), +} + +#[cfg(target_os = "macos")] +impl From for SurfaceSource { + fn from(value: CVImageBuffer) -> Self { + SurfaceSource::Surface(value) + } +} + +/// A surface element. +pub struct Surface { + source: SurfaceSource, + object_fit: ObjectFit, + style: StyleRefinement, +} + +/// Create a new surface element. +pub fn surface(source: impl Into) -> Surface { + Surface { + source: source.into(), + object_fit: ObjectFit::Contain, + style: Default::default(), + } +} + +impl Surface { + /// Set the object fit for the image. + pub fn object_fit(mut self, object_fit: ObjectFit) -> Self { + self.object_fit = object_fit; + self + } +} + +impl Element for Surface { + type RequestLayoutState = (); + type PrepaintState = (); + + fn id(&self) -> Option { + None + } + + fn request_layout( + &mut self, + _global_id: Option<&GlobalElementId>, + cx: &mut WindowContext, + ) -> (LayoutId, Self::RequestLayoutState) { + let mut style = Style::default(); + style.refine(&self.style); + let layout_id = cx.request_layout(style, []); + (layout_id, ()) + } + + fn prepaint( + &mut self, + _global_id: Option<&GlobalElementId>, + _bounds: Bounds, + _request_layout: &mut Self::RequestLayoutState, + _cx: &mut WindowContext, + ) -> Self::PrepaintState { + () + } + + fn paint( + &mut self, + _global_id: Option<&GlobalElementId>, + #[cfg_attr(not(target_os = "macos"), allow(unused_variables))] bounds: Bounds, + _: &mut Self::RequestLayoutState, + _: &mut Self::PrepaintState, + #[cfg_attr(not(target_os = "macos"), allow(unused_variables))] cx: &mut WindowContext, + ) { + match &self.source { + #[cfg(target_os = "macos")] + SurfaceSource::Surface(surface) => { + let size = crate::size(surface.width().into(), surface.height().into()); + let new_bounds = self.object_fit.get_bounds(bounds, size); + // TODO: Add support for corner_radii + cx.paint_surface(new_bounds, surface.clone()); + } + #[allow(unreachable_patterns)] + _ => {} + } + } +} + +impl IntoElement for Surface { + type Element = Self; + + fn into_element(self) -> Self::Element { + self + } +} + +impl Styled for Surface { + fn style(&mut self) -> &mut StyleRefinement { + &mut self.style + } +} diff --git a/crates/gpui/src/geometry.rs b/crates/gpui/src/geometry.rs index e1ff38bdb8..a846fc881b 100644 --- a/crates/gpui/src/geometry.rs +++ b/crates/gpui/src/geometry.rs @@ -2447,10 +2447,24 @@ impl From for Pixels { /// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the /// display. #[derive( - Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign, + Add, + AddAssign, + Clone, + Copy, + Default, + Div, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + Sub, + SubAssign, + Serialize, + Deserialize, )] #[repr(transparent)] -pub struct DevicePixels(pub(crate) i32); +pub struct DevicePixels(pub i32); impl DevicePixels { /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory. diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index d68392cf51..d19a6b745a 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -20,21 +20,25 @@ mod test; mod windows; use crate::{ - point, Action, AnyWindowHandle, AsyncWindowContext, BackgroundExecutor, Bounds, DevicePixels, - DispatchEventResult, Font, FontId, FontMetrics, FontRun, ForegroundExecutor, GPUSpecs, GlyphId, - Keymap, LineLayout, Pixels, PlatformInput, Point, RenderGlyphParams, RenderImageParams, - RenderSvgParams, Scene, SharedString, Size, Task, TaskLabel, WindowContext, - DEFAULT_WINDOW_SIZE, + point, Action, AnyWindowHandle, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, + DevicePixels, DispatchEventResult, Font, FontId, FontMetrics, FontRun, ForegroundExecutor, + GPUSpecs, GlyphId, ImageSource, Keymap, LineLayout, Pixels, PlatformInput, Point, + RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, Scene, SharedString, Size, + SvgSize, Task, TaskLabel, WindowContext, DEFAULT_WINDOW_SIZE, }; use anyhow::Result; use async_task::Runnable; use futures::channel::oneshot; +use image::codecs::gif::GifDecoder; +use image::{AnimationDecoder as _, Frame}; use parking::Unparker; use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; use seahash::SeaHasher; use serde::{Deserialize, Serialize}; +use smallvec::SmallVec; use std::borrow::Cow; use std::hash::{Hash, Hasher}; +use std::io::Cursor; use std::time::{Duration, Instant}; use std::{ fmt::{self, Debug}, @@ -43,6 +47,7 @@ use std::{ rc::Rc, sync::Arc, }; +use strum::EnumIter; use uuid::Uuid; pub use app_menu::*; @@ -969,12 +974,210 @@ impl Default for CursorStyle { /// A clipboard item that should be copied to the clipboard #[derive(Clone, Debug, Eq, PartialEq)] pub struct ClipboardItem { + entries: Vec, +} + +/// Either a ClipboardString or a ClipboardImage +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum ClipboardEntry { + /// A string entry + String(ClipboardString), + /// An image entry + Image(Image), +} + +impl ClipboardItem { + /// Create a new ClipboardItem::String with no associated metadata + pub fn new_string(text: String) -> Self { + Self { + entries: vec![ClipboardEntry::String(ClipboardString::new(text))], + } + } + + /// Create a new ClipboardItem::String with the given text and associated metadata + pub fn new_string_with_metadata(text: String, metadata: String) -> Self { + Self { + entries: vec![ClipboardEntry::String(ClipboardString { + text, + metadata: Some(metadata), + })], + } + } + + /// Create a new ClipboardItem::String with the given text and associated metadata + pub fn new_string_with_json_metadata(text: String, metadata: T) -> Self { + Self { + entries: vec![ClipboardEntry::String( + ClipboardString::new(text).with_json_metadata(metadata), + )], + } + } + + /// Concatenates together all the ClipboardString entries in the item. + /// Returns None if there were no ClipboardString entries. + pub fn text(&self) -> Option { + let mut answer = String::new(); + let mut any_entries = false; + + for entry in self.entries.iter() { + if let ClipboardEntry::String(ClipboardString { text, metadata: _ }) = entry { + answer.push_str(text); + any_entries = true; + } + } + + if any_entries { + Some(answer) + } else { + None + } + } + + /// If this item is one ClipboardEntry::String, returns its metadata. + #[cfg_attr(not(target_os = "windows"), allow(dead_code))] + pub fn metadata(&self) -> Option<&String> { + match self.entries().first() { + Some(ClipboardEntry::String(clipboard_string)) if self.entries.len() == 1 => { + clipboard_string.metadata.as_ref() + } + _ => None, + } + } + + /// Get the item's entries + pub fn entries(&self) -> &[ClipboardEntry] { + &self.entries + } + + /// Get owned versions of the item's entries + pub fn into_entries(self) -> impl Iterator { + self.entries.into_iter() + } +} + +/// One of the editor's supported image formats (e.g. PNG, JPEG) - used when dealing with images in the clipboard +#[derive(Clone, Copy, Debug, Eq, PartialEq, EnumIter, Hash)] +pub enum ImageFormat { + // Sorted from most to least likely to be pasted into an editor, + // which matters when we iterate through them trying to see if + // clipboard content matches them. + /// .png + Png, + /// .jpeg or .jpg + Jpeg, + /// .webp + Webp, + /// .gif + Gif, + /// .svg + Svg, + /// .bmp + Bmp, + /// .tif or .tiff + Tiff, +} + +/// An image, with a format and certain bytes +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Image { + /// The image format the bytes represent (e.g. PNG) + format: ImageFormat, + /// The raw image bytes + bytes: Vec, + id: u64, +} + +impl Hash for Image { + fn hash(&self, state: &mut H) { + state.write_u64(self.id); + } +} + +impl Image { + /// Get this image's ID + pub fn id(&self) -> u64 { + self.id + } + + /// Use the GPUI `use_asset` API to make this image renderable + pub fn use_render_image(self: Arc, cx: &mut WindowContext) -> Option> { + ImageSource::Image(self).use_data(cx) + } + + /// Convert the clipboard image to an `ImageData` object. + pub fn to_image_data(&self, cx: &AppContext) -> Result> { + fn frames_for_image( + bytes: &[u8], + format: image::ImageFormat, + ) -> Result> { + let mut data = image::load_from_memory_with_format(bytes, format)?.into_rgba8(); + + // Convert from RGBA to BGRA. + for pixel in data.chunks_exact_mut(4) { + pixel.swap(0, 2); + } + + Ok(SmallVec::from_elem(Frame::new(data), 1)) + } + + let frames = match self.format { + ImageFormat::Gif => { + let decoder = GifDecoder::new(Cursor::new(&self.bytes))?; + let mut frames = SmallVec::new(); + + for frame in decoder.into_frames() { + let mut frame = frame?; + // Convert from RGBA to BGRA. + for pixel in frame.buffer_mut().chunks_exact_mut(4) { + pixel.swap(0, 2); + } + frames.push(frame); + } + + frames + } + ImageFormat::Png => frames_for_image(&self.bytes, image::ImageFormat::Png)?, + ImageFormat::Jpeg => frames_for_image(&self.bytes, image::ImageFormat::Jpeg)?, + ImageFormat::Webp => frames_for_image(&self.bytes, image::ImageFormat::WebP)?, + ImageFormat::Bmp => frames_for_image(&self.bytes, image::ImageFormat::Bmp)?, + ImageFormat::Tiff => frames_for_image(&self.bytes, image::ImageFormat::Tiff)?, + ImageFormat::Svg => { + // TODO: Fix this + let pixmap = cx + .svg_renderer() + .render_pixmap(&self.bytes, SvgSize::ScaleFactor(1.0))?; + + let buffer = + image::ImageBuffer::from_raw(pixmap.width(), pixmap.height(), pixmap.take()) + .unwrap(); + + SmallVec::from_elem(Frame::new(buffer), 1) + } + }; + + Ok(Arc::new(RenderImage::new(frames))) + } + + /// Get the format of the clipboard image + pub fn format(&self) -> ImageFormat { + self.format + } + + /// Get the raw bytes of the clipboard image + pub fn bytes(&self) -> &[u8] { + self.bytes.as_slice() + } +} + +/// A clipboard item that should be copied to the clipboard +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ClipboardString { pub(crate) text: String, pub(crate) metadata: Option, } -impl ClipboardItem { - /// Create a new clipboard item with the given text +impl ClipboardString { + /// Create a new clipboard string with the given text pub fn new(text: String) -> Self { Self { text, @@ -982,19 +1185,25 @@ impl ClipboardItem { } } - /// Create a new clipboard item with the given text and metadata - pub fn with_metadata(mut self, metadata: T) -> Self { + /// Return a new clipboard item with the metadata replaced by the given metadata, + /// after serializing it as JSON. + pub fn with_json_metadata(mut self, metadata: T) -> Self { self.metadata = Some(serde_json::to_string(&metadata).unwrap()); self } - /// Get the text of the clipboard item + /// Get the text of the clipboard string pub fn text(&self) -> &String { &self.text } - /// Get the metadata of the clipboard item - pub fn metadata(&self) -> Option + /// Get the owned text of the clipboard string + pub fn into_text(self) -> String { + self.text + } + + /// Get the metadata of the clipboard string, formatted as JSON + pub fn metadata_json(&self) -> Option where T: for<'a> Deserialize<'a>, { diff --git a/crates/gpui/src/platform/linux/wayland/clipboard.rs b/crates/gpui/src/platform/linux/wayland/clipboard.rs index 3df06123af..26b5256bdd 100644 --- a/crates/gpui/src/platform/linux/wayland/clipboard.rs +++ b/crates/gpui/src/platform/linux/wayland/clipboard.rs @@ -112,14 +112,18 @@ impl Clipboard { } pub fn send(&self, _mime_type: String, fd: OwnedFd) { - if let Some(contents) = &self.contents { - self.send_internal(fd, contents.text.as_bytes().to_owned()); + if let Some(text) = self.contents.as_ref().and_then(|contents| contents.text()) { + self.send_internal(fd, text.as_bytes().to_owned()); } } pub fn send_primary(&self, _mime_type: String, fd: OwnedFd) { - if let Some(primary_contents) = &self.primary_contents { - self.send_internal(fd, primary_contents.text.as_bytes().to_owned()); + if let Some(text) = self + .primary_contents + .as_ref() + .and_then(|contents| contents.text()) + { + self.send_internal(fd, text.as_bytes().to_owned()); } } @@ -145,7 +149,7 @@ impl Clipboard { match unsafe { read_fd(fd) } { Ok(v) => { - self.cached_read = Some(ClipboardItem::new(v)); + self.cached_read = Some(ClipboardItem::new_string(v)); self.cached_read.clone() } Err(err) => { @@ -177,7 +181,7 @@ impl Clipboard { match unsafe { read_fd(fd) } { Ok(v) => { - self.cached_primary_read = Some(ClipboardItem::new(v.clone())); + self.cached_primary_read = Some(ClipboardItem::new_string(v.clone())); self.cached_primary_read.clone() } Err(err) => { diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index 9d44e236ac..f9a4efdb14 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -1259,7 +1259,7 @@ impl LinuxClient for X11Client { .store( state.clipboard.setter.atoms.primary, state.clipboard.setter.atoms.utf8_string, - item.text().as_bytes(), + item.text().unwrap_or_default().as_bytes(), ) .ok(); } @@ -1271,7 +1271,7 @@ impl LinuxClient for X11Client { .store( state.clipboard.setter.atoms.clipboard, state.clipboard.setter.atoms.utf8_string, - item.text().as_bytes(), + item.text().unwrap_or_default().as_bytes(), ) .ok(); state.clipboard_item.replace(item); @@ -1287,10 +1287,7 @@ impl LinuxClient for X11Client { state.clipboard.getter.atoms.property, Duration::from_secs(3), ) - .map(|text| crate::ClipboardItem { - text: String::from_utf8(text).unwrap(), - metadata: None, - }) + .map(|text| crate::ClipboardItem::new_string(String::from_utf8(text).unwrap())) .ok() } @@ -1318,10 +1315,7 @@ impl LinuxClient for X11Client { state.clipboard.getter.atoms.property, Duration::from_secs(3), ) - .map(|text| crate::ClipboardItem { - text: String::from_utf8(text).unwrap(), - metadata: None, - }) + .map(|text| crate::ClipboardItem::new_string(String::from_utf8(text).unwrap())) .ok() } diff --git a/crates/gpui/src/platform/mac.rs b/crates/gpui/src/platform/mac.rs index c2a09fb95e..2223dd91b4 100644 --- a/crates/gpui/src/platform/mac.rs +++ b/crates/gpui/src/platform/mac.rs @@ -16,6 +16,7 @@ use metal_renderer as renderer; #[cfg(feature = "macos-blade")] use crate::platform::blade as renderer; +mod attributed_string; mod open_type; mod platform; mod text_system; diff --git a/crates/gpui/src/platform/mac/attributed_string.rs b/crates/gpui/src/platform/mac/attributed_string.rs new file mode 100644 index 0000000000..663ce67d4c --- /dev/null +++ b/crates/gpui/src/platform/mac/attributed_string.rs @@ -0,0 +1,122 @@ +use cocoa::base::id; +use cocoa::foundation::NSRange; +use objc::{class, msg_send, sel, sel_impl}; + +/// The `cocoa` crate does not define NSAttributedString (and related Cocoa classes), +/// which are needed for copying rich text (that is, text intermingled with images) +/// to the clipboard. This adds access to those APIs. + +#[allow(non_snake_case)] +pub trait NSAttributedString: Sized { + unsafe fn alloc(_: Self) -> id { + msg_send![class!(NSAttributedString), alloc] + } + + unsafe fn init_attributed_string(self, string: id) -> id; + unsafe fn appendAttributedString_(self, attr_string: id); + unsafe fn RTFDFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id; + unsafe fn RTFFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id; + unsafe fn string(self) -> id; +} + +impl NSAttributedString for id { + unsafe fn init_attributed_string(self, string: id) -> id { + msg_send![self, initWithString: string] + } + + unsafe fn appendAttributedString_(self, attr_string: id) { + let _: () = msg_send![self, appendAttributedString: attr_string]; + } + + unsafe fn RTFDFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id { + msg_send![self, RTFDFromRange: range documentAttributes: attrs] + } + + unsafe fn RTFFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id { + msg_send![self, RTFFromRange: range documentAttributes: attrs] + } + + unsafe fn string(self) -> id { + msg_send![self, string] + } +} + +pub trait NSMutableAttributedString: NSAttributedString { + unsafe fn alloc(_: Self) -> id { + msg_send![class!(NSMutableAttributedString), alloc] + } +} + +impl NSMutableAttributedString for id {} + +#[cfg(test)] +mod tests { + use super::*; + use cocoa::appkit::NSImage; + use cocoa::base::nil; + use cocoa::foundation::NSString; + #[test] + #[ignore] // This was SIGSEGV-ing on CI but not locally; need to investigate https://github.com/zed-industries/zed/actions/runs/10362363230/job/28684225486?pr=15782#step:4:1348 + fn test_nsattributed_string() { + // TODO move these to parent module once it's actually ready to be used + #[allow(non_snake_case)] + pub trait NSTextAttachment: Sized { + unsafe fn alloc(_: Self) -> id { + msg_send![class!(NSTextAttachment), alloc] + } + } + + impl NSTextAttachment for id {} + + unsafe { + let image: id = msg_send![class!(NSImage), alloc]; + image.initWithContentsOfFile_( + NSString::alloc(nil).init_str("/Users/rtfeldman/Downloads/test.jpeg"), + ); + let _size = image.size(); + + let string = NSString::alloc(nil).init_str("Test String"); + let attr_string = NSMutableAttributedString::alloc(nil).init_attributed_string(string); + let hello_string = NSString::alloc(nil).init_str("Hello World"); + let hello_attr_string = + NSAttributedString::alloc(nil).init_attributed_string(hello_string); + attr_string.appendAttributedString_(hello_attr_string); + + let attachment = NSTextAttachment::alloc(nil); + let _: () = msg_send![attachment, setImage: image]; + let image_attr_string = + msg_send![class!(NSAttributedString), attributedStringWithAttachment: attachment]; + attr_string.appendAttributedString_(image_attr_string); + + let another_string = NSString::alloc(nil).init_str("Another String"); + let another_attr_string = + NSAttributedString::alloc(nil).init_attributed_string(another_string); + attr_string.appendAttributedString_(another_attr_string); + + let _len: cocoa::foundation::NSUInteger = msg_send![attr_string, length]; + + /////////////////////////////////////////////////// + // pasteboard.clearContents(); + + let rtfd_data = attr_string.RTFDFromRange_documentAttributes_( + NSRange::new(0, msg_send![attr_string, length]), + nil, + ); + assert_ne!(rtfd_data, nil); + // if rtfd_data != nil { + // pasteboard.setData_forType(rtfd_data, NSPasteboardTypeRTFD); + // } + + // let rtf_data = attributed_string.RTFFromRange_documentAttributes_( + // NSRange::new(0, attributed_string.length()), + // nil, + // ); + // if rtf_data != nil { + // pasteboard.setData_forType(rtf_data, NSPasteboardTypeRTF); + // } + + // let plain_text = attributed_string.string(); + // pasteboard.setString_forType(plain_text, NSPasteboardTypeString); + } + } +} diff --git a/crates/gpui/src/platform/mac/metal_renderer.rs b/crates/gpui/src/platform/mac/metal_renderer.rs index e5d3babe6c..401734e253 100644 --- a/crates/gpui/src/platform/mac/metal_renderer.rs +++ b/crates/gpui/src/platform/mac/metal_renderer.rs @@ -1,8 +1,8 @@ use super::metal_atlas::MetalAtlas; use crate::{ point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels, - Hsla, MonochromeSprite, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, - ScaledPixels, Scene, Shadow, Size, Surface, Underline, + Hsla, MonochromeSprite, PaintSurface, Path, PathId, PathVertex, PolychromeSprite, + PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size, Surface, Underline, }; use anyhow::{anyhow, Result}; use block::ConcreteBlock; @@ -1020,7 +1020,7 @@ impl MetalRenderer { fn draw_surfaces( &mut self, - surfaces: &[Surface], + surfaces: &[PaintSurface], instance_buffer: &mut InstanceBuffer, instance_offset: &mut usize, viewport_size: Size, diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index ed513f6d99..574a903b0a 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -1,8 +1,13 @@ -use super::{events::key_to_native, BoolExt}; +use super::{ + attributed_string::{NSAttributedString, NSMutableAttributedString}, + events::key_to_native, + BoolExt, +}; use crate::{ - Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, ForegroundExecutor, - Keymap, MacDispatcher, MacDisplay, MacTextSystem, MacWindow, Menu, MenuItem, PathPromptOptions, - Platform, PlatformDisplay, PlatformTextSystem, PlatformWindow, Result, SemanticVersion, Task, + hash, Action, AnyWindowHandle, BackgroundExecutor, ClipboardEntry, ClipboardItem, + ClipboardString, CursorStyle, ForegroundExecutor, Image, ImageFormat, Keymap, MacDispatcher, + MacDisplay, MacTextSystem, MacWindow, Menu, MenuItem, PathPromptOptions, Platform, + PlatformDisplay, PlatformTextSystem, PlatformWindow, Result, SemanticVersion, Task, WindowAppearance, WindowParams, }; use anyhow::anyhow; @@ -11,16 +16,17 @@ use cocoa::{ appkit::{ NSApplication, NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular, NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel, NSPasteboard, - NSPasteboardTypeString, NSSavePanel, NSWindow, + NSPasteboardTypePNG, NSPasteboardTypeRTF, NSPasteboardTypeRTFD, NSPasteboardTypeString, + NSPasteboardTypeTIFF, NSSavePanel, NSWindow, }, base::{id, nil, selector, BOOL, YES}, foundation::{ - NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSProcessInfo, NSString, + NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSProcessInfo, NSRange, NSString, NSUInteger, NSURL, }, }; use core_foundation::{ - base::{CFRelease, CFType, CFTypeRef, OSStatus, TCFType as _}, + base::{CFRelease, CFType, CFTypeRef, OSStatus, TCFType}, boolean::CFBoolean, data::CFData, dictionary::{CFDictionary, CFDictionaryRef, CFMutableDictionary}, @@ -50,6 +56,7 @@ use std::{ slice, str, sync::Arc, }; +use strum::IntoEnumIterator; use super::renderer; @@ -421,7 +428,7 @@ impl Platform for MacPlatform { pool.drain(); (*app).set_ivar(MAC_PLATFORM_IVAR, null_mut::()); - (*app.delegate()).set_ivar(MAC_PLATFORM_IVAR, null_mut::()); + (*NSWindow::delegate(app)).set_ivar(MAC_PLATFORM_IVAR, null_mut::()); } } @@ -749,7 +756,7 @@ impl Platform for MacPlatform { let app: id = msg_send![APP_CLASS, sharedApplication]; let mut state = self.0.lock(); let actions = &mut state.menu_actions; - app.setMainMenu_(self.create_menu_bar(menus, app.delegate(), actions, keymap)); + app.setMainMenu_(self.create_menu_bar(menus, NSWindow::delegate(app), actions, keymap)); } } @@ -758,7 +765,7 @@ impl Platform for MacPlatform { let app: id = msg_send![APP_CLASS, sharedApplication]; let mut state = self.0.lock(); let actions = &mut state.menu_actions; - let new = self.create_dock_menu(menu, app.delegate(), actions, keymap); + let new = self.create_dock_menu(menu, NSWindow::delegate(app), actions, keymap); if let Some(old) = state.dock_menu.replace(new) { CFRelease(old as _) } @@ -851,79 +858,115 @@ impl Platform for MacPlatform { } fn write_to_clipboard(&self, item: ClipboardItem) { - let state = self.0.lock(); + use crate::ClipboardEntry; + unsafe { - state.pasteboard.clearContents(); + // We only want to use NSAttributedString if there are multiple entries to write. + if item.entries.len() <= 1 { + match item.entries.first() { + Some(entry) => match entry { + ClipboardEntry::String(string) => { + self.write_plaintext_to_clipboard(string); + } + ClipboardEntry::Image(image) => { + self.write_image_to_clipboard(image); + } + }, + None => { + // Writing an empty list of entries just clears the clipboard. + let state = self.0.lock(); + state.pasteboard.clearContents(); + } + } + } else { + let mut any_images = false; + let attributed_string = { + let mut buf = NSMutableAttributedString::alloc(nil) + // TODO can we skip this? Or at least part of it? + .init_attributed_string(NSString::alloc(nil).init_str("")); - let text_bytes = NSData::dataWithBytes_length_( - nil, - item.text.as_ptr() as *const c_void, - item.text.len() as u64, - ); - state - .pasteboard - .setData_forType(text_bytes, NSPasteboardTypeString); + for entry in item.entries { + if let ClipboardEntry::String(ClipboardString { text, metadata: _ }) = entry + { + let to_append = NSAttributedString::alloc(nil) + .init_attributed_string(NSString::alloc(nil).init_str(&text)); - if let Some(metadata) = item.metadata.as_ref() { - let hash_bytes = ClipboardItem::text_hash(&item.text).to_be_bytes(); - let hash_bytes = NSData::dataWithBytes_length_( - nil, - hash_bytes.as_ptr() as *const c_void, - hash_bytes.len() as u64, - ); + buf.appendAttributedString_(to_append); + } + } + + buf + }; + + let state = self.0.lock(); + state.pasteboard.clearContents(); + + // Only set rich text clipboard types if we actually have 1+ images to include. + if any_images { + let rtfd_data = attributed_string.RTFDFromRange_documentAttributes_( + NSRange::new(0, msg_send![attributed_string, length]), + nil, + ); + if rtfd_data != nil { + state + .pasteboard + .setData_forType(rtfd_data, NSPasteboardTypeRTFD); + } + + let rtf_data = attributed_string.RTFFromRange_documentAttributes_( + NSRange::new(0, attributed_string.length()), + nil, + ); + if rtf_data != nil { + state + .pasteboard + .setData_forType(rtf_data, NSPasteboardTypeRTF); + } + } + + let plain_text = attributed_string.string(); state .pasteboard - .setData_forType(hash_bytes, state.text_hash_pasteboard_type); - - let metadata_bytes = NSData::dataWithBytes_length_( - nil, - metadata.as_ptr() as *const c_void, - metadata.len() as u64, - ); - state - .pasteboard - .setData_forType(metadata_bytes, state.metadata_pasteboard_type); + .setString_forType(plain_text, NSPasteboardTypeString); } } } fn read_from_clipboard(&self) -> Option { let state = self.0.lock(); - unsafe { - if let Some(text_bytes) = - self.read_from_pasteboard(state.pasteboard, NSPasteboardTypeString) - { - let text = String::from_utf8_lossy(text_bytes).to_string(); - let hash_bytes = self - .read_from_pasteboard(state.pasteboard, state.text_hash_pasteboard_type) - .and_then(|bytes| bytes.try_into().ok()) - .map(u64::from_be_bytes); - let metadata_bytes = self - .read_from_pasteboard(state.pasteboard, state.metadata_pasteboard_type) - .and_then(|bytes| String::from_utf8(bytes.to_vec()).ok()); + let pasteboard = state.pasteboard; - if let Some((hash, metadata)) = hash_bytes.zip(metadata_bytes) { - if hash == ClipboardItem::text_hash(&text) { - Some(ClipboardItem { - text, - metadata: Some(metadata), - }) - } else { - Some(ClipboardItem { - text, - metadata: None, - }) - } + // First, see if it's a string. + unsafe { + let types: id = pasteboard.types(); + let string_type: id = ns_string("public.utf8-plain-text"); + + if msg_send![types, containsObject: string_type] { + let data = pasteboard.dataForType(string_type); + if data == nil { + return None; + } else if data.bytes().is_null() { + // https://developer.apple.com/documentation/foundation/nsdata/1410616-bytes?language=objc + // "If the length of the NSData object is 0, this property returns nil." + return Some(self.read_string_from_clipboard(&state, &[])); } else { - Some(ClipboardItem { - text, - metadata: None, - }) + let bytes = + slice::from_raw_parts(data.bytes() as *mut u8, data.length() as usize); + + return Some(self.read_string_from_clipboard(&state, bytes)); + } + } + + // If it wasn't a string, try the various supported image types. + for format in ImageFormat::iter() { + if let Some(item) = try_clipboard_image(pasteboard, format) { + return Some(item); } - } else { - None } } + + // If it wasn't a string or a supported image type, give up. + None } fn write_credentials(&self, url: &str, username: &str, password: &[u8]) -> Task> { @@ -1038,6 +1081,110 @@ impl Platform for MacPlatform { } } +impl MacPlatform { + unsafe fn read_string_from_clipboard( + &self, + state: &MacPlatformState, + text_bytes: &[u8], + ) -> ClipboardItem { + let text = String::from_utf8_lossy(text_bytes).to_string(); + let metadata = self + .read_from_pasteboard(state.pasteboard, state.text_hash_pasteboard_type) + .and_then(|hash_bytes| { + let hash_bytes = hash_bytes.try_into().ok()?; + let hash = u64::from_be_bytes(hash_bytes); + let metadata = + self.read_from_pasteboard(state.pasteboard, state.metadata_pasteboard_type)?; + + if hash == ClipboardString::text_hash(&text) { + String::from_utf8(metadata.to_vec()).ok() + } else { + None + } + }); + + ClipboardItem { + entries: vec![ClipboardEntry::String(ClipboardString { text, metadata })], + } + } + + unsafe fn write_plaintext_to_clipboard(&self, string: &ClipboardString) { + let state = self.0.lock(); + state.pasteboard.clearContents(); + + let text_bytes = NSData::dataWithBytes_length_( + nil, + string.text.as_ptr() as *const c_void, + string.text.len() as u64, + ); + state + .pasteboard + .setData_forType(text_bytes, NSPasteboardTypeString); + + if let Some(metadata) = string.metadata.as_ref() { + let hash_bytes = ClipboardString::text_hash(&string.text).to_be_bytes(); + let hash_bytes = NSData::dataWithBytes_length_( + nil, + hash_bytes.as_ptr() as *const c_void, + hash_bytes.len() as u64, + ); + state + .pasteboard + .setData_forType(hash_bytes, state.text_hash_pasteboard_type); + + let metadata_bytes = NSData::dataWithBytes_length_( + nil, + metadata.as_ptr() as *const c_void, + metadata.len() as u64, + ); + state + .pasteboard + .setData_forType(metadata_bytes, state.metadata_pasteboard_type); + } + } + + unsafe fn write_image_to_clipboard(&self, image: &Image) { + let state = self.0.lock(); + state.pasteboard.clearContents(); + + let bytes = NSData::dataWithBytes_length_( + nil, + image.bytes.as_ptr() as *const c_void, + image.bytes.len() as u64, + ); + + state + .pasteboard + .setData_forType(bytes, Into::::into(image.format).inner_mut()); + } +} + +fn try_clipboard_image(pasteboard: id, format: ImageFormat) -> Option { + let mut ut_type: UTType = format.into(); + + unsafe { + let types: id = pasteboard.types(); + if msg_send![types, containsObject: ut_type.inner()] { + let data = pasteboard.dataForType(ut_type.inner_mut()); + if data == nil { + None + } else { + let bytes = Vec::from(slice::from_raw_parts( + data.bytes() as *mut u8, + data.length() as usize, + )); + let id = hash(&bytes); + + Some(ClipboardItem { + entries: vec![ClipboardEntry::Image(Image { format, bytes, id })], + }) + } + } else { + None + } + } +} + unsafe fn path_from_objc(path: id) -> PathBuf { let len = msg_send![path, lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; let bytes = path.UTF8String() as *const u8; @@ -1216,6 +1363,68 @@ mod security { pub const errSecItemNotFound: OSStatus = -25300; } +impl From for UTType { + fn from(value: ImageFormat) -> Self { + match value { + ImageFormat::Png => Self::png(), + ImageFormat::Jpeg => Self::jpeg(), + ImageFormat::Tiff => Self::tiff(), + ImageFormat::Webp => Self::webp(), + ImageFormat::Gif => Self::gif(), + ImageFormat::Bmp => Self::bmp(), + ImageFormat::Svg => Self::svg(), + } + } +} + +// See https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/ +struct UTType(id); + +impl UTType { + pub fn png() -> Self { + // https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/png + Self(unsafe { NSPasteboardTypePNG }) // This is a rare case where there's a built-in NSPasteboardType + } + + pub fn jpeg() -> Self { + // https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/jpeg + Self(unsafe { ns_string("public.jpeg") }) + } + + pub fn gif() -> Self { + // https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/gif + Self(unsafe { ns_string("com.compuserve.gif") }) + } + + pub fn webp() -> Self { + // https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/webp + Self(unsafe { ns_string("org.webmproject.webp") }) + } + + pub fn bmp() -> Self { + // https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/bmp + Self(unsafe { ns_string("com.microsoft.bmp") }) + } + + pub fn svg() -> Self { + // https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/svg + Self(unsafe { ns_string("public.svg-image") }) + } + + pub fn tiff() -> Self { + // https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/tiff + Self(unsafe { NSPasteboardTypeTIFF }) // This is a rare case where there's a built-in NSPasteboardType + } + + fn inner(&self) -> *const Object { + self.0 + } + + fn inner_mut(&mut self) -> *mut Object { + self.0 as *mut _ + } +} + #[cfg(test)] mod tests { use crate::ClipboardItem; @@ -1227,11 +1436,15 @@ mod tests { let platform = build_platform(); assert_eq!(platform.read_from_clipboard(), None); - let item = ClipboardItem::new("1".to_string()); + let item = ClipboardItem::new_string("1".to_string()); platform.write_to_clipboard(item.clone()); assert_eq!(platform.read_from_clipboard(), Some(item)); - let item = ClipboardItem::new("2".to_string()).with_metadata(vec![3, 4]); + let item = ClipboardItem { + entries: vec![ClipboardEntry::String( + ClipboardString::new("2".to_string()).with_json_metadata(vec![3, 4]), + )], + }; platform.write_to_clipboard(item.clone()); assert_eq!(platform.read_from_clipboard(), Some(item)); @@ -1250,7 +1463,7 @@ mod tests { } assert_eq!( platform.read_from_clipboard(), - Some(ClipboardItem::new(text_from_other_app.to_string())) + Some(ClipboardItem::new_string(text_from_other_app.to_string())) ); } diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index edd69d4dc9..b05f6806ef 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -735,12 +735,17 @@ fn write_to_clipboard_inner( unsafe { OpenClipboard(None)?; EmptyClipboard()?; - let encode_wide = item.text.encode_utf16().chain(Some(0)).collect_vec(); + let encode_wide = item + .text() + .unwrap_or_default() + .encode_utf16() + .chain(Some(0)) + .collect_vec(); set_data_to_clipboard(&encode_wide, CF_UNICODETEXT.0 as u32)?; - if let Some(ref metadata) = item.metadata { + if let Some((metadata, text)) = item.metadata().zip(item.text()) { let hash_result = { - let hash = ClipboardItem::text_hash(&item.text); + let hash = ClipboardString::text_hash(&text); hash.to_ne_bytes() }; let encode_wide = std::slice::from_raw_parts(hash_result.as_ptr().cast::(), 4); @@ -778,20 +783,17 @@ fn read_from_clipboard_inner(hash_format: u32, metadata_format: u32) -> Result, pub(crate) monochrome_sprites: Vec, pub(crate) polychrome_sprites: Vec, - pub(crate) surfaces: Vec, + pub(crate) surfaces: Vec, } impl Scene { @@ -183,7 +183,7 @@ pub(crate) enum Primitive { Underline(Underline), MonochromeSprite(MonochromeSprite), PolychromeSprite(PolychromeSprite), - Surface(Surface), + Surface(PaintSurface), } impl Primitive { @@ -231,9 +231,9 @@ struct BatchIterator<'a> { polychrome_sprites: &'a [PolychromeSprite], polychrome_sprites_start: usize, polychrome_sprites_iter: Peekable>, - surfaces: &'a [Surface], + surfaces: &'a [PaintSurface], surfaces_start: usize, - surfaces_iter: Peekable>, + surfaces_iter: Peekable>, } impl<'a> Iterator for BatchIterator<'a> { @@ -411,7 +411,7 @@ pub(crate) enum PrimitiveBatch<'a> { texture_id: AtlasTextureId, sprites: &'a [PolychromeSprite], }, - Surfaces(&'a [Surface]), + Surfaces(&'a [PaintSurface]), } #[derive(Default, Debug, Clone, Eq, PartialEq)] @@ -673,7 +673,7 @@ impl From for Primitive { } #[derive(Clone, Debug, Eq, PartialEq)] -pub(crate) struct Surface { +pub(crate) struct PaintSurface { pub order: DrawOrder, pub bounds: Bounds, pub content_mask: ContentMask, @@ -681,20 +681,20 @@ pub(crate) struct Surface { pub image_buffer: media::core_video::CVImageBuffer, } -impl Ord for Surface { +impl Ord for PaintSurface { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.order.cmp(&other.order) } } -impl PartialOrd for Surface { +impl PartialOrd for PaintSurface { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl From for Primitive { - fn from(surface: Surface) -> Self { +impl From for Primitive { + fn from(surface: PaintSurface) -> Self { Primitive::Surface(surface) } } diff --git a/crates/gpui/src/style.rs b/crates/gpui/src/style.rs index 0d23a96206..086be8f58f 100644 --- a/crates/gpui/src/style.rs +++ b/crates/gpui/src/style.rs @@ -5,10 +5,10 @@ use std::{ }; use crate::{ - black, phi, point, quad, rems, AbsoluteLength, Bounds, ContentMask, Corners, CornersRefinement, - CursorStyle, DefiniteLength, Edges, EdgesRefinement, Font, FontFallbacks, FontFeatures, - FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba, SharedString, Size, - SizeRefinement, Styled, TextRun, WindowContext, + black, phi, point, quad, rems, size, AbsoluteLength, Bounds, ContentMask, Corners, + CornersRefinement, CursorStyle, DefiniteLength, DevicePixels, Edges, EdgesRefinement, Font, + FontFallbacks, FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, + PointRefinement, Rgba, SharedString, Size, SizeRefinement, Styled, TextRun, WindowContext, }; use collections::HashSet; use refineable::Refineable; @@ -27,6 +27,121 @@ pub struct DebugBelow; #[cfg(debug_assertions)] impl crate::Global for DebugBelow {} +/// How to fit the image into the bounds of the element. +pub enum ObjectFit { + /// The image will be stretched to fill the bounds of the element. + Fill, + /// The image will be scaled to fit within the bounds of the element. + Contain, + /// The image will be scaled to cover the bounds of the element. + Cover, + /// The image will be scaled down to fit within the bounds of the element. + ScaleDown, + /// The image will maintain its original size. + None, +} + +impl ObjectFit { + /// Get the bounds of the image within the given bounds. + pub fn get_bounds( + &self, + bounds: Bounds, + image_size: Size, + ) -> Bounds { + let image_size = image_size.map(|dimension| Pixels::from(u32::from(dimension))); + let image_ratio = image_size.width / image_size.height; + let bounds_ratio = bounds.size.width / bounds.size.height; + + let result_bounds = match self { + ObjectFit::Fill => bounds, + ObjectFit::Contain => { + let new_size = if bounds_ratio > image_ratio { + size( + image_size.width * (bounds.size.height / image_size.height), + bounds.size.height, + ) + } else { + size( + bounds.size.width, + image_size.height * (bounds.size.width / image_size.width), + ) + }; + + Bounds { + origin: point( + bounds.origin.x + (bounds.size.width - new_size.width) / 2.0, + bounds.origin.y + (bounds.size.height - new_size.height) / 2.0, + ), + size: new_size, + } + } + ObjectFit::ScaleDown => { + // Check if the image is larger than the bounds in either dimension. + if image_size.width > bounds.size.width || image_size.height > bounds.size.height { + // If the image is larger, use the same logic as Contain to scale it down. + let new_size = if bounds_ratio > image_ratio { + size( + image_size.width * (bounds.size.height / image_size.height), + bounds.size.height, + ) + } else { + size( + bounds.size.width, + image_size.height * (bounds.size.width / image_size.width), + ) + }; + + Bounds { + origin: point( + bounds.origin.x + (bounds.size.width - new_size.width) / 2.0, + bounds.origin.y + (bounds.size.height - new_size.height) / 2.0, + ), + size: new_size, + } + } else { + // If the image is smaller than or equal to the container, display it at its original size, + // centered within the container. + let original_size = size(image_size.width, image_size.height); + Bounds { + origin: point( + bounds.origin.x + (bounds.size.width - original_size.width) / 2.0, + bounds.origin.y + (bounds.size.height - original_size.height) / 2.0, + ), + size: original_size, + } + } + } + ObjectFit::Cover => { + let new_size = if bounds_ratio > image_ratio { + size( + bounds.size.width, + image_size.height * (bounds.size.width / image_size.width), + ) + } else { + size( + image_size.width * (bounds.size.height / image_size.height), + bounds.size.height, + ) + }; + + Bounds { + origin: point( + bounds.origin.x + (bounds.size.width - new_size.width) / 2.0, + bounds.origin.y + (bounds.size.height - new_size.height) / 2.0, + ), + size: new_size, + } + } + ObjectFit::None => Bounds { + origin: bounds.origin, + size: image_size, + }, + }; + + result_bounds + } +} + /// The CSS styling that can be applied to an element via the `Styled` trait #[derive(Clone, Refineable, Debug)] #[refineable(Debug)] diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 1cfbe0dbae..ae454ae022 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -1,26 +1,25 @@ use crate::{ - hash, point, prelude::*, px, size, transparent_black, Action, AnyDrag, AnyElement, AnyTooltip, + point, prelude::*, px, size, transparent_black, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, Arena, Asset, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, Decorations, DevicePixels, DispatchActionListener, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter, - FileDropEvent, Flatten, FontId, GPUSpecs, Global, GlobalElementId, GlyphId, Hsla, ImageData, - InputHandler, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke, - KeystrokeEvent, LayoutId, LineLayoutIndex, Model, ModelContext, Modifiers, - ModifiersChangedEvent, MonochromeSprite, MouseButton, MouseEvent, MouseMoveEvent, MouseUpEvent, - Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, - PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, - RenderImageParams, RenderSvgParams, Replay, ResizeEdge, ScaledPixels, Scene, Shadow, - SharedString, Size, StrikethroughStyle, Style, SubscriberSet, Subscription, TaffyLayoutEngine, - Task, TextStyle, TextStyleRefinement, TransformationMatrix, Underline, UnderlineStyle, View, - VisualContext, WeakView, WindowAppearance, WindowBackgroundAppearance, WindowBounds, - WindowControls, WindowDecorations, WindowOptions, WindowParams, WindowTextSystem, - SUBPIXEL_VARIANTS, + FileDropEvent, Flatten, FontId, GPUSpecs, Global, GlobalElementId, GlyphId, Hsla, InputHandler, + IsZero, KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke, KeystrokeEvent, LayoutId, + LineLayoutIndex, Model, ModelContext, Modifiers, ModifiersChangedEvent, MonochromeSprite, + MouseButton, MouseEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, + PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, + PromptLevel, Quad, Render, RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, + Replay, ResizeEdge, ScaledPixels, Scene, Shadow, SharedString, Size, StrikethroughStyle, Style, + SubscriberSet, Subscription, TaffyLayoutEngine, Task, TextStyle, TextStyleRefinement, + TransformationMatrix, Underline, UnderlineStyle, View, VisualContext, WeakView, + WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowControls, WindowDecorations, + WindowOptions, WindowParams, WindowTextSystem, SUBPIXEL_VARIANTS, }; use anyhow::{anyhow, Context as _, Result}; use collections::{FxHashMap, FxHashSet}; use derive_more::{Deref, DerefMut}; use futures::channel::oneshot; -use futures::{future::Shared, FutureExt}; +use futures::FutureExt; #[cfg(target_os = "macos")] use media::core_video::CVImageBuffer; use parking_lot::RwLock; @@ -1956,36 +1955,6 @@ impl<'a> WindowContext<'a> { self.window.requested_autoscroll.take() } - /// Remove an asset from GPUI's cache - pub fn remove_cached_asset( - &mut self, - source: &A::Source, - ) -> Option { - self.asset_cache.remove::(source) - } - - /// Asynchronously load an asset, if the asset hasn't finished loading this will return None. - /// Your view will be re-drawn once the asset has finished loading. - /// - /// Note that the multiple calls to this method will only result in one `Asset::load` call. - /// The results of that call will be cached, and returned on subsequent uses of this API. - /// - /// Use [Self::remove_cached_asset] to reload your asset. - pub fn use_cached_asset( - &mut self, - source: &A::Source, - ) -> Option { - self.asset_cache.get::(source).or_else(|| { - if let Some(asset) = self.use_asset::(source) { - self.asset_cache - .insert::(source.to_owned(), asset.clone()); - Some(asset) - } else { - None - } - }) - } - /// Asynchronously load an asset, if the asset hasn't finished loading this will return None. /// Your view will be re-drawn once the asset has finished loading. /// @@ -1994,19 +1963,7 @@ impl<'a> WindowContext<'a> { /// /// This asset will not be cached by default, see [Self::use_cached_asset] pub fn use_asset(&mut self, source: &A::Source) -> Option { - let asset_id = (TypeId::of::(), hash(source)); - let mut is_first = false; - let task = self - .loading_assets - .remove(&asset_id) - .map(|boxed_task| *boxed_task.downcast::>>().unwrap()) - .unwrap_or_else(|| { - is_first = true; - let future = A::load(source.clone(), self); - let task = self.background_executor().spawn(future).shared(); - task - }); - + let (task, is_first) = self.fetch_asset::(source); task.clone().now_or_never().or_else(|| { if is_first { let parent_id = self.parent_view_id(); @@ -2027,12 +1984,9 @@ impl<'a> WindowContext<'a> { .detach(); } - self.loading_assets.insert(asset_id, Box::new(task)); - None }) } - /// Obtain the current element offset. This method should only be called during the /// prepaint phase of element drawing. pub fn element_offset(&self) -> Point { @@ -2610,13 +2564,14 @@ impl<'a> WindowContext<'a> { } /// Paint an image into the scene for the next frame at the current z-index. + /// This method will panic if the frame_index is not valid /// /// This method should only be called as part of the paint phase of element drawing. pub fn paint_image( &mut self, bounds: Bounds, corner_radii: Corners, - data: Arc, + data: Arc, frame_index: usize, grayscale: bool, ) -> Result<()> { @@ -2639,7 +2594,10 @@ impl<'a> WindowContext<'a> { .get_or_insert_with(¶ms.clone().into(), &mut || { Ok(Some(( data.size(frame_index), - Cow::Borrowed(data.as_bytes(frame_index)), + Cow::Borrowed( + data.as_bytes(frame_index) + .expect("It's the caller's job to pass a valid frame index"), + ), ))) })? .expect("Callback above only returns Some"); @@ -2665,6 +2623,8 @@ impl<'a> WindowContext<'a> { /// This method should only be called as part of the paint phase of element drawing. #[cfg(target_os = "macos")] pub fn paint_surface(&mut self, bounds: Bounds, image_buffer: CVImageBuffer) { + use crate::PaintSurface; + debug_assert_eq!( self.window.draw_phase, DrawPhase::Paint, @@ -2674,15 +2634,12 @@ impl<'a> WindowContext<'a> { let scale_factor = self.scale_factor(); let bounds = bounds.scale(scale_factor); let content_mask = self.content_mask().scale(scale_factor); - self.window - .next_frame - .scene - .insert_primitive(crate::Surface { - order: 0, - bounds, - content_mask, - image_buffer, - }); + self.window.next_frame.scene.insert_primitive(PaintSurface { + order: 0, + bounds, + content_mask, + image_buffer, + }); } #[must_use] diff --git a/crates/language_model/Cargo.toml b/crates/language_model/Cargo.toml index 90f9943f17..ef273ac44f 100644 --- a/crates/language_model/Cargo.toml +++ b/crates/language_model/Cargo.toml @@ -50,6 +50,9 @@ theme.workspace = true tiktoken-rs.workspace = true ui.workspace = true util.workspace = true +base64.workspace = true +image.workspace = true + [dev-dependencies] ctor.workspace = true diff --git a/crates/language_model/src/provider/anthropic.rs b/crates/language_model/src/provider/anthropic.rs index d65b789dc9..2445430775 100644 --- a/crates/language_model/src/provider/anthropic.rs +++ b/crates/language_model/src/provider/anthropic.rs @@ -221,24 +221,44 @@ pub fn count_anthropic_tokens( ) -> BoxFuture<'static, Result> { cx.background_executor() .spawn(async move { - let messages = request - .messages - .into_iter() - .map(|message| tiktoken_rs::ChatCompletionRequestMessage { - role: match message.role { - Role::User => "user".into(), - Role::Assistant => "assistant".into(), - Role::System => "system".into(), - }, - content: Some(message.content), - name: None, - function_call: None, - }) - .collect::>(); + let messages = request.messages; + let mut tokens_from_images = 0; + let mut string_messages = Vec::with_capacity(messages.len()); + + for message in messages { + use crate::MessageContent; + + let mut string_contents = String::new(); + + for content in message.content { + match content { + MessageContent::Text(string) => { + string_contents.push_str(&string); + } + MessageContent::Image(image) => { + tokens_from_images += image.estimate_tokens(); + } + } + } + + if !string_contents.is_empty() { + string_messages.push(tiktoken_rs::ChatCompletionRequestMessage { + role: match message.role { + Role::User => "user".into(), + Role::Assistant => "assistant".into(), + Role::System => "system".into(), + }, + content: Some(string_contents), + name: None, + function_call: None, + }); + } + } // Tiktoken doesn't yet support these models, so we manually use the // same tokenizer as GPT-4. - tiktoken_rs::num_tokens_from_messages("gpt-4", &messages) + tiktoken_rs::num_tokens_from_messages("gpt-4", &string_messages) + .map(|tokens| tokens + tokens_from_images) }) .boxed() } diff --git a/crates/language_model/src/provider/copilot_chat.rs b/crates/language_model/src/provider/copilot_chat.rs index a0bdc3beab..e1fc35ed75 100644 --- a/crates/language_model/src/provider/copilot_chat.rs +++ b/crates/language_model/src/provider/copilot_chat.rs @@ -193,7 +193,7 @@ impl LanguageModel for CopilotChatLanguageModel { cx: &AsyncAppContext, ) -> BoxFuture<'static, Result>>> { if let Some(message) = request.messages.last() { - if message.content.trim().is_empty() { + if message.contents_empty() { const EMPTY_PROMPT_MSG: &str = "Empty prompts aren't allowed. Please provide a non-empty prompt."; return futures::future::ready(Err(anyhow::anyhow!(EMPTY_PROMPT_MSG))).boxed(); @@ -270,7 +270,7 @@ impl CopilotChatLanguageModel { Role::Assistant => CopilotChatRole::Assistant, Role::System => CopilotChatRole::System, }, - content: msg.content, + content: msg.string_contents(), }) .collect(), ) diff --git a/crates/language_model/src/provider/ollama.rs b/crates/language_model/src/provider/ollama.rs index fcf253c7a6..88bc21791f 100644 --- a/crates/language_model/src/provider/ollama.rs +++ b/crates/language_model/src/provider/ollama.rs @@ -182,14 +182,14 @@ impl OllamaLanguageModel { .into_iter() .map(|msg| match msg.role { Role::User => ChatMessage::User { - content: msg.content, + content: msg.string_contents(), }, Role::Assistant => ChatMessage::Assistant { - content: msg.content, + content: msg.string_contents(), tool_calls: None, }, Role::System => ChatMessage::System { - content: msg.content, + content: msg.string_contents(), }, }) .collect(), @@ -257,7 +257,7 @@ impl LanguageModel for OllamaLanguageModel { let token_count = request .messages .iter() - .map(|msg| msg.content.chars().count()) + .map(|msg| msg.string_contents().chars().count()) .sum::() / 4; diff --git a/crates/language_model/src/provider/open_ai.rs b/crates/language_model/src/provider/open_ai.rs index 1d696d28ca..c8b99d8ff0 100644 --- a/crates/language_model/src/provider/open_ai.rs +++ b/crates/language_model/src/provider/open_ai.rs @@ -363,7 +363,7 @@ pub fn count_open_ai_tokens( Role::Assistant => "assistant".into(), Role::System => "system".into(), }, - content: Some(message.content), + content: Some(message.string_contents()), name: None, function_call: None, }) diff --git a/crates/language_model/src/request.rs b/crates/language_model/src/request.rs index 6cc8db3a88..7a545dd814 100644 --- a/crates/language_model/src/request.rs +++ b/crates/language_model/src/request.rs @@ -1,10 +1,223 @@ +use std::io::{Cursor, Write}; + use crate::role::Role; +use base64::write::EncoderWriter; +use gpui::{point, size, AppContext, DevicePixels, Image, ObjectFit, RenderImage, Size, Task}; +use image::{codecs::png::PngEncoder, imageops::resize, DynamicImage, ImageDecoder}; use serde::{Deserialize, Serialize}; +use ui::{px, SharedString}; +use util::ResultExt; + +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug, Hash)] +pub struct LanguageModelImage { + // A base64 encoded PNG image + pub source: SharedString, + size: Size, +} + +const ANTHROPIC_SIZE_LIMT: f32 = 1568.0; // Anthropic wants uploaded images to be smaller than this in both dimensions + +impl LanguageModelImage { + pub fn from_image(data: Image, cx: &mut AppContext) -> Task> { + cx.background_executor().spawn(async move { + match data.format() { + gpui::ImageFormat::Png + | gpui::ImageFormat::Jpeg + | gpui::ImageFormat::Webp + | gpui::ImageFormat::Gif => {} + _ => return None, + }; + + let image = image::codecs::png::PngDecoder::new(Cursor::new(data.bytes())).log_err()?; + let (width, height) = image.dimensions(); + let image_size = size(DevicePixels(width as i32), DevicePixels(height as i32)); + + let mut base64_image = Vec::new(); + + { + let mut base64_encoder = EncoderWriter::new( + Cursor::new(&mut base64_image), + &base64::engine::general_purpose::STANDARD, + ); + + if image_size.width.0 > ANTHROPIC_SIZE_LIMT as i32 + || image_size.height.0 > ANTHROPIC_SIZE_LIMT as i32 + { + let new_bounds = ObjectFit::ScaleDown.get_bounds( + gpui::Bounds { + origin: point(px(0.0), px(0.0)), + size: size(px(ANTHROPIC_SIZE_LIMT), px(ANTHROPIC_SIZE_LIMT)), + }, + image_size, + ); + let image = DynamicImage::from_decoder(image).log_err()?.resize( + new_bounds.size.width.0 as u32, + new_bounds.size.height.0 as u32, + image::imageops::FilterType::Triangle, + ); + + let mut png = Vec::new(); + image + .write_with_encoder(PngEncoder::new(&mut png)) + .log_err()?; + + base64_encoder.write_all(png.as_slice()).log_err()?; + } else { + base64_encoder.write_all(data.bytes()).log_err()?; + } + } + + // SAFETY: The base64 encoder should not produce non-UTF8 + let source = unsafe { String::from_utf8_unchecked(base64_image) }; + + Some(LanguageModelImage { + size: image_size, + source: source.into(), + }) + }) + } + + /// Resolves image into an LLM-ready format (base64) + pub fn from_render_image(data: &RenderImage) -> Option { + let image_size = data.size(0); + + let mut bytes = data.as_bytes(0).unwrap_or(&[]).to_vec(); + // Convert from BGRA to RGBA. + for pixel in bytes.chunks_exact_mut(4) { + pixel.swap(2, 0); + } + let mut image = image::RgbaImage::from_vec( + image_size.width.0 as u32, + image_size.height.0 as u32, + bytes, + ) + .expect("We already know this works"); + + // https://docs.anthropic.com/en/docs/build-with-claude/vision + if image_size.width.0 > ANTHROPIC_SIZE_LIMT as i32 + || image_size.height.0 > ANTHROPIC_SIZE_LIMT as i32 + { + let new_bounds = ObjectFit::ScaleDown.get_bounds( + gpui::Bounds { + origin: point(px(0.0), px(0.0)), + size: size(px(ANTHROPIC_SIZE_LIMT), px(ANTHROPIC_SIZE_LIMT)), + }, + image_size, + ); + + image = resize( + &image, + new_bounds.size.width.0 as u32, + new_bounds.size.height.0 as u32, + image::imageops::FilterType::Triangle, + ); + } + + let mut png = Vec::new(); + + image + .write_with_encoder(PngEncoder::new(&mut png)) + .log_err()?; + + let mut base64_image = Vec::new(); + + { + let mut base64_encoder = EncoderWriter::new( + Cursor::new(&mut base64_image), + &base64::engine::general_purpose::STANDARD, + ); + + base64_encoder.write_all(png.as_slice()).log_err()?; + } + + // SAFETY: The base64 encoder should not produce non-UTF8 + let source = unsafe { String::from_utf8_unchecked(base64_image) }; + + Some(LanguageModelImage { + size: image_size, + source: source.into(), + }) + } + + pub fn estimate_tokens(&self) -> usize { + let width = self.size.width.0.unsigned_abs() as usize; + let height = self.size.height.0.unsigned_abs() as usize; + + // From: https://docs.anthropic.com/en/docs/build-with-claude/vision#calculate-image-costs + // Note that are a lot of conditions on anthropic's API, and OpenAI doesn't use this, + // so this method is more of a rough guess + (width * height) / 750 + } +} + +#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)] +pub enum MessageContent { + Text(String), + Image(LanguageModelImage), +} + +impl std::fmt::Debug for MessageContent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + MessageContent::Text(t) => f.debug_struct("MessageContent").field("text", t).finish(), + MessageContent::Image(i) => f + .debug_struct("MessageContent") + .field("image", &i.source.len()) + .finish(), + } + } +} + +impl MessageContent { + pub fn as_string(&self) -> &str { + match self { + MessageContent::Text(s) => s.as_str(), + MessageContent::Image(_) => "", + } + } +} + +impl From for MessageContent { + fn from(value: String) -> Self { + MessageContent::Text(value) + } +} + +impl From<&str> for MessageContent { + fn from(value: &str) -> Self { + MessageContent::Text(value.to_string()) + } +} #[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Hash)] pub struct LanguageModelRequestMessage { pub role: Role, - pub content: String, + pub content: Vec, +} + +impl LanguageModelRequestMessage { + pub fn string_contents(&self) -> String { + let mut string_buffer = String::new(); + for string in self.content.iter().filter_map(|content| match content { + MessageContent::Text(s) => Some(s), + MessageContent::Image(_) => None, + }) { + string_buffer.push_str(string.as_str()) + } + string_buffer + } + + pub fn contents_empty(&self) -> bool { + self.content.is_empty() + || self + .content + .get(0) + .map(|content| match content { + MessageContent::Text(s) => s.is_empty(), + MessageContent::Image(_) => true, + }) + .unwrap_or(false) + } } #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)] @@ -23,14 +236,14 @@ impl LanguageModelRequest { .into_iter() .map(|msg| match msg.role { Role::User => open_ai::RequestMessage::User { - content: msg.content, + content: msg.string_contents(), }, Role::Assistant => open_ai::RequestMessage::Assistant { - content: Some(msg.content), + content: Some(msg.string_contents()), tool_calls: Vec::new(), }, Role::System => open_ai::RequestMessage::System { - content: msg.content, + content: msg.string_contents(), }, }) .collect(), @@ -51,7 +264,7 @@ impl LanguageModelRequest { .into_iter() .map(|msg| google_ai::Content { parts: vec![google_ai::Part::TextPart(google_ai::TextPart { - text: msg.content, + text: msg.string_contents(), })], role: match msg.role { Role::User => google_ai::Role::User, @@ -77,7 +290,7 @@ impl LanguageModelRequest { let mut system_message = String::new(); for message in self.messages { - if message.content.is_empty() { + if message.contents_empty() { continue; } @@ -85,8 +298,11 @@ impl LanguageModelRequest { Role::User | Role::Assistant => { if let Some(last_message) = new_messages.last_mut() { if last_message.role == message.role { - last_message.content.push_str("\n\n"); - last_message.content.push_str(&message.content); + // TODO: is this append done properly? + last_message.content.push(MessageContent::Text(format!( + "\n\n{}", + message.string_contents() + ))); continue; } } @@ -97,7 +313,7 @@ impl LanguageModelRequest { if !system_message.is_empty() { system_message.push_str("\n\n"); } - system_message.push_str(&message.content); + system_message.push_str(&message.string_contents()); } } } @@ -113,9 +329,24 @@ impl LanguageModelRequest { Role::Assistant => anthropic::Role::Assistant, Role::System => return None, }, - content: vec![anthropic::Content::Text { - text: message.content, - }], + content: message + .content + .into_iter() + // TODO: filter out the empty messages in the message construction step + .filter_map(|content| match content { + MessageContent::Text(t) if !t.is_empty() => { + Some(anthropic::Content::Text { text: t }) + } + MessageContent::Image(i) => Some(anthropic::Content::Image { + source: anthropic::ImageSource { + source_type: "base64".to_string(), + media_type: "image/png".to_string(), + data: i.source.to_string(), + }, + }), + _ => None, + }) + .collect(), }) }) .collect(), diff --git a/crates/live_kit_client/src/test.rs b/crates/live_kit_client/src/test.rs index a0193478dd..3449d887dc 100644 --- a/crates/live_kit_client/src/test.rs +++ b/crates/live_kit_client/src/test.rs @@ -3,7 +3,7 @@ use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use collections::{btree_map::Entry as BTreeEntry, hash_map::Entry, BTreeMap, HashMap, HashSet}; use futures::Stream; -use gpui::{BackgroundExecutor, ImageSource}; +use gpui::{BackgroundExecutor, SurfaceSource}; use live_kit_server::{proto, token}; use parking_lot::Mutex; @@ -870,7 +870,7 @@ impl Frame { self.height } - pub fn image(&self) -> ImageSource { + pub fn image(&self) -> SurfaceSource { unimplemented!("you can't call this in test mode") } } diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index fa2af10ab3..84fbd776d9 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -150,7 +150,7 @@ impl Markdown { return; } let text = text.text_for_range(self.selection.start..self.selection.end); - cx.write_to_clipboard(ClipboardItem::new(text)); + cx.write_to_clipboard(ClipboardItem::new_string(text)); } fn parse(&mut self, cx: &mut ViewContext) { @@ -480,7 +480,7 @@ impl MarkdownElement { { let text = rendered_text .text_for_range(markdown.selection.start..markdown.selection.end); - cx.write_to_primary(ClipboardItem::new(text)) + cx.write_to_primary(ClipboardItem::new_string(text)) } cx.notify(); } diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index bfdbfb8eab..9b4044d86c 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -1067,7 +1067,7 @@ impl OutlinePanel { .and_then(|entry| self.abs_path(&entry, cx)) .map(|p| p.to_string_lossy().to_string()) { - cx.write_to_clipboard(ClipboardItem::new(clipboard_text)); + cx.write_to_clipboard(ClipboardItem::new_string(clipboard_text)); } } @@ -1082,7 +1082,7 @@ impl OutlinePanel { }) .map(|p| p.to_string_lossy().to_string()) { - cx.write_to_clipboard(ClipboardItem::new(clipboard_text)); + cx.write_to_clipboard(ClipboardItem::new_string(clipboard_text)); } } diff --git a/crates/paths/src/paths.rs b/crates/paths/src/paths.rs index 1ecf5aa46d..d0726dabc5 100644 --- a/crates/paths/src/paths.rs +++ b/crates/paths/src/paths.rs @@ -170,6 +170,12 @@ pub fn contexts_dir() -> &'static PathBuf { }) } +/// Returns the path within the contexts directory where images from contexts are stored. +pub fn context_images_dir() -> &'static PathBuf { + static CONTEXT_IMAGES_DIR: OnceLock = OnceLock::new(); + CONTEXT_IMAGES_DIR.get_or_init(|| contexts_dir().join("images")) +} + /// Returns the path to the contexts directory. /// /// This is where the prompts for use with the Assistant are stored. diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index d4fa0eff41..d9202fab07 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1357,7 +1357,7 @@ impl ProjectPanel { fn copy_path(&mut self, _: &CopyPath, cx: &mut ViewContext) { if let Some((worktree, entry)) = self.selected_entry(cx) { - cx.write_to_clipboard(ClipboardItem::new( + cx.write_to_clipboard(ClipboardItem::new_string( worktree .abs_path() .join(&entry.path) @@ -1369,7 +1369,9 @@ impl ProjectPanel { fn copy_relative_path(&mut self, _: &CopyRelativePath, cx: &mut ViewContext) { if let Some((_, entry)) = self.selected_entry(cx) { - cx.write_to_clipboard(ClipboardItem::new(entry.path.to_string_lossy().to_string())); + cx.write_to_clipboard(ClipboardItem::new_string( + entry.path.to_string_lossy().to_string(), + )); } } diff --git a/crates/repl/src/outputs.rs b/crates/repl/src/outputs.rs index 16897e2e45..4182a5b4b6 100644 --- a/crates/repl/src/outputs.rs +++ b/crates/repl/src/outputs.rs @@ -5,7 +5,7 @@ use crate::stdio::TerminalOutput; use anyhow::Result; use base64::prelude::*; use gpui::{ - img, percentage, Animation, AnimationExt, AnyElement, FontWeight, ImageData, Render, Task, + img, percentage, Animation, AnimationExt, AnyElement, FontWeight, Render, RenderImage, Task, TextRun, Transformation, View, }; use runtimelib::datatable::TableSchema; @@ -38,7 +38,7 @@ fn rank_mime_type(mimetype: &MimeType) -> usize { pub struct ImageView { height: u32, width: u32, - image: Arc, + image: Arc, } impl ImageView { @@ -76,7 +76,7 @@ impl ImageView { let height = data.height(); let width = data.width(); - let gpui_image_data = ImageData::new(vec![image::Frame::new(data)]); + let gpui_image_data = RenderImage::new(vec![image::Frame::new(data)]); return Ok(ImageView { height, diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 6210ed55dc..ce6b9bd6ac 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -656,13 +656,17 @@ impl Terminal { cx.emit(Event::BreadcrumbsChanged); } AlacTermEvent::ClipboardStore(_, data) => { - cx.write_to_clipboard(ClipboardItem::new(data.to_string())) + cx.write_to_clipboard(ClipboardItem::new_string(data.to_string())) + } + AlacTermEvent::ClipboardLoad(_, format) => { + self.write_to_pty( + match &cx.read_from_clipboard().and_then(|item| item.text()) { + // The terminal only supports pasting strings, not images. + Some(text) => format(text), + _ => format(""), + }, + ) } - AlacTermEvent::ClipboardLoad(_, format) => self.write_to_pty(format( - &cx.read_from_clipboard() - .map(|ci| ci.text().to_string()) - .unwrap_or_else(|| "".to_string()), - )), AlacTermEvent::PtyWrite(out) => self.write_to_pty(out.clone()), AlacTermEvent::TextAreaSizeRequest(format) => { self.write_to_pty(format(self.last_content.size.into())) @@ -767,7 +771,7 @@ impl Terminal { #[cfg(target_os = "linux")] if let Some(selection_text) = term.selection_to_string() { - cx.write_to_primary(ClipboardItem::new(selection_text)); + cx.write_to_primary(ClipboardItem::new_string(selection_text)); } if let Some((_, head)) = selection { @@ -788,7 +792,7 @@ impl Terminal { #[cfg(target_os = "linux")] if let Some(selection_text) = term.selection_to_string() { - cx.write_to_primary(ClipboardItem::new(selection_text)); + cx.write_to_primary(ClipboardItem::new_string(selection_text)); } self.selection_head = Some(point); @@ -798,7 +802,7 @@ impl Terminal { InternalEvent::Copy => { if let Some(txt) = term.selection_to_string() { - cx.write_to_clipboard(ClipboardItem::new(txt)) + cx.write_to_clipboard(ClipboardItem::new_string(txt)) } } InternalEvent::ScrollToAlacPoint(point) => { @@ -1342,7 +1346,7 @@ impl Terminal { #[cfg(target_os = "linux")] MouseButton::Middle => { if let Some(item) = _cx.read_from_primary() { - let text = item.text().to_string(); + let text = item.text().unwrap_or_default().to_string(); self.input(text); } } diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 27e5dd2481..33d11f8351 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -488,9 +488,9 @@ impl TerminalView { ///Attempt to paste the clipboard into the terminal fn paste(&mut self, _: &Paste, cx: &mut ViewContext) { - if let Some(item) = cx.read_from_clipboard() { + if let Some(clipboard_string) = cx.read_from_clipboard().and_then(|item| item.text()) { self.terminal - .update(cx, |terminal, _cx| terminal.paste(item.text())); + .update(cx, |terminal, _cx| terminal.paste(&clipboard_string)); } } diff --git a/crates/vim/src/normal/paste.rs b/crates/vim/src/normal/paste.rs index e2ddf80408..84f144a16a 100644 --- a/crates/vim/src/normal/paste.rs +++ b/crates/vim/src/normal/paste.rs @@ -361,7 +361,8 @@ mod test { Mode::Normal, ); assert_eq!( - cx.read_from_clipboard().map(|item| item.text().clone()), + cx.read_from_clipboard() + .map(|item| item.text().unwrap().to_string()), Some("jumps".into()) ); cx.simulate_keystrokes("d d p"); @@ -373,10 +374,11 @@ mod test { Mode::Normal, ); assert_eq!( - cx.read_from_clipboard().map(|item| item.text().clone()), + cx.read_from_clipboard() + .map(|item| item.text().unwrap().to_string()), Some("jumps".into()) ); - cx.write_to_clipboard(ClipboardItem::new("test-copy".to_string())); + cx.write_to_clipboard(ClipboardItem::new_string("test-copy".to_string())); cx.simulate_keystrokes("shift-p"); cx.assert_state( indoc! {" diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index 73afdbe1e4..6223aae942 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -5,7 +5,7 @@ use crate::surrounds::SurroundsType; use crate::{motion::Motion, object::Object}; use collections::HashMap; use editor::{Anchor, ClipboardSelection}; -use gpui::{Action, ClipboardItem, KeyContext}; +use gpui::{Action, ClipboardEntry, ClipboardItem, KeyContext}; use language::{CursorShape, Selection, TransactionId}; use serde::{Deserialize, Serialize}; use ui::SharedString; @@ -129,20 +129,24 @@ pub struct Register { impl From for ClipboardItem { fn from(register: Register) -> Self { - let item = ClipboardItem::new(register.text.into()); if let Some(clipboard_selections) = register.clipboard_selections { - item.with_metadata(clipboard_selections) + ClipboardItem::new_string_with_json_metadata(register.text.into(), clipboard_selections) } else { - item + ClipboardItem::new_string(register.text.into()) } } } impl From for Register { - fn from(value: ClipboardItem) -> Self { - Register { - text: value.text().to_owned().into(), - clipboard_selections: value.metadata::>(), + fn from(item: ClipboardItem) -> Self { + // For now, we don't store metadata for multiple entries. + match item.entries().first() { + Some(ClipboardEntry::String(value)) if item.entries().len() == 1 => Register { + text: value.text().to_owned().into(), + clipboard_selections: value.metadata_json::>(), + }, + // For now, registers can't store images. This could change in the future. + _ => Register::default(), } } } diff --git a/crates/vim/src/test/neovim_backed_test_context.rs b/crates/vim/src/test/neovim_backed_test_context.rs index e48b3782b8..075f5621d7 100644 --- a/crates/vim/src/test/neovim_backed_test_context.rs +++ b/crates/vim/src/test/neovim_backed_test_context.rs @@ -247,7 +247,12 @@ impl NeovimBackedTestContext { register: '"', state: self.shared_state().await, neovim: self.neovim.read_register('"').await, - editor: self.read_from_clipboard().unwrap().text().clone(), + editor: self + .read_from_clipboard() + .unwrap() + .text() + .unwrap() + .to_owned(), } } diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index cac66dde0f..26ddca9d85 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -586,7 +586,7 @@ impl Vim { } else { self.workspace_state.last_yank = cx .read_from_clipboard() - .map(|item| item.text().to_owned().into()); + .and_then(|item| item.text().map(|string| string.into())) } self.workspace_state.registers.insert('"', content.clone()); @@ -663,7 +663,7 @@ impl Vim { fn system_clipboard_is_newer(&self, cx: &mut AppContext) -> bool { cx.read_from_clipboard().is_some_and(|item| { if let Some(last_state) = &self.workspace_state.last_yank { - last_state != item.text() + Some(last_state.as_ref()) != item.text().as_deref() } else { true } diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 8d8f848997..ea0449b249 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -927,7 +927,7 @@ mod test { the lazy dog"}); assert_eq!( cx.read_from_clipboard() - .map(|item| item.text().clone()) + .map(|item| item.text().unwrap().to_string()) .unwrap(), "The q" ); diff --git a/crates/workspace/src/notifications.rs b/crates/workspace/src/notifications.rs index 2cffb83584..03a8e34bce 100644 --- a/crates/workspace/src/notifications.rs +++ b/crates/workspace/src/notifications.rs @@ -342,7 +342,7 @@ impl Render for LanguageServerPrompt { .on_click({ let message = request.message.clone(); move |_, cx| { - cx.write_to_clipboard(ClipboardItem::new( + cx.write_to_clipboard(ClipboardItem::new_string( message.clone(), )) } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 38c368074b..a2956a01a9 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1632,7 +1632,7 @@ impl Pane { .and_then(|entry| entry.project_path(cx)) .map(|p| p.path.to_string_lossy().to_string()) { - cx.write_to_clipboard(ClipboardItem::new(clipboard_text)); + cx.write_to_clipboard(ClipboardItem::new_string(clipboard_text)); } } @@ -1842,7 +1842,7 @@ impl Pane { "Copy Path", Some(Box::new(CopyPath)), cx.handler_for(&pane, move |_, cx| { - cx.write_to_clipboard(ClipboardItem::new( + cx.write_to_clipboard(ClipboardItem::new_string( abs_path.to_string_lossy().to_string(), )); }), diff --git a/crates/workspace/src/shared_screen.rs b/crates/workspace/src/shared_screen.rs index 49af337e09..59df859488 100644 --- a/crates/workspace/src/shared_screen.rs +++ b/crates/workspace/src/shared_screen.rs @@ -7,7 +7,7 @@ use call::participant::{Frame, RemoteVideoTrack}; use client::{proto::PeerId, User}; use futures::StreamExt; use gpui::{ - div, img, AppContext, EventEmitter, FocusHandle, FocusableView, InteractiveElement, + div, surface, AppContext, EventEmitter, FocusHandle, FocusableView, InteractiveElement, ParentElement, Render, SharedString, Styled, Task, View, ViewContext, VisualContext, WindowContext, }; @@ -75,7 +75,7 @@ impl Render for SharedScreen { .children( self.frame .as_ref() - .map(|frame| img(frame.image()).size_full()), + .map(|frame| surface(frame.image()).size_full()), ) } }