Compare commits
6 Commits
zeta-cli-e
...
review-ass
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7ed4de96c | ||
|
|
dae295fc72 | ||
|
|
e1ed35377a | ||
|
|
c707ec1c24 | ||
|
|
a5677a1e93 | ||
|
|
eba6f443fd |
149
Cargo.lock
generated
149
Cargo.lock
generated
@@ -86,7 +86,7 @@ version = "0.25.1-dev"
|
||||
source = "git+https://github.com/zed-industries/alacritty.git?branch=add-hush-login-flag#828457c9ff1f7ea0a0469337cc8a37ee3a1b0590"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"home",
|
||||
"libc",
|
||||
"log",
|
||||
@@ -128,7 +128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43"
|
||||
dependencies = [
|
||||
"alsa-sys",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
@@ -453,6 +453,7 @@ dependencies = [
|
||||
"assistant_slash_command",
|
||||
"assistant_tool",
|
||||
"async-watch",
|
||||
"buffer_diff",
|
||||
"chrono",
|
||||
"client",
|
||||
"clock",
|
||||
@@ -1880,10 +1881,10 @@ version = "0.69.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
@@ -1903,10 +1904,10 @@ version = "0.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.12.1",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
@@ -1961,9 +1962,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -1993,7 +1994,7 @@ source = "git+https://github.com/kvark/blade?rev=b16f5c7bd873c7126f48c82c39e7ae6
|
||||
dependencies = [
|
||||
"ash",
|
||||
"ash-window",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"bytemuck",
|
||||
"codespan-reporting",
|
||||
"glow",
|
||||
@@ -2041,9 +2042,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "1.7.0"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b17679a8d69b6d7fd9cd9801a536cec9fa5e5970b69f9d4747f70b39b031f5e7"
|
||||
checksum = "675f87afced0413c9bb02843499dbbd3882a237645883f71a2b59644a6d2f753"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
@@ -2322,7 +2323,7 @@ version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"log",
|
||||
"polling",
|
||||
"rustix",
|
||||
@@ -2828,7 +2829,7 @@ version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block",
|
||||
"cocoa-foundation 0.2.0",
|
||||
"core-foundation 0.10.0",
|
||||
@@ -2858,7 +2859,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14045fb83be07b5acf1c0884b2180461635b433455fa35d1cd6f17f1450679d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block",
|
||||
"core-foundation 0.10.0",
|
||||
"core-graphics-types 0.2.0",
|
||||
@@ -3327,7 +3328,7 @@ version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation 0.10.0",
|
||||
"core-graphics-types 0.2.0",
|
||||
"foreign-types 0.5.0",
|
||||
@@ -3351,7 +3352,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation 0.10.0",
|
||||
"libc",
|
||||
]
|
||||
@@ -3423,7 +3424,7 @@ version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e418dd4f5128c3e93eab12246391c54a20c496811131f85754dc8152ee207892"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"fontdb 0.16.2",
|
||||
"log",
|
||||
"rangemap",
|
||||
@@ -5076,7 +5077,7 @@ name = "font-kit"
|
||||
version = "0.14.1"
|
||||
source = "git+https://github.com/zed-industries/font-kit?rev=40391b7#40391b7c0041d8a8572af2afa3de32ae088f0120"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"byteorder",
|
||||
"core-foundation 0.9.4",
|
||||
"core-graphics 0.23.2",
|
||||
@@ -5276,7 +5277,7 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
name = "fsevent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation 0.9.4",
|
||||
"fsevent-sys 3.1.0",
|
||||
"parking_lot",
|
||||
@@ -5604,7 +5605,7 @@ version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5220b8ba44c68a9a7f7a7659e864dd73692e417ef0211bea133c7b74e031eeb9"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
@@ -5770,7 +5771,7 @@ version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"gpu-alloc-types",
|
||||
]
|
||||
|
||||
@@ -5791,7 +5792,7 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6103,7 +6104,7 @@ version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd54745cfacb7b97dee45e8fdb91814b62bccddb481debb7de0f9ee6b7bf5b43"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"byteorder",
|
||||
"heed-traits",
|
||||
"heed-types",
|
||||
@@ -6663,9 +6664,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.6"
|
||||
version = "0.25.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
|
||||
checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder-lite",
|
||||
@@ -6840,7 +6841,7 @@ version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
@@ -7581,7 +7582,7 @@ version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"libc",
|
||||
"redox_syscall 0.5.8",
|
||||
]
|
||||
@@ -8220,7 +8221,7 @@ version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block",
|
||||
"core-graphics-types 0.1.3",
|
||||
"foreign-types 0.5.0",
|
||||
@@ -8385,7 +8386,7 @@ checksum = "364f94bc34f61332abebe8cad6f6cd82a5b65cff22c828d05d0968911462ca4f"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bit-set 0.8.0",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cfg_aliases 0.1.1",
|
||||
"codespan-reporting",
|
||||
"hexf-parse",
|
||||
@@ -8454,7 +8455,7 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"ndk-sys",
|
||||
@@ -8489,7 +8490,7 @@ version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cfg-if",
|
||||
"cfg_aliases 0.2.1",
|
||||
"libc",
|
||||
@@ -8573,7 +8574,7 @@ version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"filetime",
|
||||
"fsevent-sys 4.1.0",
|
||||
"inotify",
|
||||
@@ -8591,7 +8592,7 @@ name = "notify"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/zed-industries/notify.git?rev=bbb9ea5ae52b253e095737847e367c30653a2e96#bbb9ea5ae52b253e095737847e367c30653a2e96"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"filetime",
|
||||
"fsevent-sys 4.1.0",
|
||||
"inotify",
|
||||
@@ -8867,7 +8868,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"libc",
|
||||
"objc2",
|
||||
@@ -8883,7 +8884,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-core-location",
|
||||
@@ -8907,7 +8908,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
@@ -8949,7 +8950,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"libc",
|
||||
"objc2",
|
||||
@@ -8973,7 +8974,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
@@ -8985,7 +8986,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
@@ -9008,7 +9009,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-cloud-kit",
|
||||
@@ -9040,7 +9041,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-core-location",
|
||||
@@ -9183,7 +9184,7 @@ version = "0.10.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cfg-if",
|
||||
"foreign-types 0.3.2",
|
||||
"libc",
|
||||
@@ -10712,7 +10713,7 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4"
|
||||
dependencies = [
|
||||
"bytes 1.10.1",
|
||||
"heck 0.4.1",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.12.1",
|
||||
"log",
|
||||
"multimap 0.10.0",
|
||||
"once_cell",
|
||||
@@ -10745,7 +10746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.12.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
@@ -10822,7 +10823,7 @@ version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"memchr",
|
||||
"pulldown-cmark-escape",
|
||||
"unicase",
|
||||
@@ -10834,7 +10835,7 @@ version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
@@ -11215,7 +11216,7 @@ version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11858,7 +11859,7 @@ version = "0.38.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"errno 0.3.10",
|
||||
"itoa",
|
||||
"libc",
|
||||
@@ -12018,7 +12019,7 @@ version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"bytemuck",
|
||||
"libm",
|
||||
"smallvec",
|
||||
@@ -12035,7 +12036,7 @@ version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"bytemuck",
|
||||
"core_maths",
|
||||
"log",
|
||||
@@ -12258,7 +12259,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"any_vec",
|
||||
"anyhow",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"client",
|
||||
"collections",
|
||||
"editor",
|
||||
@@ -12300,7 +12301,7 @@ version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation 0.9.4",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -12313,7 +12314,7 @@ version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation 0.10.0",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -12913,7 +12914,7 @@ version = "0.3.0+sdk-1.3.268.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -13080,7 +13081,7 @@ dependencies = [
|
||||
"atoi",
|
||||
"base64 0.22.1",
|
||||
"bigdecimal",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"byteorder",
|
||||
"bytes 1.10.1",
|
||||
"chrono",
|
||||
@@ -13127,7 +13128,7 @@ dependencies = [
|
||||
"atoi",
|
||||
"base64 0.22.1",
|
||||
"bigdecimal",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"crc",
|
||||
@@ -13589,7 +13590,7 @@ version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation 0.9.4",
|
||||
"system-configuration-sys 0.6.0",
|
||||
]
|
||||
@@ -13633,7 +13634,7 @@ version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc4592f674ce18521c2a81483873a49596655b179f71c5e05d10c1fe66c78745"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cap-fs-ext",
|
||||
"cap-std",
|
||||
"fd-lock",
|
||||
@@ -14453,7 +14454,7 @@ version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"bytes 1.10.1",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@@ -15366,7 +15367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5924018406ce0063cd67f8e008104968b74b563ee1b85dde3ed1f7cb87d3dbd"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"cursor-icon",
|
||||
"log",
|
||||
"memchr",
|
||||
@@ -15590,7 +15591,7 @@ version = "0.201.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"indexmap",
|
||||
"semver",
|
||||
]
|
||||
@@ -15601,7 +15602,7 @@ version = "0.221.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d06bfa36ab3ac2be0dee563380147a5b81ba10dd8885d7fbbc9eb574be67d185"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"hashbrown 0.15.2",
|
||||
"indexmap",
|
||||
"semver",
|
||||
@@ -15627,7 +15628,7 @@ checksum = "11976a250672556d1c4c04c6d5d7656ac9192ac9edc42a4587d6c21460010e69"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"bumpalo",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
@@ -15833,7 +15834,7 @@ checksum = "8d1be69bfcab1bdac74daa7a1f9695ab992b9c8e21b9b061e7d66434097e0ca4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"bytes 1.10.1",
|
||||
"cap-fs-ext",
|
||||
"cap-net-ext",
|
||||
@@ -15914,7 +15915,7 @@ version = "0.31.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"rustix",
|
||||
"wayland-backend",
|
||||
"wayland-scanner",
|
||||
@@ -15937,7 +15938,7 @@ version = "0.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-scanner",
|
||||
@@ -15949,7 +15950,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
@@ -16116,7 +16117,7 @@ checksum = "4b9af35bc9629c52c261465320a9a07959164928b4241980ba1cf923b9e6751d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"thiserror 1.0.69",
|
||||
"tracing",
|
||||
"wasmtime",
|
||||
@@ -16731,7 +16732,7 @@ version = "0.36.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f3fd376f71958b862e7afb20cfe5a22830e1963462f3a17f49d82a6c1d1f42d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
@@ -16750,7 +16751,7 @@ version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "288f992ea30e6b5c531b52cdd5f3be81c148554b09ea416f058d16556ba92c27"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"wit-bindgen-rt 0.22.0",
|
||||
"wit-bindgen-rust-macro",
|
||||
]
|
||||
@@ -16777,7 +16778,7 @@ version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -16815,7 +16816,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "421c0c848a0660a8c22e2fd217929a0191f14476b68962afd2af89fd22e39825"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
@@ -16834,7 +16835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66c55ca8772d2b270e28066caed50ce4e53a28c3ac10e01efbd90e5be31e448b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
@@ -17077,7 +17078,7 @@ name = "xim-parser"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/XDeme1/xim-rs?rev=d50d461764c2213655cd9cf65a0ea94c70d3c4fd#d50d461764c2213655cd9cf65a0ea94c70d3c4fd"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -25,6 +25,7 @@ assistant_settings.workspace = true
|
||||
assistant_slash_command.workspace = true
|
||||
assistant_tool.workspace = true
|
||||
async-watch.workspace = true
|
||||
buffer_diff.workspace = true
|
||||
chrono.workspace = true
|
||||
client.workspace = true
|
||||
clock.workspace = true
|
||||
@@ -85,6 +86,7 @@ workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
buffer_diff = { workspace = true, features = ["test-support"] }
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
gpui = { workspace = true, "features" = ["test-support"] }
|
||||
indoc.workspace = true
|
||||
|
||||
@@ -521,6 +521,10 @@ impl ActiveThread {
|
||||
}
|
||||
}
|
||||
ThreadEvent::CheckpointChanged => cx.notify(),
|
||||
ThreadEvent::DiffChanged => {
|
||||
// todo!("update list of changed files")
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ mod profile_selector;
|
||||
mod terminal_codegen;
|
||||
mod terminal_inline_assistant;
|
||||
mod thread;
|
||||
mod thread_diff;
|
||||
mod thread_history;
|
||||
mod thread_store;
|
||||
mod tool_use;
|
||||
@@ -36,6 +37,7 @@ use crate::assistant_configuration::{AddContextServerModal, ManageProfilesModal}
|
||||
pub use crate::assistant_panel::{AssistantPanel, ConcreteAssistantPanelDelegate};
|
||||
pub use crate::inline_assistant::InlineAssistant;
|
||||
pub use crate::thread::{Message, RequestKind, Thread, ThreadEvent};
|
||||
pub(crate) use crate::thread_diff::*;
|
||||
pub use crate::thread_store::ThreadStore;
|
||||
|
||||
actions!(
|
||||
@@ -60,7 +62,8 @@ actions!(
|
||||
FocusRight,
|
||||
RemoveFocusedContext,
|
||||
AcceptSuggestedContext,
|
||||
OpenActiveThreadAsMarkdown
|
||||
OpenActiveThreadAsMarkdown,
|
||||
ShowThreadDiff
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ use crate::context_strip::{ContextStrip, ContextStripEvent, SuggestContextKind};
|
||||
use crate::profile_selector::ProfileSelector;
|
||||
use crate::thread::{RequestKind, Thread};
|
||||
use crate::thread_store::ThreadStore;
|
||||
use crate::{Chat, ChatMode, RemoveAllContext, ThreadEvent, ToggleContextPicker};
|
||||
use crate::{Chat, ChatMode, RemoveAllContext, ShowThreadDiff, ThreadEvent, ToggleContextPicker};
|
||||
|
||||
pub struct MessageEditor {
|
||||
thread: Entity<Thread>,
|
||||
@@ -152,6 +152,32 @@ impl MessageEditor {
|
||||
) {
|
||||
self.context_picker_menu_handle.toggle(window, cx);
|
||||
}
|
||||
|
||||
fn show_thread_diff(
|
||||
&mut self,
|
||||
_: &ShowThreadDiff,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
};
|
||||
let diff_source = Arc::new(self.thread.read(cx).diff_source(cx));
|
||||
let project_diff = cx.new(|cx| {
|
||||
git_ui::project_diff::ProjectDiff::new(
|
||||
diff_source,
|
||||
self.project.clone(),
|
||||
workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item_to_active_pane(Box::new(project_diff), None, true, window, cx)
|
||||
});
|
||||
}
|
||||
|
||||
pub fn remove_all_context(
|
||||
&mut self,
|
||||
_: &RemoveAllContext,
|
||||
@@ -565,6 +591,7 @@ impl Render for MessageEditor {
|
||||
this.model_selector
|
||||
.update(cx, |model_selector, cx| model_selector.toggle(window, cx));
|
||||
}))
|
||||
.on_action(cx.listener(Self::show_thread_diff))
|
||||
.on_action(cx.listener(Self::toggle_context_picker))
|
||||
.on_action(cx.listener(Self::remove_all_context))
|
||||
.on_action(cx.listener(Self::move_up))
|
||||
|
||||
@@ -34,6 +34,7 @@ use crate::thread_store::{
|
||||
SerializedToolUse,
|
||||
};
|
||||
use crate::tool_use::{PendingToolUse, ToolUse, ToolUseState};
|
||||
use crate::{ChangeAuthor, ThreadDiff, ThreadDiffSource};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum RequestKind {
|
||||
@@ -181,6 +182,7 @@ pub struct Thread {
|
||||
completion_count: usize,
|
||||
pending_completions: Vec<PendingCompletion>,
|
||||
project: Entity<Project>,
|
||||
git_store: Entity<GitStore>,
|
||||
prompt_builder: Arc<PromptBuilder>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
tool_use: ToolUseState,
|
||||
@@ -190,6 +192,7 @@ pub struct Thread {
|
||||
initial_project_snapshot: Shared<Task<Option<Arc<ProjectSnapshot>>>>,
|
||||
cumulative_token_usage: TokenUsage,
|
||||
feedback: Option<ThreadFeedback>,
|
||||
diff: Entity<ThreadDiff>,
|
||||
}
|
||||
|
||||
impl Thread {
|
||||
@@ -213,6 +216,7 @@ impl Thread {
|
||||
completion_count: 0,
|
||||
pending_completions: Vec::new(),
|
||||
project: project.clone(),
|
||||
git_store: project.read(cx).git_store().clone(),
|
||||
prompt_builder,
|
||||
tools: tools.clone(),
|
||||
last_restore_checkpoint: None,
|
||||
@@ -220,13 +224,14 @@ impl Thread {
|
||||
tool_use: ToolUseState::new(tools.clone()),
|
||||
action_log: cx.new(|_| ActionLog::new()),
|
||||
initial_project_snapshot: {
|
||||
let project_snapshot = Self::project_snapshot(project, cx);
|
||||
let project_snapshot = Self::project_snapshot(project.clone(), cx);
|
||||
cx.foreground_executor()
|
||||
.spawn(async move { Some(project_snapshot.await) })
|
||||
.shared()
|
||||
},
|
||||
cumulative_token_usage: TokenUsage::default(),
|
||||
feedback: None,
|
||||
diff: cx.new(|cx| ThreadDiff::new(project.clone(), cx)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,6 +285,8 @@ impl Thread {
|
||||
pending_completions: Vec::new(),
|
||||
last_restore_checkpoint: None,
|
||||
pending_checkpoint: None,
|
||||
diff: cx.new(|cx| ThreadDiff::new(project.clone(), cx)),
|
||||
git_store: project.read(cx).git_store().clone(),
|
||||
project,
|
||||
prompt_builder,
|
||||
tools,
|
||||
@@ -356,6 +363,15 @@ impl Thread {
|
||||
!self.tool_use.pending_tool_uses().is_empty()
|
||||
}
|
||||
|
||||
pub fn diff_source(&self, cx: &App) -> ThreadDiffSource {
|
||||
let project = self.project.read(cx);
|
||||
ThreadDiffSource::new(
|
||||
self.diff.clone(),
|
||||
project.git_store().clone(),
|
||||
project.languages().clone(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn checkpoint_for_message(&self, id: MessageId) -> Option<ThreadCheckpoint> {
|
||||
self.checkpoints_by_message.get(&id).cloned()
|
||||
}
|
||||
@@ -1231,17 +1247,37 @@ impl Thread {
|
||||
tool: Arc<dyn Tool>,
|
||||
cx: &mut Context<Thread>,
|
||||
) -> Task<()> {
|
||||
let run_tool = tool.run(
|
||||
input,
|
||||
messages,
|
||||
self.project.clone(),
|
||||
self.action_log.clone(),
|
||||
cx,
|
||||
);
|
||||
let diff = self.diff.clone();
|
||||
let git_store = self.git_store.clone();
|
||||
let checkpoint = git_store.read(cx).checkpoint(cx);
|
||||
let messages = messages.to_vec();
|
||||
let project = self.project.clone();
|
||||
let action_log = self.action_log.clone();
|
||||
|
||||
cx.spawn({
|
||||
async move |thread: WeakEntity<Thread>, cx| {
|
||||
let output = run_tool.await;
|
||||
if let Ok(checkpoint) = checkpoint.await {
|
||||
diff.update(cx, |diff, cx| {
|
||||
diff.compute_changes(ChangeAuthor::User, checkpoint)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
let Ok(output) =
|
||||
cx.update(|cx| tool.run(input, &messages, project, action_log, cx))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let output = output.await;
|
||||
|
||||
if let Ok(checkpoint) = git_store.read_with(cx, |git, cx| git.checkpoint(cx)) {
|
||||
if let Ok(checkpoint) = checkpoint.await {
|
||||
diff.update(cx, |diff, cx| {
|
||||
diff.compute_changes(ChangeAuthor::Agent, checkpoint)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
thread
|
||||
.update(cx, |thread, cx| {
|
||||
@@ -1562,6 +1598,7 @@ pub enum ThreadEvent {
|
||||
canceled: bool,
|
||||
},
|
||||
CheckpointChanged,
|
||||
DiffChanged,
|
||||
ToolConfirmationNeeded,
|
||||
}
|
||||
|
||||
|
||||
219
crates/assistant2/src/thread_diff.rs
Normal file
219
crates/assistant2/src/thread_diff.rs
Normal file
@@ -0,0 +1,219 @@
|
||||
use anyhow::{Context as _, Result};
|
||||
use buffer_diff::BufferDiff;
|
||||
use collections::HashMap;
|
||||
use futures::{channel::mpsc, future::Shared, FutureExt, StreamExt};
|
||||
use gpui::{prelude::*, App, Entity, Subscription, Task};
|
||||
use language::{Buffer, LanguageRegistry};
|
||||
use project::{
|
||||
git_store::{GitStore, GitStoreCheckpoint, GitStoreIndex, GitStoreStatus},
|
||||
Project,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use util::TryFutureExt;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum ChangeAuthor {
|
||||
User,
|
||||
Agent,
|
||||
}
|
||||
|
||||
pub struct ThreadDiff {
|
||||
base: Shared<Task<Option<GitStoreIndex>>>,
|
||||
diffs_by_buffer: HashMap<Entity<Buffer>, Entity<BufferDiff>>,
|
||||
status: GitStoreStatus,
|
||||
project: Entity<Project>,
|
||||
git_store: Entity<GitStore>,
|
||||
checkpoints_tx: mpsc::UnboundedSender<(ChangeAuthor, GitStoreCheckpoint)>,
|
||||
update_status_tx: async_watch::Sender<()>,
|
||||
_subscription: Subscription,
|
||||
_maintain_status: Task<Result<()>>,
|
||||
_maintain_diff: Task<Result<()>>,
|
||||
}
|
||||
|
||||
impl ThreadDiff {
|
||||
pub fn new(project: Entity<Project>, cx: &mut Context<Self>) -> Self {
|
||||
let git_store = project.read(cx).git_store().clone();
|
||||
let (checkpoints_tx, mut checkpoints_rx) = mpsc::unbounded();
|
||||
let (update_status_tx, mut update_status_rx) = async_watch::channel(());
|
||||
let checkpoint = git_store.read(cx).checkpoint(cx);
|
||||
let base = cx
|
||||
.background_spawn(
|
||||
project
|
||||
.read(cx)
|
||||
.git_store()
|
||||
.read(cx)
|
||||
.create_index(cx)
|
||||
.log_err(),
|
||||
)
|
||||
.shared();
|
||||
Self {
|
||||
base: base.clone(),
|
||||
status: GitStoreStatus::default(),
|
||||
diffs_by_buffer: HashMap::default(),
|
||||
git_store: git_store.clone(),
|
||||
project,
|
||||
checkpoints_tx,
|
||||
update_status_tx,
|
||||
_subscription: cx.subscribe(&git_store, |this, _git_store, event, _cx| {
|
||||
if let project::git_store::GitEvent::FileSystemUpdated = event {
|
||||
this.update_status_tx.send(()).ok();
|
||||
}
|
||||
}),
|
||||
_maintain_status: cx.spawn({
|
||||
let git_store = git_store.clone();
|
||||
let base = base.clone();
|
||||
async move |this, cx| {
|
||||
let base = base.await.context("failed to create base")?;
|
||||
while let Ok(()) = update_status_rx.recv().await {
|
||||
let status = git_store
|
||||
.read_with(cx, |store, cx| store.status(Some(base.clone()), cx))?
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
this.update(cx, |this, cx| this.set_status(status, cx))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}),
|
||||
_maintain_diff: cx.spawn(async move |this, cx| {
|
||||
let mut last_checkpoint = checkpoint.await.ok();
|
||||
let base = base.await.context("failed to create base")?;
|
||||
while let Some((author, checkpoint)) = checkpoints_rx.next().await {
|
||||
if let Some(last_checkpoint) = last_checkpoint {
|
||||
if author == ChangeAuthor::User {
|
||||
let diff = git_store
|
||||
.read_with(cx, |store, cx| {
|
||||
store.diff_checkpoints(last_checkpoint, checkpoint.clone(), cx)
|
||||
})?
|
||||
.await;
|
||||
|
||||
if let Ok(diff) = diff {
|
||||
_ = git_store
|
||||
.read_with(cx, |store, cx| {
|
||||
store.apply_diff(base.clone(), diff, cx)
|
||||
})?
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
this.update(cx, |this, _cx| this.update_status_tx.send(()).ok())?;
|
||||
}
|
||||
|
||||
last_checkpoint = Some(checkpoint);
|
||||
}
|
||||
Ok(())
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_changes(&mut self, author: ChangeAuthor, checkpoint: GitStoreCheckpoint) {
|
||||
_ = self.checkpoints_tx.unbounded_send((author, checkpoint));
|
||||
}
|
||||
|
||||
fn set_status(&mut self, status: GitStoreStatus, cx: &mut Context<Self>) {
|
||||
self.status = status;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ThreadDiffSource {
|
||||
thread_diff: Entity<ThreadDiff>,
|
||||
git_store: Entity<GitStore>,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
}
|
||||
|
||||
impl ThreadDiffSource {
|
||||
pub fn new(
|
||||
thread_diff: Entity<ThreadDiff>,
|
||||
git_store: Entity<GitStore>,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
) -> Self {
|
||||
Self {
|
||||
thread_diff,
|
||||
git_store,
|
||||
language_registry,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl git_ui::project_diff::DiffSource for ThreadDiffSource {
|
||||
fn observe(&self, cx: &mut App, mut f: Box<dyn FnMut(&mut App) + Send>) -> Subscription {
|
||||
cx.observe(&self.thread_diff, move |_, cx| f(cx))
|
||||
}
|
||||
|
||||
fn status(&self, cx: &App) -> Vec<git_ui::project_diff::StatusEntry> {
|
||||
let mut results = Vec::new();
|
||||
|
||||
for (repo, repo_path, status) in self
|
||||
.thread_diff
|
||||
.read(cx)
|
||||
.status
|
||||
.entries(&self.git_store, cx)
|
||||
{
|
||||
let Some(project_path) = repo.read(cx).repo_path_to_project_path(repo_path, cx) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let status = match *status {
|
||||
git::status::FileStatus::Tracked(mut tracked_status) => {
|
||||
if tracked_status.worktree_status == git::status::StatusCode::Unmodified {
|
||||
continue;
|
||||
} else {
|
||||
tracked_status.index_status = git::status::StatusCode::Unmodified;
|
||||
git::status::FileStatus::Tracked(tracked_status)
|
||||
}
|
||||
}
|
||||
status @ _ => status,
|
||||
};
|
||||
|
||||
results.push(git_ui::project_diff::StatusEntry {
|
||||
project_path,
|
||||
status,
|
||||
has_conflict: false,
|
||||
});
|
||||
}
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
fn open_uncommitted_diff(
|
||||
&self,
|
||||
buffer: Entity<Buffer>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<Entity<BufferDiff>>> {
|
||||
let base = self.thread_diff.read(cx).base.clone();
|
||||
let git_store = self.git_store.clone();
|
||||
let language_registry = self.language_registry.clone();
|
||||
let thread_diff = self.thread_diff.clone();
|
||||
cx.spawn(async move |cx| {
|
||||
let base = base.await.context("failed to load diff base")?;
|
||||
let base_text = git_store
|
||||
.read_with(cx, |git, cx| git.load_index_text(Some(base), &buffer, cx))?
|
||||
.await;
|
||||
let snapshot = buffer.read_with(cx, |buffer, _cx| buffer.snapshot())?;
|
||||
|
||||
let diff = thread_diff.update(cx, |thread_diff, cx| {
|
||||
thread_diff
|
||||
.diffs_by_buffer
|
||||
.entry(buffer.clone())
|
||||
.or_insert_with(|| cx.new(|cx| BufferDiff::new(&snapshot, cx)))
|
||||
.clone()
|
||||
})?;
|
||||
let base_text = Arc::new(base_text.unwrap_or_default());
|
||||
let diff_snapshot = BufferDiff::update_diff(
|
||||
diff.clone(),
|
||||
snapshot.text.clone(),
|
||||
Some(base_text),
|
||||
true,
|
||||
false,
|
||||
snapshot.language().cloned(),
|
||||
Some(language_registry),
|
||||
cx,
|
||||
)
|
||||
.await?;
|
||||
diff.update(cx, |diff, cx| {
|
||||
diff.set_snapshot(&snapshot, diff_snapshot, false, None, cx);
|
||||
})?;
|
||||
Ok(diff)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1308,7 +1308,7 @@ impl GitRepository for RealGitRepository {
|
||||
.spawn(async move {
|
||||
let working_directory = working_directory?;
|
||||
let git = GitBinary::new(git_binary_path, working_directory, executor);
|
||||
git.run(&[
|
||||
git.run_raw(&[
|
||||
"diff",
|
||||
"--find-renames",
|
||||
"--patch",
|
||||
@@ -1463,7 +1463,7 @@ impl GitBinary {
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
let mut stdout = self.run_raw(args).await?;
|
||||
if stdout.chars().last() == Some('\n') {
|
||||
if stdout.ends_with('\n') {
|
||||
stdout.pop();
|
||||
}
|
||||
Ok(stdout)
|
||||
|
||||
@@ -26,7 +26,11 @@ use project::{
|
||||
git_store::{GitEvent, GitStore},
|
||||
Project, ProjectPath,
|
||||
};
|
||||
use std::any::{Any, TypeId};
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
};
|
||||
use theme::ActiveTheme;
|
||||
use ui::{prelude::*, vertical_divider, KeyBinding, Tooltip};
|
||||
use util::ResultExt as _;
|
||||
@@ -39,7 +43,67 @@ use workspace::{
|
||||
|
||||
actions!(git, [Diff, Add]);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StatusEntry {
|
||||
pub project_path: ProjectPath,
|
||||
pub status: FileStatus,
|
||||
pub has_conflict: bool,
|
||||
}
|
||||
|
||||
pub trait DiffSource {
|
||||
fn observe(&self, cx: &mut App, f: Box<dyn FnMut(&mut App) + Send>) -> Subscription;
|
||||
fn status(&self, cx: &App) -> Vec<StatusEntry>;
|
||||
fn open_uncommitted_diff(
|
||||
&self,
|
||||
buffer: Entity<Buffer>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<Entity<BufferDiff>>>;
|
||||
}
|
||||
|
||||
pub struct ProjectDiffSource(Entity<Project>);
|
||||
|
||||
impl DiffSource for ProjectDiffSource {
|
||||
fn observe(&self, cx: &mut App, mut f: Box<dyn FnMut(&mut App) + Send>) -> Subscription {
|
||||
let git_store = self.0.read(cx).git_store().clone();
|
||||
cx.subscribe(&git_store, move |_git_store, event, cx| match event {
|
||||
GitEvent::ActiveRepositoryChanged
|
||||
| GitEvent::FileSystemUpdated
|
||||
| GitEvent::GitStateUpdated => f(cx),
|
||||
_ => {}
|
||||
})
|
||||
}
|
||||
|
||||
fn status(&self, cx: &App) -> Vec<StatusEntry> {
|
||||
let mut result = Vec::new();
|
||||
if let Some(git_repo) = self.0.read(cx).git_store().read(cx).active_repository() {
|
||||
let git_repo = git_repo.read(cx);
|
||||
for entry in git_repo.cached_status() {
|
||||
if let Some(project_path) = git_repo.repo_path_to_project_path(&entry.repo_path, cx)
|
||||
{
|
||||
let has_conflict = git_repo.has_conflict(&entry.repo_path);
|
||||
result.push(StatusEntry {
|
||||
project_path,
|
||||
status: entry.status,
|
||||
has_conflict,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn open_uncommitted_diff(
|
||||
&self,
|
||||
buffer: Entity<Buffer>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<Entity<BufferDiff>>> {
|
||||
self.0
|
||||
.update(cx, |project, cx| project.open_uncommitted_diff(buffer, cx))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProjectDiff {
|
||||
source: Arc<dyn DiffSource>,
|
||||
project: Entity<Project>,
|
||||
multibuffer: Entity<MultiBuffer>,
|
||||
editor: Entity<Editor>,
|
||||
@@ -102,8 +166,16 @@ impl ProjectDiff {
|
||||
existing
|
||||
} else {
|
||||
let workspace_handle = cx.entity();
|
||||
let project_diff =
|
||||
cx.new(|cx| Self::new(workspace.project().clone(), workspace_handle, window, cx));
|
||||
let source = Arc::new(ProjectDiffSource(workspace.project().clone()));
|
||||
let project_diff = cx.new(|cx| {
|
||||
Self::new(
|
||||
source,
|
||||
workspace.project().clone(),
|
||||
workspace_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
workspace.add_item_to_active_pane(
|
||||
Box::new(project_diff.clone()),
|
||||
None,
|
||||
@@ -126,7 +198,8 @@ impl ProjectDiff {
|
||||
})
|
||||
}
|
||||
|
||||
fn new(
|
||||
pub fn new(
|
||||
source: Arc<dyn DiffSource>,
|
||||
project: Entity<Project>,
|
||||
workspace: Entity<Workspace>,
|
||||
window: &mut Window,
|
||||
@@ -149,17 +222,16 @@ impl ProjectDiff {
|
||||
.detach();
|
||||
|
||||
let git_store = project.read(cx).git_store().clone();
|
||||
let git_store_subscription = cx.subscribe_in(
|
||||
&git_store,
|
||||
window,
|
||||
move |this, _git_store, event, _window, _cx| match event {
|
||||
GitEvent::ActiveRepositoryChanged
|
||||
| GitEvent::FileSystemUpdated
|
||||
| GitEvent::GitStateUpdated => {
|
||||
*this.update_needed.borrow_mut() = ();
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
let weak_this = cx.weak_entity();
|
||||
let diff_source_subscription = source.observe(
|
||||
cx,
|
||||
Box::new(move |cx| {
|
||||
weak_this
|
||||
.update(cx, |this, _| {
|
||||
*this.update_needed.borrow_mut() = ();
|
||||
})
|
||||
.ok();
|
||||
}),
|
||||
);
|
||||
|
||||
let (mut send, recv) = postage::watch::channel::<()>();
|
||||
@@ -171,6 +243,7 @@ impl ProjectDiff {
|
||||
*send.borrow_mut() = ();
|
||||
|
||||
Self {
|
||||
source,
|
||||
project,
|
||||
git_store: git_store.clone(),
|
||||
workspace: workspace.downgrade(),
|
||||
@@ -181,7 +254,7 @@ impl ProjectDiff {
|
||||
update_needed: send,
|
||||
current_branch: None,
|
||||
_task: worker,
|
||||
_subscription: git_store_subscription,
|
||||
_subscription: diff_source_subscription,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,56 +401,53 @@ impl ProjectDiff {
|
||||
}
|
||||
|
||||
fn load_buffers(&mut self, cx: &mut Context<Self>) -> Vec<Task<Result<DiffBuffer>>> {
|
||||
let Some(repo) = self.git_store.read(cx).active_repository() else {
|
||||
self.multibuffer.update(cx, |multibuffer, cx| {
|
||||
multibuffer.clear(cx);
|
||||
});
|
||||
return vec![];
|
||||
};
|
||||
|
||||
let mut previous_paths = self.multibuffer.read(cx).paths().collect::<HashSet<_>>();
|
||||
|
||||
let mut result = vec![];
|
||||
repo.update(cx, |repo, cx| {
|
||||
for entry in repo.cached_status() {
|
||||
if !entry.status.has_changes() {
|
||||
continue;
|
||||
}
|
||||
let Some(project_path) = repo.repo_path_to_project_path(&entry.repo_path, cx)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let namespace = if repo.has_conflict(&entry.repo_path) {
|
||||
CONFLICT_NAMESPACE
|
||||
} else if entry.status.is_created() {
|
||||
NEW_NAMESPACE
|
||||
} else {
|
||||
TRACKED_NAMESPACE
|
||||
};
|
||||
let path_key = PathKey::namespaced(namespace, entry.repo_path.0.clone());
|
||||
|
||||
previous_paths.remove(&path_key);
|
||||
let load_buffer = self
|
||||
.project
|
||||
.update(cx, |project, cx| project.open_buffer(project_path, cx));
|
||||
|
||||
let project = self.project.clone();
|
||||
result.push(cx.spawn(async move |_, cx| {
|
||||
let buffer = load_buffer.await?;
|
||||
let changes = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_uncommitted_diff(buffer.clone(), cx)
|
||||
})?
|
||||
.await?;
|
||||
Ok(DiffBuffer {
|
||||
path_key,
|
||||
buffer,
|
||||
diff: changes,
|
||||
file_status: entry.status,
|
||||
})
|
||||
}));
|
||||
for entry in self.source.status(cx) {
|
||||
if !entry.status.has_changes() {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
|
||||
let Some(worktree) = self
|
||||
.project
|
||||
.read(cx)
|
||||
.worktree_for_id(entry.project_path.worktree_id, cx)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let full_path =
|
||||
Arc::from(Path::new(worktree.read(cx).root_name()).join(&entry.project_path.path));
|
||||
|
||||
let namespace = if entry.has_conflict {
|
||||
CONFLICT_NAMESPACE
|
||||
} else if entry.status.is_created() {
|
||||
NEW_NAMESPACE
|
||||
} else {
|
||||
TRACKED_NAMESPACE
|
||||
};
|
||||
let path_key = PathKey::namespaced(namespace, full_path);
|
||||
|
||||
previous_paths.remove(&path_key);
|
||||
let load_buffer = self.project.update(cx, |project, cx| {
|
||||
project.open_buffer(entry.project_path, cx)
|
||||
});
|
||||
|
||||
let source = self.source.clone();
|
||||
result.push(cx.spawn(async move |_, cx| {
|
||||
let buffer = load_buffer.await?;
|
||||
let changes = cx
|
||||
.update(|cx| source.open_uncommitted_diff(buffer.clone(), cx))?
|
||||
.await?;
|
||||
Ok(DiffBuffer {
|
||||
path_key,
|
||||
buffer,
|
||||
diff: changes,
|
||||
file_status: entry.status,
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
||||
self.multibuffer.update(cx, |multibuffer, cx| {
|
||||
for path in previous_paths {
|
||||
multibuffer.remove_excerpts_for_path(path, cx);
|
||||
@@ -586,7 +656,15 @@ impl Item for ProjectDiff {
|
||||
Self: Sized,
|
||||
{
|
||||
let workspace = self.workspace.upgrade()?;
|
||||
Some(cx.new(|cx| ProjectDiff::new(self.project.clone(), workspace, window, cx)))
|
||||
Some(cx.new(|cx| {
|
||||
ProjectDiff::new(
|
||||
self.source.clone(),
|
||||
self.project.clone(),
|
||||
workspace,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}))
|
||||
}
|
||||
|
||||
fn is_dirty(&self, cx: &App) -> bool {
|
||||
@@ -744,7 +822,7 @@ impl SerializableItem for ProjectDiff {
|
||||
}
|
||||
|
||||
fn deserialize(
|
||||
_project: Entity<Project>,
|
||||
project: Entity<Project>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
_workspace_id: workspace::WorkspaceId,
|
||||
_item_id: workspace::ItemId,
|
||||
@@ -754,7 +832,16 @@ impl SerializableItem for ProjectDiff {
|
||||
window.spawn(cx, async move |cx| {
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
let workspace_handle = cx.entity();
|
||||
cx.new(|cx| Self::new(workspace.project().clone(), workspace_handle, window, cx))
|
||||
let diff = Arc::new(ProjectDiffSource(project));
|
||||
cx.new(|cx| {
|
||||
Self::new(
|
||||
diff,
|
||||
workspace.project().clone(),
|
||||
workspace_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1338,8 +1425,9 @@ mod tests {
|
||||
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let source = Arc::new(ProjectDiffSource(project.clone()));
|
||||
let diff = cx.new_window_entity(|window, cx| {
|
||||
ProjectDiff::new(project.clone(), workspace, window, cx)
|
||||
ProjectDiff::new(source, project.clone(), workspace, window, cx)
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
@@ -1392,8 +1480,9 @@ mod tests {
|
||||
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let source = Arc::new(ProjectDiffSource(project.clone()));
|
||||
let diff = cx.new_window_entity(|window, cx| {
|
||||
ProjectDiff::new(project.clone(), workspace, window, cx)
|
||||
ProjectDiff::new(source, project.clone(), workspace, window, cx)
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
@@ -1465,6 +1554,7 @@ mod tests {
|
||||
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let source = Arc::new(ProjectDiffSource(project.clone()));
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/project/foo"), cx)
|
||||
@@ -1475,7 +1565,7 @@ mod tests {
|
||||
Editor::for_buffer(buffer, Some(project.clone()), window, cx)
|
||||
});
|
||||
let diff = cx.new_window_entity(|window, cx| {
|
||||
ProjectDiff::new(project.clone(), workspace, window, cx)
|
||||
ProjectDiff::new(source, project.clone(), workspace, window, cx)
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
|
||||
@@ -158,10 +158,45 @@ pub struct GitStoreIndex {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GitStoreStatus {
|
||||
#[allow(dead_code)]
|
||||
statuses_by_work_dir_abs_path: HashMap<PathBuf, GitStatus>,
|
||||
}
|
||||
|
||||
impl GitStoreStatus {
|
||||
pub fn entries<'a>(
|
||||
&'a self,
|
||||
git_store: &Entity<GitStore>,
|
||||
cx: &App,
|
||||
) -> impl 'a + Iterator<Item = (Entity<Repository>, &'a RepoPath, &'a FileStatus)> {
|
||||
let repositories_by_work_dir_abs_path = git_store
|
||||
.read(cx)
|
||||
.repositories
|
||||
.values()
|
||||
.map(|repo| {
|
||||
(
|
||||
repo.read(cx)
|
||||
.repository_entry
|
||||
.work_directory_abs_path
|
||||
.clone(),
|
||||
repo.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
self.statuses_by_work_dir_abs_path
|
||||
.iter()
|
||||
.flat_map(move |(work_dir_abs_path, status)| {
|
||||
status
|
||||
.entries
|
||||
.iter()
|
||||
.map(move |(repo_path, status)| (work_dir_abs_path, repo_path, status))
|
||||
})
|
||||
.filter_map(move |(work_dir_abs_path, repo_path, status)| {
|
||||
let repository = repositories_by_work_dir_abs_path.get(work_dir_abs_path)?;
|
||||
Some((repository.clone(), repo_path, status))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Repository {
|
||||
pub repository_entry: RepositoryEntry,
|
||||
pub merge_message: Option<String>,
|
||||
@@ -790,7 +825,11 @@ impl GitStore {
|
||||
.diff_checkpoints(base_checkpoint, target_checkpoint);
|
||||
tasks.push(async move {
|
||||
let diff = diff.await??;
|
||||
anyhow::Ok((work_dir_abs_path, diff))
|
||||
if diff.is_empty() {
|
||||
anyhow::Ok(None)
|
||||
} else {
|
||||
anyhow::Ok(Some((work_dir_abs_path, diff)))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -799,7 +838,10 @@ impl GitStore {
|
||||
cx.background_spawn(async move {
|
||||
let diffs_by_path = future::try_join_all(tasks).await?;
|
||||
Ok(GitStoreDiff {
|
||||
diffs_by_work_dir_abs_path: diffs_by_path.into_iter().collect(),
|
||||
diffs_by_work_dir_abs_path: diffs_by_path
|
||||
.into_iter()
|
||||
.filter_map(|diff| diff)
|
||||
.collect(),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user