Detailed changes
@@ -263,9 +263,9 @@ checksum = "34cd60c5e3152cef0a592f1b296f1cc93715d89d2551d85315828c3a09575ff4"
[[package]]
name = "anyhow"
-version = "1.0.93"
+version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
+checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8"
[[package]]
name = "approx"
@@ -290,7 +290,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -652,7 +652,7 @@ dependencies = [
"futures-lite 2.3.0",
"parking",
"polling 3.7.3",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"slab",
"tracing",
"windows-sys 0.59.0",
@@ -734,7 +734,7 @@ dependencies = [
"cfg-if",
"event-listener 3.1.0",
"futures-lite 1.13.0",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"windows-sys 0.48.0",
]
@@ -753,7 +753,7 @@ dependencies = [
"cfg-if",
"event-listener 5.3.1",
"futures-lite 2.3.0",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"tracing",
"windows-sys 0.59.0",
]
@@ -777,7 +777,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -792,7 +792,7 @@ dependencies = [
"cfg-if",
"futures-core",
"futures-io",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"signal-hook-registry",
"slab",
"windows-sys 0.59.0",
@@ -845,7 +845,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -909,7 +909,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -1596,7 +1596,7 @@ dependencies = [
"regex",
"rustc-hash 1.1.0",
"shlex",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -1616,7 +1616,7 @@ dependencies = [
"regex",
"rustc-hash 1.1.0",
"shlex",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -1740,7 +1740,7 @@ source = "git+https://github.com/kvark/blade?rev=e142a3a5e678eb6a13e642ad8401b1f
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -1824,7 +1824,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
"syn_derive",
]
@@ -1909,7 +1909,7 @@ checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -1983,7 +1983,7 @@ dependencies = [
"bitflags 2.6.0",
"log",
"polling 3.7.3",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"slab",
"thiserror",
]
@@ -1995,7 +1995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
dependencies = [
"calloop",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"wayland-backend",
"wayland-client",
]
@@ -2011,9 +2011,9 @@ dependencies = [
[[package]]
name = "cap-fs-ext"
-version = "3.4.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e16619ada836f12897a72011fe99b03f0025b87a8dbbea4f3c9f89b458a23bf3"
+checksum = "eb23061fc1c4ead4e45ca713080fe768e6234e959f5a5c399c39eb41aa34e56e"
dependencies = [
"cap-primitives",
"cap-std",
@@ -2023,21 +2023,21 @@ dependencies = [
[[package]]
name = "cap-net-ext"
-version = "3.4.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "710b0eb776410a22c89a98f2f80b2187c2ac3a8206b99f3412332e63c9b09de0"
+checksum = "f83ae11f116bcbafc5327c6af250341db96b5930046732e1905f7dc65887e0e1"
dependencies = [
"cap-primitives",
"cap-std",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"smallvec",
]
[[package]]
name = "cap-primitives"
-version = "3.4.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82fa6c3f9773feab88d844aa50035a33fb6e7e7426105d2f4bb7aadc42a5f89a"
+checksum = "6d00bd8d26c4270d950eaaa837387964a2089a1c3c349a690a1fa03221d29531"
dependencies = [
"ambient-authority",
"fs-set-times",
@@ -2045,16 +2045,16 @@ dependencies = [
"io-lifetimes 2.0.3",
"ipnet",
"maybe-owned",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"windows-sys 0.52.0",
"winx",
]
[[package]]
name = "cap-rand"
-version = "3.4.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53774d49369892b70184f8312e50c1b87edccb376691de4485b0ff554b27c36c"
+checksum = "dbcb16a619d8b8211ed61f42bd290d2a1ac71277a69cf8417ec0996fa92f5211"
dependencies = [
"ambient-authority",
"rand 0.8.5",
@@ -2062,27 +2062,27 @@ dependencies = [
[[package]]
name = "cap-std"
-version = "3.4.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f71b70818556b4fe2a10c7c30baac3f5f45e973f49fc2673d7c75c39d0baf5b"
+checksum = "19eb8e3d71996828751c1ed3908a439639752ac6bdc874e41469ef7fc15fbd7f"
dependencies = [
"cap-primitives",
"io-extras",
"io-lifetimes 2.0.3",
- "rustix 0.38.39",
+ "rustix 0.38.35",
]
[[package]]
name = "cap-time-ext"
-version = "3.4.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69dd48afa2363f746c93f961c211f6f099fb594a3446b8097bc5f79db51b6816"
+checksum = "61142dc51e25b7acc970ca578ce2c3695eac22bbba46c1073f5f583e78957725"
dependencies = [
"ambient-authority",
"cap-primitives",
"iana-time-zone",
"once_cell",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"winx",
]
@@ -2147,7 +2147,7 @@ dependencies = [
"quote",
"serde",
"serde_json",
- "syn 2.0.87",
+ "syn 2.0.76",
"tempfile",
"toml 0.8.19",
]
@@ -2340,7 +2340,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -3068,18 +3068,18 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f823c6662ea77699089ec8b6b4b8a23c1e1a9c6526a6420ede7ac957274a7ab4"
+checksum = "32d69b774780246008783a75edfb943eccc2487b6a43808503a07cd563f2ffde"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-bitset"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fcbb4187005097204458a8e4309bb9e737933477e47b4609f81b07a5b4cdd25"
+checksum = "a7d8d71c6b32c1a7cff254c5e5d7359872c1e5e610fbe963472afcddbd9cf303"
dependencies = [
"serde",
"serde_derive",
@@ -3087,9 +3087,9 @@ dependencies = [
[[package]]
name = "cranelift-codegen"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cd1aaf8e88339f4f95afffd60d22033546ec7da4d79e805b85260a16668f78f"
+checksum = "3ad3a906f2a3f3590ad9798d59a46959a8593258eb985af722f634723c063a2c"
dependencies = [
"bumpalo",
"cranelift-bforest",
@@ -3110,33 +3110,33 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e541b0418bbba3ce82040a445bd9a83bf3e0da604a95178d9e949dc8a7840af"
+checksum = "cd5e4ee12262a135efbef3ced4ab2153adafe4adc55f36af94f9d73be0f7505d"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91fc96a709a30be39d53ecf89dbfe4edcc5adba528d4b65f7e58dc867ba70fab"
+checksum = "5b9374a2a5f060f72e3080fe1c87c9ff4bef2cbe798faae60daf276fb1a13968"
[[package]]
name = "cranelift-control"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c3bfcb035e0a501323896bb7ea3d7a5dd1fac3e92dda458ccd23960fde12c88"
+checksum = "fba3ca2f344bb22d265a928e7c3f5f46e1a2eb41f1393bd53538d07b6ffb5293"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2f00b4eba51d73a8c343c45cfdeeffa1f74f423bba0e6b8e290e646777c2b81"
+checksum = "a6aef77dfb018eed09d92d4244abe3c1c060cbbd900c24f75ddde7d75d0e781e"
dependencies = [
"cranelift-bitset",
"serde",
@@ -3145,9 +3145,9 @@ dependencies = [
[[package]]
name = "cranelift-frontend"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52d5e18bf04660bb716dacf45809e2d4c85e7111701e27dbdb75b4634504ad8f"
+checksum = "7b1d6954f03d63df1cb95d66153c97df0201862220861349bbd5f583754b1917"
dependencies = [
"cranelift-codegen",
"log",
@@ -3157,15 +3157,15 @@ dependencies = [
[[package]]
name = "cranelift-isle"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31f9901807b6d0fde1205f0e4db9d96dcf7ddfc1894c69eb2ff93c47ebf2439f"
+checksum = "f8b9b7e088b784796ea8aa5947c1cc12034c1b076a077ec2a5a287da717fa746"
[[package]]
name = "cranelift-native"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "967d65a4077726a9afc3f4694e037f34b992cbe2b6c48ce519b714a0b0558f97"
+checksum = "4cab7424083d070669ff3fdeea7c5b4b5013a055aa1ee0532703f17a5f62af64"
dependencies = [
"cranelift-codegen",
"libc",
@@ -3174,9 +3174,9 @@ dependencies = [
[[package]]
name = "cranelift-wasm"
-version = "0.111.2"
+version = "0.111.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4899fd1ef6b1fe1df30f26ef864bd6e45040b8cf9f3cb3905d3e973c25698579"
+checksum = "81a9f6d0495984eef1d753ec8748de0b216b37ade16d219f1c0f27d8188d7f77"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
@@ -3346,7 +3346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
dependencies = [
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -3485,7 +3485,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -3598,17 +3598,6 @@ dependencies = [
"windows-sys 0.48.0",
]
-[[package]]
-name = "displaydoc"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.87",
-]
-
[[package]]
name = "dlib"
version = "0.5.2"
@@ -3761,7 +3750,7 @@ dependencies = [
"enum-ordinalize",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -3878,7 +3867,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -3899,7 +3888,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -4308,7 +4297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947"
dependencies = [
"cfg-if",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"windows-sys 0.52.0",
]
@@ -4562,7 +4551,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -4644,7 +4633,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb"
dependencies = [
"io-lifetimes 2.0.3",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"windows-sys 0.52.0",
]
@@ -4805,7 +4794,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -5282,12 +5271,11 @@ dependencies = [
[[package]]
name = "handlebars"
-version = "6.2.0"
+version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315"
+checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b"
dependencies = [
"log",
- "num-order",
"pest",
"pest_derive",
"serde",
@@ -5507,7 +5495,7 @@ dependencies = [
"markup5ever",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -5777,124 +5765,6 @@ dependencies = [
"cc",
]
-[[package]]
-name = "icu_collections"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
-dependencies = [
- "displaydoc",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locid"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
-dependencies = [
- "displaydoc",
- "litemap",
- "tinystr",
- "writeable",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locid_transform"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
-dependencies = [
- "displaydoc",
- "icu_locid",
- "icu_locid_transform_data",
- "icu_provider",
- "tinystr",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locid_transform_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
-
-[[package]]
-name = "icu_normalizer"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
-dependencies = [
- "displaydoc",
- "icu_collections",
- "icu_normalizer_data",
- "icu_properties",
- "icu_provider",
- "smallvec",
- "utf16_iter",
- "utf8_iter",
- "write16",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
-
-[[package]]
-name = "icu_properties"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
-dependencies = [
- "displaydoc",
- "icu_collections",
- "icu_locid_transform",
- "icu_properties_data",
- "icu_provider",
- "tinystr",
- "zerovec",
-]
-
-[[package]]
-name = "icu_properties_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
-
-[[package]]
-name = "icu_provider"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
-dependencies = [
- "displaydoc",
- "icu_locid",
- "icu_provider_macros",
- "stable_deref_trait",
- "tinystr",
- "writeable",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
-name = "icu_provider_macros"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.87",
-]
-
[[package]]
name = "id-arena"
version = "2.2.1"
@@ -5903,23 +5773,12 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "idna"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
-dependencies = [
- "idna_adapter",
- "smallvec",
- "utf8_iter",
-]
-
-[[package]]
-name = "idna_adapter"
-version = "1.2.0"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
- "icu_normalizer",
- "icu_properties",
+ "unicode-bidi",
+ "unicode-normalization",
]
[[package]]
@@ -6068,7 +5927,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -6153,14 +6012,14 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
name = "io-extras"
-version = "0.18.3"
+version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d45fd7584f9b67ac37bc041212d06bfac0700b36456b05890d36a3b626260eb"
+checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b"
dependencies = [
"io-lifetimes 2.0.3",
"windows-sys 0.52.0",
@@ -6450,7 +6309,7 @@ dependencies = [
"parking_lot",
"postage",
"pretty_assertions",
- "pulldown-cmark 0.12.2",
+ "pulldown-cmark 0.12.1",
"rand 0.8.5",
"regex",
"rpc",
@@ -6778,7 +6637,7 @@ checksum = "b01f197a15988fb5b2ec0a5a9800c97e70771499c456ad757d63b3c5e9b96e75"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -6793,12 +6652,6 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
-[[package]]
-name = "litemap"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
-
[[package]]
name = "live_kit_client"
version = "0.1.0"
@@ -6986,7 +6839,7 @@ dependencies = [
"linkify",
"log",
"node_runtime",
- "pulldown-cmark 0.12.2",
+ "pulldown-cmark 0.12.1",
"settings",
"theme",
"ui",
@@ -7006,7 +6859,7 @@ dependencies = [
"linkify",
"log",
"pretty_assertions",
- "pulldown-cmark 0.12.2",
+ "pulldown-cmark 0.12.1",
"settings",
"theme",
"ui",
@@ -7081,9 +6934,9 @@ dependencies = [
[[package]]
name = "mdbook"
-version = "0.4.41"
+version = "0.4.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c57953fbe900c241a7879c8fd81c5a6bebc583dc8a4338582c63b58b49014d7"
+checksum = "b45a38e19bd200220ef07c892b0157ad3d2365e5b5a267ca01ad12182491eea5"
dependencies = [
"ammonia",
"anyhow",
@@ -7093,7 +6946,7 @@ dependencies = [
"elasticlunr-rs",
"env_logger 0.11.5",
"futures-util",
- "handlebars 6.2.0",
+ "handlebars 5.1.2",
"ignore",
"log",
"memchr",
@@ -7139,7 +6992,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64"
dependencies = [
- "rustix 0.38.39",
+ "rustix 0.38.35",
]
[[package]]
@@ -7614,7 +7467,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -7647,21 +7500,6 @@ dependencies = [
"num-traits",
]
-[[package]]
-name = "num-modular"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f"
-
-[[package]]
-name = "num-order"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6"
-dependencies = [
- "num-modular",
-]
-
[[package]]
name = "num-rational"
version = "0.4.2"
@@ -7711,7 +7549,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -7899,7 +7737,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -7985,7 +7823,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -8098,7 +7936,7 @@ dependencies = [
"by_address",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -8268,7 +8106,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -8702,7 +8540,7 @@ dependencies = [
"phf_shared 0.11.2",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -8762,7 +8600,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -8905,7 +8743,7 @@ dependencies = [
"concurrent-queue",
"hermit-abi 0.4.0",
"pin-project-lite",
- "rustix 0.38.39",
+ "rustix 0.38.35",
"tracing",
"windows-sys 0.59.0",
]
@@ -9002,7 +8840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
dependencies = [
"proc-macro2",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -9063,7 +8901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30"
dependencies = [
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -9307,9 +9145,9 @@ dependencies = [
[[package]]
name = "pulldown-cmark"
-version = "0.12.2"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
+checksum = "666f0f59e259aea2d72e6012290c09877a780935cc3c18b1ceded41f3890d59c"
dependencies = [
"bitflags 2.6.0",
"memchr",
@@ -10033,7 +9871,7 @@ dependencies = [
"gpui",
"language",
"linkify",
- "pulldown-cmark 0.12.2",
+ "pulldown-cmark 0.12.1",
"theme",
"ui",
"util",
@@ -10231,7 +10069,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
- "syn 2.0.87",
+ "syn 2.0.76",
"walkdir",
]
@@ -10305,9 +10143,9 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.39"
+version = "0.38.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee"
+checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f"
dependencies = [
"bitflags 2.6.0",
"errno 0.3.9",
@@ -10326,7 +10164,7 @@ checksum = "a25c3aad9fc1424eb82c88087789a7d938e1829724f3e4043163baf0d13cfc12"
dependencies = [
"errno 0.3.9",
"libc",
- "rustix 0.38.39",
+ "rustix 0.38.35",
]
[[package]]
@@ -10504,7 +10342,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals 0.29.1",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -10551,7 +10389,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -10592,7 +10430,7 @@ dependencies = [
"proc-macro2",
"quote",
"sea-bae",
- "syn 2.0.87",
+ "syn 2.0.76",
"unicode-ident",
]
@@ -10791,7 +10629,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -10813,7 +10651,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -10827,9 +10665,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.132"
+version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
+checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
dependencies = [
"indexmap 2.4.0",
"itoa",
@@ -10890,7 +10728,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -11449,7 +11287,7 @@ dependencies = [
"quote",
"sqlx-core",
"sqlx-macros-core",
- "syn 2.0.87",
+ "syn 2.0.76",
]
[[package]]
@@ -1480,7 +1480,6 @@ struct ScrollPosition {
}
struct PatchViewState {
- footer_block_id: CustomBlockId,
crease_id: CreaseId,
editor: Option<PatchEditorState>,
update_task: Option<Task<()>>,
@@ -1934,7 +1933,7 @@ impl ContextEditor {
);
});
- Crease::new(
+ Crease::inline(
start..end,
placeholder,
fold_toggle("tool-use"),
@@ -2032,7 +2031,7 @@ impl ContextEditor {
let end = buffer
.anchor_in_excerpt(excerpt_id, command.source_range.end)
.unwrap();
- Crease::new(start..end, placeholder, render_toggle, render_trailer)
+ Crease::inline(start..end, placeholder, render_toggle, render_trailer)
}),
cx,
);
@@ -2124,7 +2123,7 @@ impl ContextEditor {
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
- let crease = Crease::new(
+ let crease = Crease::inline(
start..end,
placeholder,
fold_toggle("tool-use"),
@@ -2192,18 +2191,14 @@ impl ContextEditor {
let crease_end = buffer
.anchor_in_excerpt(excerpt_id, invoked_slash_command.range.end)
.unwrap();
- let fold_placeholder =
- invoked_slash_command_fold_placeholder(command_id, context);
- let crease_ids = editor.insert_creases(
- [Crease::new(
- crease_start..crease_end,
- fold_placeholder.clone(),
- fold_toggle("invoked-slash-command"),
- |_row, _folded, _cx| Empty.into_any(),
- )],
- cx,
+ let crease = Crease::inline(
+ crease_start..crease_end,
+ invoked_slash_command_fold_placeholder(command_id, context),
+ fold_toggle("invoked-slash-command"),
+ |_row, _folded, _cx| Empty.into_any(),
);
- editor.fold_ranges([(crease_start..crease_end, fold_placeholder)], false, cx);
+ let crease_ids = editor.insert_creases([crease.clone()], cx);
+ editor.fold_creases(vec![crease], false, cx);
entry.insert(crease_ids[0]);
} else {
cx.notify()
@@ -2225,23 +2220,32 @@ impl ContextEditor {
cx: &mut ViewContext<ContextEditor>,
) {
let this = cx.view().downgrade();
- let mut removed_crease_ids = Vec::new();
- let mut removed_block_ids = HashSet::default();
let mut editors_to_close = Vec::new();
- for range in removed {
- if let Some(state) = self.patches.remove(range) {
- editors_to_close.extend(state.editor.and_then(|state| state.editor.upgrade()));
- removed_block_ids.insert(state.footer_block_id);
- removed_crease_ids.push(state.crease_id);
- }
- }
self.editor.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
let multibuffer = &snapshot.buffer_snapshot;
let (&excerpt_id, _, _) = multibuffer.as_singleton().unwrap();
- let mut replaced_blocks = HashMap::default();
+ let mut removed_crease_ids = Vec::new();
+ let mut ranges_to_unfold: Vec<Range<Anchor>> = Vec::new();
+ for range in removed {
+ if let Some(state) = self.patches.remove(range) {
+ let patch_start = multibuffer
+ .anchor_in_excerpt(excerpt_id, range.start)
+ .unwrap();
+ let patch_end = multibuffer
+ .anchor_in_excerpt(excerpt_id, range.end)
+ .unwrap();
+
+ editors_to_close.extend(state.editor.and_then(|state| state.editor.upgrade()));
+ ranges_to_unfold.push(patch_start..patch_end);
+ removed_crease_ids.push(state.crease_id);
+ }
+ }
+ editor.unfold_ranges(&ranges_to_unfold, true, false, cx);
+ editor.remove_creases(removed_crease_ids, cx);
+
for range in updated {
let Some(patch) = self.context.read(cx).patch_for_range(&range, cx).cloned() else {
continue;
@@ -2254,19 +2258,21 @@ impl ContextEditor {
let patch_end = multibuffer
.anchor_in_excerpt(excerpt_id, patch.range.end)
.unwrap();
- let render_block: RenderBlock = Box::new({
+ let render_block: RenderBlock = Arc::new({
let this = this.clone();
let patch_range = range.clone();
move |cx: &mut BlockContext<'_, '_>| {
let max_width = cx.max_width;
let gutter_width = cx.gutter_dimensions.full_width();
let block_id = cx.block_id;
+ let selected = cx.selected;
this.update(&mut **cx, |this, cx| {
- this.render_patch_footer(
+ this.render_patch_block(
patch_range.clone(),
max_width,
gutter_width,
block_id,
+ selected,
cx,
)
})
@@ -2276,25 +2282,16 @@ impl ContextEditor {
}
});
- let header_placeholder = FoldPlaceholder {
- render: {
- let this = this.clone();
- let patch_range = range.clone();
- Arc::new(move |fold_id, _range, cx| {
- this.update(cx, |this, cx| {
- this.render_patch_header(patch_range.clone(), fold_id, cx)
- })
- .ok()
- .flatten()
- .unwrap_or_else(|| Empty.into_any())
- })
- },
- ..Default::default()
- };
+ let height = path_count as u32 + 1;
+ let crease = Crease::block(
+ patch_start..patch_end,
+ height,
+ BlockStyle::Flex,
+ render_block.clone(),
+ );
let should_refold;
if let Some(state) = self.patches.get_mut(&range) {
- replaced_blocks.insert(state.footer_block_id, render_block);
if let Some(editor_state) = &state.editor {
if editor_state.opened_patch != patch {
state.update_task = Some({
@@ -2311,33 +2308,11 @@ impl ContextEditor {
should_refold =
snapshot.intersects_fold(patch_start.to_offset(&snapshot.buffer_snapshot));
} else {
- let block_ids = editor.insert_blocks(
- [BlockProperties {
- height: path_count as u32 + 1,
- style: BlockStyle::Flex,
- render: render_block,
- placement: BlockPlacement::Below(patch_start),
- priority: 0,
- }],
- None,
- cx,
- );
-
- let new_crease_ids = editor.insert_creases(
- [Crease::new(
- patch_start..patch_end,
- header_placeholder.clone(),
- fold_toggle("patch-header"),
- |_, _, _| Empty.into_any_element(),
- )],
- cx,
- );
-
+ let crease_id = editor.insert_creases([crease.clone()], cx)[0];
self.patches.insert(
range.clone(),
PatchViewState {
- footer_block_id: block_ids[0],
- crease_id: new_crease_ids[0],
+ crease_id,
editor: None,
update_task: None,
},
@@ -2348,13 +2323,9 @@ impl ContextEditor {
if should_refold {
editor.unfold_ranges(&[patch_start..patch_end], true, false, cx);
- editor.fold_ranges([(patch_start..patch_end, header_placeholder)], false, cx);
+ editor.fold_creases(vec![crease], false, cx);
}
}
-
- editor.remove_creases(removed_crease_ids, cx);
- editor.remove_blocks(removed_block_ids, None, cx);
- editor.replace_blocks(replaced_blocks, None, cx);
});
for editor in editors_to_close {
@@ -2385,7 +2356,7 @@ impl ContextEditor {
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
buffer_rows_to_fold.insert(buffer_row);
creases.push(
- Crease::new(
+ Crease::inline(
start..end,
FoldPlaceholder {
render: render_fold_icon_button(
@@ -2674,7 +2645,7 @@ impl ContextEditor {
let mut blocks_to_replace: HashMap<_, RenderBlock> = Default::default();
let render_block = |message: MessageMetadata| -> RenderBlock {
- Box::new({
+ Arc::new({
let context = self.context.clone();
move |cx| {
@@ -3127,7 +3098,7 @@ impl ContextEditor {
crease_title,
cx.view().downgrade(),
);
- let crease = Crease::new(
+ let crease = Crease::inline(
anchor_before..anchor_after,
fold_placeholder,
render_quote_selection_output_toggle,
@@ -3217,31 +3188,29 @@ impl ContextEditor {
&snapshot,
)
.filter_map(|crease| {
- if let Some(metadata) = &crease.metadata {
- let start = crease
- .range
+ if let Crease::Inline {
+ range, metadata, ..
+ } = &crease
+ {
+ let metadata = metadata.as_ref()?;
+ let start = range
.start
.to_offset(&snapshot)
.saturating_sub(selection_start);
- let end = crease
- .range
+ let end = range
.end
.to_offset(&snapshot)
.saturating_sub(selection_start);
let range_relative_to_selection = start..end;
-
- if range_relative_to_selection.is_empty() {
- None
- } else {
- Some(SelectedCreaseMetadata {
+ if !range_relative_to_selection.is_empty() {
+ return Some(SelectedCreaseMetadata {
range_relative_to_selection,
crease: metadata.clone(),
- })
+ });
}
- } else {
- None
}
+ None
})
.collect::<Vec<_>>()
}),
@@ -3322,7 +3291,7 @@ impl ContextEditor {
let buffer_row = MultiBufferRow(start.to_point(&buffer).row);
buffer_rows_to_fold.insert(buffer_row);
- Crease::new(
+ Crease::inline(
start..end,
FoldPlaceholder {
render: render_fold_icon_button(
@@ -3415,7 +3384,7 @@ impl ContextEditor {
placement: BlockPlacement::Above(anchor),
height: MAX_HEIGHT_IN_LINES,
style: BlockStyle::Sticky,
- render: Box::new(move |cx| {
+ render: Arc::new(move |cx| {
let image_size = size_for_image(
&image,
size(
@@ -3472,33 +3441,13 @@ impl ContextEditor {
.unwrap_or_else(|| Cow::Borrowed(DEFAULT_TAB_TITLE))
}
- fn render_patch_header(
- &self,
- range: Range<text::Anchor>,
- _id: FoldId,
- cx: &mut ViewContext<Self>,
- ) -> Option<AnyElement> {
- let patch = self.context.read(cx).patch_for_range(&range, cx)?;
- let theme = cx.theme().clone();
- Some(
- h_flex()
- .px_1()
- .py_0p5()
- .border_b_1()
- .border_color(theme.status().info_border)
- .gap_1()
- .child(Icon::new(IconName::Diff).size(IconSize::Small))
- .child(Label::new(patch.title.clone()).size(LabelSize::Small))
- .into_any(),
- )
- }
-
- fn render_patch_footer(
+ fn render_patch_block(
&mut self,
range: Range<text::Anchor>,
max_width: Pixels,
gutter_width: Pixels,
id: BlockId,
+ selected: bool,
cx: &mut ViewContext<Self>,
) -> Option<AnyElement> {
let snapshot = self.editor.update(cx, |editor, cx| editor.snapshot(cx));
@@ -3509,10 +3458,7 @@ impl ContextEditor {
.anchor_in_excerpt(excerpt_id, range.start)
.unwrap();
- if !snapshot.intersects_fold(anchor) {
- return None;
- }
-
+ let theme = cx.theme().clone();
let patch = self.context.read(cx).patch_for_range(&range, cx)?;
let paths = patch
.paths()
@@ -3522,9 +3468,17 @@ impl ContextEditor {
Some(
v_flex()
.id(id)
- .pl(gutter_width)
- .w(max_width)
- .py_2()
+ .bg(theme.colors().editor_background)
+ .ml(gutter_width)
+ .w(max_width - gutter_width)
+ .rounded_md()
+ .border_1()
+ .border_color(theme.colors().border)
+ .hover(|style| style.border_color(theme.colors().text_accent))
+ .when(selected, |this| {
+ this.border_color(theme.colors().text_accent)
+ })
+ .pb_1()
.cursor(CursorStyle::PointingHand)
.on_click(cx.listener(move |this, _, cx| {
this.editor.update(cx, |editor, cx| {
@@ -3534,24 +3488,55 @@ impl ContextEditor {
});
this.focus_active_patch(cx);
}))
+ .child(
+ h_flex()
+ .rounded_t_md()
+ .bg(theme.colors().element_background)
+ .px_2()
+ .py_1()
+ .child(Label::new(patch.title.clone()).size(LabelSize::Small))
+ .border_b_1()
+ .border_color(theme.colors().border),
+ )
.children(paths.into_iter().map(|path| {
h_flex()
- .pl_1()
+ .px_2()
+ .pt_1()
.gap_1()
.child(Icon::new(IconName::File).size(IconSize::Small))
.child(Label::new(path).size(LabelSize::Small))
}))
.when(patch.status == AssistantPatchStatus::Pending, |div| {
div.child(
- Label::new("Generating")
- .color(Color::Muted)
- .size(LabelSize::Small)
- .with_animation(
- "pulsating-label",
- Animation::new(Duration::from_secs(2))
- .repeat()
- .with_easing(pulsating_between(0.4, 1.)),
- |label, delta| label.alpha(delta),
+ h_flex()
+ .pt_1()
+ .px_2()
+ .gap_1()
+ .child(
+ Icon::new(IconName::ArrowCircle)
+ .size(IconSize::XSmall)
+ .color(Color::Info)
+ .with_animation(
+ "arrow-circle",
+ Animation::new(Duration::from_secs(2)).repeat(),
+ |icon, delta| {
+ icon.transform(Transformation::rotate(percentage(
+ delta,
+ )))
+ },
+ ),
+ )
+ .child(
+ Label::new("Generating")
+ .color(Color::Muted)
+ .size(LabelSize::Small)
+ .with_animation(
+ "pulsating-label",
+ Animation::new(Duration::from_secs(2))
+ .repeat()
+ .with_easing(pulsating_between(0.4, 1.)),
+ |label, delta| label.alpha(delta),
+ ),
),
)
})
@@ -460,7 +460,7 @@ impl InlineAssistant {
style: BlockStyle::Sticky,
placement: BlockPlacement::Below(range.end),
height: 0,
- render: Box::new(|cx| {
+ render: Arc::new(|cx| {
v_flex()
.h_full()
.w_full()
@@ -1197,8 +1197,9 @@ impl InlineAssistant {
placement: BlockPlacement::Above(new_row),
height,
style: BlockStyle::Flex,
- render: Box::new(move |cx| {
+ render: Arc::new(move |cx| {
div()
+ .occlude()
.bg(cx.theme().status().deleted_background)
.size_full()
.h(height as f32 * cx.line_height())
@@ -1317,7 +1318,7 @@ impl InlineAssistGroup {
fn build_assist_editor_renderer(editor: &View<PromptEditor>) -> RenderBlock {
let editor = editor.clone();
- Box::new(move |cx: &mut BlockContext| {
+ Arc::new(move |cx: &mut BlockContext| {
*editor.read(cx).gutter_dimensions.lock() = *cx.gutter_dimensions;
editor.clone().into_any_element()
})
@@ -1480,6 +1481,7 @@ impl Render for PromptEditor {
h_flex()
.key_context("PromptEditor")
.bg(cx.theme().colors().editor_background)
+ .occlude()
.border_y_1()
.border_color(cx.theme().status().info_border)
.size_full()
@@ -32,6 +32,7 @@ use std::{
cmp::Ordering,
mem,
ops::Range,
+ sync::Arc,
};
use theme::ActiveTheme;
pub use toolbar_controls::ToolbarControls;
@@ -790,10 +791,11 @@ const DIAGNOSTIC_HEADER: &str = "diagnostic header";
fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
let (message, code_ranges) = highlight_diagnostic_message(&diagnostic, None);
let message: SharedString = message;
- Box::new(move |cx| {
+ Arc::new(move |cx| {
let highlight_style: HighlightStyle = cx.theme().colors().text_accent.into();
h_flex()
.id(DIAGNOSTIC_HEADER)
+ .occlude()
.h(2. * cx.line_height())
.pl_10()
.pr_5()
@@ -36,7 +36,7 @@ use block_map::{BlockRow, BlockSnapshot};
use collections::{HashMap, HashSet};
pub use crease_map::*;
pub use fold_map::{Fold, FoldId, FoldPlaceholder, FoldPoint};
-use fold_map::{FoldMap, FoldMapWriter, FoldOffset, FoldSnapshot};
+use fold_map::{FoldMap, FoldSnapshot};
use gpui::{
AnyElement, Font, HighlightStyle, LineLayout, Model, ModelContext, Pixels, UnderlineStyle,
};
@@ -65,7 +65,7 @@ use std::{
};
use sum_tree::{Bias, TreeMap};
use tab_map::{TabMap, TabSnapshot};
-use text::{Edit, LineIndent};
+use text::LineIndent;
use ui::{div, px, IntoElement, ParentElement, SharedString, Styled, WindowContext};
use unicode_segmentation::UnicodeSegmentation;
use wrap_map::{WrapMap, WrapSnapshot};
@@ -197,22 +197,86 @@ impl DisplayMap {
other
.folds_in_range(0..other.buffer_snapshot.len())
.map(|fold| {
- (
+ Crease::simple(
fold.range.to_offset(&other.buffer_snapshot),
fold.placeholder.clone(),
)
- }),
+ })
+ .collect(),
cx,
);
}
- /// Creates folds for the given ranges.
- pub fn fold<T: ToOffset>(
+ /// Creates folds for the given creases.
+ pub fn fold<T: Clone + ToOffset>(
&mut self,
- ranges: impl IntoIterator<Item = (Range<T>, FoldPlaceholder)>,
+ creases: Vec<Crease<T>>,
cx: &mut ModelContext<Self>,
) {
- self.update_fold_map(cx, |fold_map| fold_map.fold(ranges))
+ let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
+ let edits = self.buffer_subscription.consume().into_inner();
+ let tab_size = Self::tab_size(&self.buffer, cx);
+ let (snapshot, edits) = self.inlay_map.sync(buffer_snapshot.clone(), edits);
+ let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
+ let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
+ let (snapshot, edits) = self
+ .wrap_map
+ .update(cx, |map, cx| map.sync(snapshot, edits, cx));
+ self.block_map.read(snapshot, edits);
+
+ let inline = creases.iter().filter_map(|crease| {
+ if let Crease::Inline {
+ range, placeholder, ..
+ } = crease
+ {
+ Some((range.clone(), placeholder.clone()))
+ } else {
+ None
+ }
+ });
+ let (snapshot, edits) = fold_map.fold(inline);
+
+ let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
+ let (snapshot, edits) = self
+ .wrap_map
+ .update(cx, |map, cx| map.sync(snapshot, edits, cx));
+ let mut block_map = self.block_map.write(snapshot, edits);
+ let blocks = creases.into_iter().filter_map(|crease| {
+ if let Crease::Block {
+ range,
+ block_height,
+ render_block,
+ block_style,
+ block_priority,
+ ..
+ } = crease
+ {
+ Some((
+ range,
+ render_block,
+ block_height,
+ block_style,
+ block_priority,
+ ))
+ } else {
+ None
+ }
+ });
+ block_map.insert(
+ blocks
+ .into_iter()
+ .map(|(range, render, height, style, priority)| {
+ let start = buffer_snapshot.anchor_before(range.start);
+ let end = buffer_snapshot.anchor_after(range.end);
+ BlockProperties {
+ placement: BlockPlacement::Replace(start..end),
+ render,
+ height,
+ style,
+ priority,
+ }
+ }),
+ );
}
/// Removes any folds with the given ranges.
@@ -222,7 +286,22 @@ impl DisplayMap {
type_id: TypeId,
cx: &mut ModelContext<Self>,
) {
- self.update_fold_map(cx, |fold_map| fold_map.remove_folds(ranges, type_id))
+ let snapshot = self.buffer.read(cx).snapshot(cx);
+ let edits = self.buffer_subscription.consume().into_inner();
+ let tab_size = Self::tab_size(&self.buffer, cx);
+ let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
+ let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
+ let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
+ let (snapshot, edits) = self
+ .wrap_map
+ .update(cx, |map, cx| map.sync(snapshot, edits, cx));
+ self.block_map.read(snapshot, edits);
+ let (snapshot, edits) = fold_map.remove_folds(ranges, type_id);
+ let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
+ let (snapshot, edits) = self
+ .wrap_map
+ .update(cx, |map, cx| map.sync(snapshot, edits, cx));
+ self.block_map.write(snapshot, edits);
}
/// Removes any folds whose ranges intersect any of the given ranges.
@@ -231,18 +310,12 @@ impl DisplayMap {
ranges: impl IntoIterator<Item = Range<T>>,
inclusive: bool,
cx: &mut ModelContext<Self>,
- ) {
- self.update_fold_map(cx, |fold_map| {
- fold_map.unfold_intersecting(ranges, inclusive)
- })
- }
-
- fn update_fold_map(
- &mut self,
- cx: &mut ModelContext<Self>,
- callback: impl FnOnce(&mut FoldMapWriter) -> (FoldSnapshot, Vec<Edit<FoldOffset>>),
) {
let snapshot = self.buffer.read(cx).snapshot(cx);
+ let offset_ranges = ranges
+ .into_iter()
+ .map(|range| range.start.to_offset(&snapshot)..range.end.to_offset(&snapshot))
+ .collect::<Vec<_>>();
let edits = self.buffer_subscription.consume().into_inner();
let tab_size = Self::tab_size(&self.buffer, cx);
let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
@@ -252,17 +325,20 @@ impl DisplayMap {
.wrap_map
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
self.block_map.read(snapshot, edits);
- let (snapshot, edits) = callback(&mut fold_map);
+
+ let (snapshot, edits) =
+ fold_map.unfold_intersecting(offset_ranges.iter().cloned(), inclusive);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
- self.block_map.read(snapshot, edits);
+ let mut block_map = self.block_map.write(snapshot, edits);
+ block_map.remove_intersecting_replace_blocks(offset_ranges, inclusive);
}
pub fn insert_creases(
&mut self,
- creases: impl IntoIterator<Item = Crease>,
+ creases: impl IntoIterator<Item = Crease<Anchor>>,
cx: &mut ModelContext<Self>,
) -> Vec<CreaseId> {
let snapshot = self.buffer.read(cx).snapshot(cx);
@@ -596,7 +672,7 @@ impl DisplaySnapshot {
) -> impl Iterator<Item = Option<MultiBufferRow>> + '_ {
self.block_snapshot
.buffer_rows(BlockRow(start_row.0))
- .map(|row| row.map(|row| MultiBufferRow(row.0)))
+ .map(|row| row.map(MultiBufferRow))
}
pub fn max_buffer_row(&self) -> MultiBufferRow {
@@ -987,7 +1063,12 @@ impl DisplaySnapshot {
}
pub fn is_line_folded(&self, buffer_row: MultiBufferRow) -> bool {
- self.fold_snapshot.is_line_folded(buffer_row)
+ self.block_snapshot.is_line_replaced(buffer_row)
+ || self.fold_snapshot.is_line_folded(buffer_row)
+ }
+
+ pub fn is_line_replaced(&self, buffer_row: MultiBufferRow) -> bool {
+ self.block_snapshot.is_line_replaced(buffer_row)
}
pub fn is_block_line(&self, display_row: DisplayRow) -> bool {
@@ -1061,19 +1142,42 @@ impl DisplaySnapshot {
.unwrap_or(false)
}
- pub fn foldable_range(
- &self,
- buffer_row: MultiBufferRow,
- ) -> Option<(Range<Point>, FoldPlaceholder)> {
+ pub fn crease_for_buffer_row(&self, buffer_row: MultiBufferRow) -> Option<Crease<Point>> {
let start = MultiBufferPoint::new(buffer_row.0, self.buffer_snapshot.line_len(buffer_row));
if let Some(crease) = self
.crease_snapshot
.query_row(buffer_row, &self.buffer_snapshot)
{
- Some((
- crease.range.to_point(&self.buffer_snapshot),
- crease.placeholder.clone(),
- ))
+ match crease {
+ Crease::Inline {
+ range,
+ placeholder,
+ render_toggle,
+ render_trailer,
+ metadata,
+ } => Some(Crease::Inline {
+ range: range.to_point(&self.buffer_snapshot),
+ placeholder: placeholder.clone(),
+ render_toggle: render_toggle.clone(),
+ render_trailer: render_trailer.clone(),
+ metadata: metadata.clone(),
+ }),
+ Crease::Block {
+ range,
+ block_height,
+ block_style,
+ render_block,
+ block_priority,
+ render_toggle,
+ } => Some(Crease::Block {
+ range: range.to_point(&self.buffer_snapshot),
+ block_height: *block_height,
+ block_style: *block_style,
+ render_block: render_block.clone(),
+ block_priority: *block_priority,
+ render_toggle: render_toggle.clone(),
+ }),
+ }
} else if self.starts_indent(MultiBufferRow(start.row))
&& !self.is_line_folded(MultiBufferRow(start.row))
{
@@ -1110,7 +1214,13 @@ impl DisplaySnapshot {
.line_len(MultiBufferRow(row_before_line_breaks.row)),
);
- Some((start..row_before_line_breaks, self.fold_placeholder.clone()))
+ Some(Crease::Inline {
+ range: start..row_before_line_breaks,
+ placeholder: self.fold_placeholder.clone(),
+ render_toggle: None,
+ render_trailer: None,
+ metadata: None,
+ })
} else {
None
}
@@ -1418,7 +1528,7 @@ pub mod tests {
placement,
style: BlockStyle::Fixed,
height,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority,
}
})
@@ -1457,7 +1567,8 @@ pub mod tests {
map.fold(
ranges
.into_iter()
- .map(|range| (range, FoldPlaceholder::test())),
+ .map(|range| Crease::simple(range, FoldPlaceholder::test()))
+ .collect(),
cx,
);
});
@@ -1832,7 +1943,7 @@ pub mod tests {
map.update(cx, |map, cx| {
map.fold(
- vec![(
+ vec![Crease::simple(
MultiBufferPoint::new(0, 6)..MultiBufferPoint::new(3, 2),
FoldPlaceholder::test(),
)],
@@ -1922,7 +2033,7 @@ pub mod tests {
),
height: 1,
style: BlockStyle::Sticky,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
}],
cx,
@@ -2028,7 +2139,7 @@ pub mod tests {
),
height: 1,
style: BlockStyle::Sticky,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
}],
cx,
@@ -2104,7 +2215,7 @@ pub mod tests {
),
height: 4,
style: BlockStyle::Fixed,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
}],
cx,
@@ -2253,7 +2364,7 @@ pub mod tests {
map.update(cx, |map, cx| {
map.fold(
- vec![(
+ vec![Crease::simple(
MultiBufferPoint::new(0, 6)..MultiBufferPoint::new(3, 2),
FoldPlaceholder::test(),
)],
@@ -2452,7 +2563,7 @@ pub mod tests {
snapshot.anchor_before(Point::new(2, 0))..snapshot.anchor_after(Point::new(3, 3));
map.crease_map.insert(
- [Crease::new(
+ [Crease::inline(
range,
FoldPlaceholder::test(),
|_row, _status, _toggle, _cx| div(),
@@ -7,7 +7,7 @@ use collections::{Bound, HashMap, HashSet};
use gpui::{AnyElement, EntityId, Pixels, WindowContext};
use language::{Chunk, Patch, Point};
use multi_buffer::{
- Anchor, ExcerptId, ExcerptInfo, MultiBufferRow, MultiBufferSnapshot, ToPoint as _,
+ Anchor, ExcerptId, ExcerptInfo, MultiBufferRow, MultiBufferSnapshot, ToOffset, ToPoint as _,
};
use parking_lot::Mutex;
use std::{
@@ -77,7 +77,7 @@ pub struct BlockRow(pub(super) u32);
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
struct WrapRow(u32);
-pub type RenderBlock = Box<dyn Send + FnMut(&mut BlockContext) -> AnyElement>;
+pub type RenderBlock = Arc<dyn Send + Sync + Fn(&mut BlockContext) -> AnyElement>;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BlockPlacement<T> {
@@ -352,6 +352,13 @@ impl Block {
Block::ExcerptBoundary { next_excerpt, .. } => next_excerpt.is_none(),
}
}
+
+ fn is_replacement(&self) -> bool {
+ match self {
+ Block::Custom(block) => matches!(block.placement, BlockPlacement::Replace(_)),
+ Block::ExcerptBoundary { .. } => false,
+ }
+ }
}
impl Debug for Block {
@@ -1119,6 +1126,64 @@ impl<'a> BlockMapWriter<'a> {
.retain(|id, _| !block_ids.contains(id));
self.0.sync(wrap_snapshot, edits);
}
+
+ pub fn remove_intersecting_replace_blocks<T>(
+ &mut self,
+ ranges: impl IntoIterator<Item = Range<T>>,
+ inclusive: bool,
+ ) where
+ T: ToOffset,
+ {
+ let wrap_snapshot = self.0.wrap_snapshot.borrow();
+ let mut blocks_to_remove = HashSet::default();
+ for range in ranges {
+ let range = range.start.to_offset(wrap_snapshot.buffer_snapshot())
+ ..range.end.to_offset(wrap_snapshot.buffer_snapshot());
+ for block in self.blocks_intersecting_buffer_range(range, inclusive) {
+ if matches!(block.placement, BlockPlacement::Replace(_)) {
+ blocks_to_remove.insert(block.id);
+ }
+ }
+ }
+ drop(wrap_snapshot);
+ self.remove(blocks_to_remove);
+ }
+
+ fn blocks_intersecting_buffer_range(
+ &self,
+ range: Range<usize>,
+ inclusive: bool,
+ ) -> &[Arc<CustomBlock>] {
+ let wrap_snapshot = self.0.wrap_snapshot.borrow();
+ let buffer = wrap_snapshot.buffer_snapshot();
+ let start_block_ix = match self.0.custom_blocks.binary_search_by(|probe| {
+ probe
+ .end()
+ .to_offset(buffer)
+ .cmp(&range.start)
+ .then(if inclusive {
+ Ordering::Greater
+ } else {
+ Ordering::Less
+ })
+ }) {
+ Ok(ix) | Err(ix) => ix,
+ };
+ let end_block_ix = match self.0.custom_blocks.binary_search_by(|probe| {
+ probe
+ .start()
+ .to_offset(buffer)
+ .cmp(&range.end)
+ .then(if inclusive {
+ Ordering::Less
+ } else {
+ Ordering::Greater
+ })
+ }) {
+ Ok(ix) | Err(ix) => ix,
+ };
+ &self.0.custom_blocks[start_block_ix..end_block_ix]
+ }
}
impl BlockSnapshot {
@@ -1298,6 +1363,21 @@ impl BlockSnapshot {
cursor.item().map_or(false, |t| t.block.is_some())
}
+ pub(super) fn is_line_replaced(&self, row: MultiBufferRow) -> bool {
+ let wrap_point = self
+ .wrap_snapshot
+ .make_wrap_point(Point::new(row.0, 0), Bias::Left);
+ let mut cursor = self.transforms.cursor::<(WrapRow, BlockRow)>(&());
+ cursor.seek(&WrapRow(wrap_point.row()), Bias::Right, &());
+ cursor.item().map_or(false, |transform| {
+ if let Some(Block::Custom(block)) = transform.block.as_ref() {
+ matches!(block.placement, BlockPlacement::Replace(_))
+ } else {
+ false
+ }
+ })
+ }
+
pub fn clip_point(&self, point: BlockPoint, bias: Bias) -> BlockPoint {
let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(&());
cursor.seek(&BlockRow(point.row), Bias::Right, &());
@@ -1515,7 +1595,7 @@ impl<'a> Iterator for BlockChunks<'a> {
}
impl<'a> Iterator for BlockBufferRows<'a> {
- type Item = Option<BlockRow>;
+ type Item = Option<u32>;
fn next(&mut self) -> Option<Self::Item> {
if self.started {
@@ -1538,16 +1618,25 @@ impl<'a> Iterator for BlockBufferRows<'a> {
}
}
- if self.transforms.item()?.block.is_none() {
+ let transform = self.transforms.item()?;
+ if transform
+ .block
+ .as_ref()
+ .map_or(true, |block| block.is_replacement())
+ {
self.input_buffer_rows.seek(self.transforms.start().1 .0);
}
}
let transform = self.transforms.item()?;
- if transform.block.is_some() {
- Some(None)
+ if let Some(block) = transform.block.as_ref() {
+ if block.is_replacement() && self.transforms.start().0 == self.output_row {
+ Some(self.input_buffer_rows.next().unwrap())
+ } else {
+ Some(None)
+ }
} else {
- Some(self.input_buffer_rows.next().unwrap().map(BlockRow))
+ Some(self.input_buffer_rows.next().unwrap())
}
}
}
@@ -1709,21 +1798,21 @@ mod tests {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(1, 0))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(1, 2))),
height: 2,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Below(buffer_snapshot.anchor_after(Point::new(3, 3))),
height: 3,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
]);
@@ -1821,10 +1910,7 @@ mod tests {
);
assert_eq!(
- snapshot
- .buffer_rows(BlockRow(0))
- .map(|row| row.map(|r| r.0))
- .collect::<Vec<_>>(),
+ snapshot.buffer_rows(BlockRow(0)).collect::<Vec<_>>(),
&[
Some(0),
None,
@@ -1960,21 +2046,21 @@ mod tests {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(1, 0))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(1, 2))),
height: 2,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Below(buffer_snapshot.anchor_after(Point::new(3, 3))),
height: 3,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
]);
@@ -2062,14 +2148,14 @@ mod tests {
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(1, 12))),
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
height: 1,
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Below(buffer_snapshot.anchor_after(Point::new(1, 1))),
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
height: 1,
priority: 0,
},
@@ -2109,7 +2195,7 @@ mod tests {
..buffer_snapshot.anchor_before(Point::new(3, 1)),
),
height: 4,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
}]);
@@ -2162,14 +2248,14 @@ mod tests {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(1, 3))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Below(buffer_snapshot.anchor_after(Point::new(6, 2))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
]);
@@ -2183,21 +2269,21 @@ mod tests {
style: BlockStyle::Fixed,
placement: BlockPlacement::Below(buffer_snapshot.anchor_after(Point::new(1, 3))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(2, 1))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
BlockProperties {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(buffer_snapshot.anchor_after(Point::new(6, 1))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
},
]);
@@ -2302,7 +2388,7 @@ mod tests {
style: BlockStyle::Fixed,
placement,
height,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
}
})
@@ -2321,7 +2407,7 @@ mod tests {
placement: props.placement.clone(),
height: props.height,
style: props.style,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
}));
}
@@ -2409,6 +2495,7 @@ mod tests {
let mut expected_buffer_rows = Vec::new();
let mut expected_text = String::new();
let mut expected_block_positions = Vec::new();
+ let mut expected_replaced_buffer_rows = HashSet::default();
let input_text = wraps_snapshot.text();
// Loop over the input lines, creating (N - 1) empty lines for
@@ -2422,6 +2509,9 @@ mod tests {
let mut block_row = 0;
while let Some((wrap_row, input_line)) = input_text_lines.next() {
let wrap_row = wrap_row as u32;
+ let multibuffer_row = wraps_snapshot
+ .to_point(WrapPoint::new(wrap_row, 0), Bias::Left)
+ .row;
// Create empty lines for the above block
while let Some((placement, block)) = sorted_blocks_iter.peek() {
@@ -2451,30 +2541,33 @@ mod tests {
{
if wrap_row >= replace_range.start.0 {
is_in_replace_block = true;
+
+ if wrap_row == replace_range.start.0 {
+ expected_buffer_rows.push(input_buffer_rows[multibuffer_row as usize]);
+ }
+
if wrap_row == replace_range.end.0 {
expected_block_positions.push((block_row, block.id()));
- if block.height() > 0 {
- let text = "\n".repeat((block.height() - 1) as usize);
- if block_row > 0 {
- expected_text.push('\n');
- }
- expected_text.push_str(&text);
- for _ in 0..block.height() {
- expected_buffer_rows.push(None);
- }
- block_row += block.height();
+ let text = "\n".repeat((block.height() - 1) as usize);
+ if block_row > 0 {
+ expected_text.push('\n');
}
+ expected_text.push_str(&text);
+
+ for _ in 1..block.height() {
+ expected_buffer_rows.push(None);
+ }
+ block_row += block.height();
sorted_blocks_iter.next();
}
}
}
- if !is_in_replace_block {
- let buffer_row = input_buffer_rows[wraps_snapshot
- .to_point(WrapPoint::new(wrap_row, 0), Bias::Left)
- .row as usize];
-
+ if is_in_replace_block {
+ expected_replaced_buffer_rows.insert(MultiBufferRow(multibuffer_row));
+ } else {
+ let buffer_row = input_buffer_rows[multibuffer_row as usize];
let soft_wrapped = wraps_snapshot
.to_tab_point(WrapPoint::new(wrap_row, 0))
.column()
@@ -2543,9 +2636,10 @@ mod tests {
assert_eq!(
blocks_snapshot
.buffer_rows(BlockRow(start_row as u32))
- .map(|row| row.map(|r| r.0))
.collect::<Vec<_>>(),
- &expected_buffer_rows[start_row..]
+ &expected_buffer_rows[start_row..],
+ "incorrect buffer_rows starting at row {:?}",
+ start_row
);
}
@@ -2666,6 +2760,16 @@ mod tests {
block_point.column += c.len_utf8() as u32;
}
}
+
+ for buffer_row in 0..=buffer_snapshot.max_point().row {
+ let buffer_row = MultiBufferRow(buffer_row);
+ assert_eq!(
+ blocks_snapshot.is_line_replaced(buffer_row),
+ expected_replaced_buffer_rows.contains(&buffer_row),
+ "incorrect is_line_replaced({:?})",
+ buffer_row
+ );
+ }
}
}
@@ -2,12 +2,12 @@ use collections::HashMap;
use gpui::{AnyElement, IntoElement};
use multi_buffer::{Anchor, AnchorRangeExt, MultiBufferRow, MultiBufferSnapshot, ToPoint};
use serde::{Deserialize, Serialize};
-use std::{cmp::Ordering, ops::Range, sync::Arc};
+use std::{cmp::Ordering, fmt::Debug, ops::Range, sync::Arc};
use sum_tree::{Bias, SeekTarget, SumTree};
use text::Point;
use ui::{IconName, SharedString, WindowContext};
-use crate::FoldPlaceholder;
+use crate::{BlockStyle, FoldPlaceholder, RenderBlock};
#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct CreaseId(usize);
@@ -45,15 +45,15 @@ impl CreaseSnapshot {
&'a self,
row: MultiBufferRow,
snapshot: &'a MultiBufferSnapshot,
- ) -> Option<&'a Crease> {
+ ) -> Option<&'a Crease<Anchor>> {
let start = snapshot.anchor_before(Point::new(row.0, 0));
let mut cursor = self.creases.cursor::<ItemSummary>(snapshot);
cursor.seek(&start, Bias::Left, snapshot);
while let Some(item) = cursor.item() {
- match Ord::cmp(&item.crease.range.start.to_point(snapshot).row, &row.0) {
+ match Ord::cmp(&item.crease.range().start.to_point(snapshot).row, &row.0) {
Ordering::Less => cursor.next(snapshot),
Ordering::Equal => {
- if item.crease.range.start.is_valid(snapshot) {
+ if item.crease.range().start.is_valid(snapshot) {
return Some(&item.crease);
} else {
cursor.next(snapshot);
@@ -69,7 +69,7 @@ impl CreaseSnapshot {
&'a self,
range: Range<MultiBufferRow>,
snapshot: &'a MultiBufferSnapshot,
- ) -> impl 'a + Iterator<Item = &'a Crease> {
+ ) -> impl 'a + Iterator<Item = &'a Crease<Anchor>> {
let start = snapshot.anchor_before(Point::new(range.start.0, 0));
let mut cursor = self.creases.cursor::<ItemSummary>(snapshot);
cursor.seek(&start, Bias::Left, snapshot);
@@ -77,8 +77,9 @@ impl CreaseSnapshot {
std::iter::from_fn(move || {
while let Some(item) = cursor.item() {
cursor.next(snapshot);
- let crease_start = item.crease.range.start.to_point(snapshot);
- let crease_end = item.crease.range.end.to_point(snapshot);
+ let crease_range = item.crease.range();
+ let crease_start = crease_range.start.to_point(snapshot);
+ let crease_end = crease_range.end.to_point(snapshot);
if crease_end.row > range.end.0 {
continue;
}
@@ -99,8 +100,9 @@ impl CreaseSnapshot {
cursor.next(snapshot);
while let Some(item) = cursor.item() {
- let start_point = item.crease.range.start.to_point(snapshot);
- let end_point = item.crease.range.end.to_point(snapshot);
+ let crease_range = item.crease.range();
+ let start_point = crease_range.start.to_point(snapshot);
+ let end_point = crease_range.end.to_point(snapshot);
results.push((item.id, start_point..end_point));
cursor.next(snapshot);
}
@@ -123,12 +125,22 @@ type RenderTrailerFn =
Arc<dyn Send + Sync + Fn(MultiBufferRow, bool, &mut WindowContext) -> AnyElement>;
#[derive(Clone)]
-pub struct Crease {
- pub range: Range<Anchor>,
- pub placeholder: FoldPlaceholder,
- pub render_toggle: RenderToggleFn,
- pub render_trailer: RenderTrailerFn,
- pub metadata: Option<CreaseMetadata>,
+pub enum Crease<T> {
+ Inline {
+ range: Range<T>,
+ placeholder: FoldPlaceholder,
+ render_toggle: Option<RenderToggleFn>,
+ render_trailer: Option<RenderTrailerFn>,
+ metadata: Option<CreaseMetadata>,
+ },
+ Block {
+ range: Range<T>,
+ block_height: u32,
+ block_style: BlockStyle,
+ render_block: RenderBlock,
+ block_priority: usize,
+ render_toggle: Option<RenderToggleFn>,
+ },
}
/// Metadata about a [`Crease`], that is used for serialization.
@@ -138,9 +150,30 @@ pub struct CreaseMetadata {
pub label: SharedString,
}
-impl Crease {
- pub fn new<RenderToggle, ToggleElement, RenderTrailer, TrailerElement>(
- range: Range<Anchor>,
+impl<T> Crease<T> {
+ pub fn simple(range: Range<T>, placeholder: FoldPlaceholder) -> Self {
+ Crease::Inline {
+ range,
+ placeholder,
+ render_toggle: None,
+ render_trailer: None,
+ metadata: None,
+ }
+ }
+
+ pub fn block(range: Range<T>, height: u32, style: BlockStyle, render: RenderBlock) -> Self {
+ Self::Block {
+ range,
+ block_height: height,
+ block_style: style,
+ render_block: render,
+ block_priority: 0,
+ render_toggle: None,
+ }
+ }
+
+ pub fn inline<RenderToggle, ToggleElement, RenderTrailer, TrailerElement>(
+ range: Range<T>,
placeholder: FoldPlaceholder,
render_toggle: RenderToggle,
render_trailer: RenderTrailer,
@@ -164,37 +197,76 @@ impl Crease {
+ 'static,
TrailerElement: IntoElement,
{
- Crease {
+ Crease::Inline {
range,
placeholder,
- render_toggle: Arc::new(move |row, folded, toggle, cx| {
+ render_toggle: Some(Arc::new(move |row, folded, toggle, cx| {
render_toggle(row, folded, toggle, cx).into_any_element()
- }),
- render_trailer: Arc::new(move |row, folded, cx| {
+ })),
+ render_trailer: Some(Arc::new(move |row, folded, cx| {
render_trailer(row, folded, cx).into_any_element()
- }),
+ })),
metadata: None,
}
}
- pub fn with_metadata(mut self, metadata: CreaseMetadata) -> Self {
- self.metadata = Some(metadata);
- self
+ pub fn with_metadata(self, metadata: CreaseMetadata) -> Self {
+ match self {
+ Crease::Inline {
+ range,
+ placeholder,
+ render_toggle,
+ render_trailer,
+ ..
+ } => Crease::Inline {
+ range,
+ placeholder,
+ render_toggle,
+ render_trailer,
+ metadata: Some(metadata),
+ },
+ Crease::Block { .. } => self,
+ }
+ }
+
+ pub fn range(&self) -> &Range<T> {
+ match self {
+ Crease::Inline { range, .. } => range,
+ Crease::Block { range, .. } => range,
+ }
}
}
-impl std::fmt::Debug for Crease {
+impl<T> std::fmt::Debug for Crease<T>
+where
+ T: Debug,
+{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("Crease")
- .field("range", &self.range)
- .finish()
+ match self {
+ Crease::Inline {
+ range, metadata, ..
+ } => f
+ .debug_struct("Crease::Inline")
+ .field("range", range)
+ .field("metadata", metadata)
+ .finish_non_exhaustive(),
+ Crease::Block {
+ range,
+ block_height,
+ ..
+ } => f
+ .debug_struct("Crease::Block")
+ .field("range", range)
+ .field("height", block_height)
+ .finish_non_exhaustive(),
+ }
}
}
#[derive(Clone, Debug)]
struct CreaseItem {
id: CreaseId,
- crease: Crease,
+ crease: Crease<Anchor>,
}
impl CreaseMap {
@@ -204,7 +276,7 @@ impl CreaseMap {
pub fn insert(
&mut self,
- creases: impl IntoIterator<Item = Crease>,
+ creases: impl IntoIterator<Item = Crease<Anchor>>,
snapshot: &MultiBufferSnapshot,
) -> Vec<CreaseId> {
let mut new_ids = Vec::new();
@@ -212,11 +284,12 @@ impl CreaseMap {
let mut new_creases = SumTree::new(snapshot);
let mut cursor = self.snapshot.creases.cursor::<ItemSummary>(snapshot);
for crease in creases {
- new_creases.append(cursor.slice(&crease.range, Bias::Left, snapshot), snapshot);
+ let crease_range = crease.range().clone();
+ new_creases.append(cursor.slice(&crease_range, Bias::Left, snapshot), snapshot);
let id = self.next_id;
self.next_id.0 += 1;
- self.id_to_range.insert(id, crease.range.clone());
+ self.id_to_range.insert(id, crease_range);
new_creases.push(CreaseItem { crease, id }, snapshot);
new_ids.push(id);
}
@@ -293,7 +366,7 @@ impl sum_tree::Item for CreaseItem {
fn summary(&self, _cx: &MultiBufferSnapshot) -> Self::Summary {
ItemSummary {
- range: self.crease.range.clone(),
+ range: self.crease.range().clone(),
}
}
}
@@ -326,13 +399,13 @@ mod test {
// Insert creases
let creases = [
- Crease::new(
+ Crease::inline(
snapshot.anchor_before(Point::new(1, 0))..snapshot.anchor_after(Point::new(1, 5)),
FoldPlaceholder::test(),
|_row, _folded, _toggle, _cx| div(),
|_row, _folded, _cx| div(),
),
- Crease::new(
+ Crease::inline(
snapshot.anchor_before(Point::new(3, 0))..snapshot.anchor_after(Point::new(3, 5)),
FoldPlaceholder::test(),
|_row, _folded, _toggle, _cx| div(),
@@ -372,19 +445,19 @@ mod test {
let mut crease_map = CreaseMap::new(&snapshot);
let creases = [
- Crease::new(
+ Crease::inline(
snapshot.anchor_before(Point::new(1, 0))..snapshot.anchor_after(Point::new(1, 5)),
FoldPlaceholder::test(),
|_row, _folded, _toggle, _cx| div(),
|_row, _folded, _cx| div(),
),
- Crease::new(
+ Crease::inline(
snapshot.anchor_before(Point::new(3, 0))..snapshot.anchor_after(Point::new(3, 5)),
FoldPlaceholder::test(),
|_row, _folded, _toggle, _cx| div(),
|_row, _folded, _cx| div(),
),
- Crease::new(
+ Crease::inline(
snapshot.anchor_before(Point::new(5, 0))..snapshot.anchor_after(Point::new(5, 5)),
FoldPlaceholder::test(),
|_row, _folded, _toggle, _cx| div(),
@@ -402,12 +475,12 @@ mod test {
let range = MultiBufferRow(2)..MultiBufferRow(5);
let creases: Vec<_> = crease_snapshot.creases_in_range(range, &snapshot).collect();
assert_eq!(creases.len(), 1);
- assert_eq!(creases[0].range.start.to_point(&snapshot).row, 3);
+ assert_eq!(creases[0].range().start.to_point(&snapshot).row, 3);
let range = MultiBufferRow(0)..MultiBufferRow(2);
let creases: Vec<_> = crease_snapshot.creases_in_range(range, &snapshot).collect();
assert_eq!(creases.len(), 1);
- assert_eq!(creases[0].range.start.to_point(&snapshot).row, 1);
+ assert_eq!(creases[0].range().start.to_point(&snapshot).row, 1);
let range = MultiBufferRow(6)..MultiBufferRow(7);
let creases: Vec<_> = crease_snapshot.creases_in_range(range, &snapshot).collect();
@@ -6779,7 +6779,7 @@ impl Editor {
let mut edits = Vec::new();
let mut unfold_ranges = Vec::new();
- let mut refold_ranges = Vec::new();
+ let mut refold_creases = Vec::new();
let selections = self.selections.all::<Point>(cx);
let mut selections = selections.iter().peekable();
@@ -6854,7 +6854,7 @@ impl Editor {
let mut end = fold.range.end.to_point(&buffer);
start.row -= row_delta;
end.row -= row_delta;
- refold_ranges.push((start..end, fold.placeholder.clone()));
+ refold_creases.push(Crease::simple(start..end, fold.placeholder.clone()));
}
}
}
@@ -6870,7 +6870,7 @@ impl Editor {
buffer.edit([(range, text)], None, cx);
}
});
- this.fold_ranges(refold_ranges, true, cx);
+ this.fold_creases(refold_creases, true, cx);
this.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.select(new_selections);
})
@@ -6883,7 +6883,7 @@ impl Editor {
let mut edits = Vec::new();
let mut unfold_ranges = Vec::new();
- let mut refold_ranges = Vec::new();
+ let mut refold_creases = Vec::new();
let selections = self.selections.all::<Point>(cx);
let mut selections = selections.iter().peekable();
@@ -6948,7 +6948,7 @@ impl Editor {
let mut end = fold.range.end.to_point(&buffer);
start.row += row_delta;
end.row += row_delta;
- refold_ranges.push((start..end, fold.placeholder.clone()));
+ refold_creases.push(Crease::simple(start..end, fold.placeholder.clone()));
}
}
}
@@ -6964,7 +6964,7 @@ impl Editor {
buffer.edit([(range, text)], None, cx);
}
});
- this.fold_ranges(refold_ranges, true, cx);
+ this.fold_creases(refold_creases, true, cx);
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections));
});
}
@@ -10421,7 +10421,7 @@ impl Editor {
style: BlockStyle::Flex,
placement: BlockPlacement::Below(range.start),
height: 1,
- render: Box::new({
+ render: Arc::new({
let rename_editor = rename_editor.clone();
move |cx: &mut BlockContext| {
let mut text_style = cx.editor_style.text.clone();
@@ -10431,6 +10431,7 @@ impl Editor {
text_style = text_style.highlight(highlight_style);
}
div()
+ .occlude()
.pl(cx.anchor_x)
.child(EditorElement::new(
&rename_editor,
@@ -10894,7 +10895,7 @@ impl Editor {
}
pub fn fold(&mut self, _: &actions::Fold, cx: &mut ViewContext<Self>) {
- let mut fold_ranges = Vec::new();
+ let mut to_fold = Vec::new();
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all_adjusted(cx);
@@ -10906,12 +10907,10 @@ impl Editor {
let mut found = false;
let mut row = range.start.row;
while row <= range.end.row {
- if let Some((foldable_range, fold_text)) =
- { display_map.foldable_range(MultiBufferRow(row)) }
- {
+ if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) {
found = true;
- row = foldable_range.end.row + 1;
- fold_ranges.push((foldable_range, fold_text));
+ row = crease.range().end.row + 1;
+ to_fold.push(crease);
} else {
row += 1
}
@@ -10922,11 +10921,9 @@ impl Editor {
}
for row in (0..=range.start.row).rev() {
- if let Some((foldable_range, fold_text)) =
- display_map.foldable_range(MultiBufferRow(row))
- {
- if foldable_range.end.row >= buffer_start_row {
- fold_ranges.push((foldable_range, fold_text));
+ if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) {
+ if crease.range().end.row >= buffer_start_row {
+ to_fold.push(crease);
if row <= range.start.row {
break;
}
@@ -10935,26 +10932,29 @@ impl Editor {
}
}
- self.fold_ranges(fold_ranges, true, cx);
+ self.fold_creases(to_fold, true, cx);
}
fn fold_at_level(&mut self, fold_at: &FoldAtLevel, cx: &mut ViewContext<Self>) {
let fold_at_level = fold_at.level;
let snapshot = self.buffer.read(cx).snapshot(cx);
- let mut fold_ranges = Vec::new();
+ let mut to_fold = Vec::new();
let mut stack = vec![(0, snapshot.max_buffer_row().0, 1)];
while let Some((mut start_row, end_row, current_level)) = stack.pop() {
while start_row < end_row {
- match self.snapshot(cx).foldable_range(MultiBufferRow(start_row)) {
- Some(foldable_range) => {
- let nested_start_row = foldable_range.0.start.row + 1;
- let nested_end_row = foldable_range.0.end.row;
+ match self
+ .snapshot(cx)
+ .crease_for_buffer_row(MultiBufferRow(start_row))
+ {
+ Some(crease) => {
+ let nested_start_row = crease.range().start.row + 1;
+ let nested_end_row = crease.range().end.row;
if current_level < fold_at_level {
stack.push((nested_start_row, nested_end_row, current_level + 1));
} else if current_level == fold_at_level {
- fold_ranges.push(foldable_range);
+ to_fold.push(crease);
}
start_row = nested_end_row + 1;
@@ -10964,7 +10964,7 @@ impl Editor {
}
}
- self.fold_ranges(fold_ranges, true, cx);
+ self.fold_creases(to_fold, true, cx);
}
pub fn fold_all(&mut self, _: &actions::FoldAll, cx: &mut ViewContext<Self>) {
@@ -10972,16 +10972,18 @@ impl Editor {
let snapshot = self.buffer.read(cx).snapshot(cx);
for row in 0..snapshot.max_buffer_row().0 {
- if let Some(foldable_range) = self.snapshot(cx).foldable_range(MultiBufferRow(row)) {
+ if let Some(foldable_range) =
+ self.snapshot(cx).crease_for_buffer_row(MultiBufferRow(row))
+ {
fold_ranges.push(foldable_range);
}
}
- self.fold_ranges(fold_ranges, true, cx);
+ self.fold_creases(fold_ranges, true, cx);
}
pub fn fold_recursive(&mut self, _: &actions::FoldRecursive, cx: &mut ViewContext<Self>) {
- let mut fold_ranges = Vec::new();
+ let mut to_fold = Vec::new();
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all_adjusted(cx);
@@ -10992,11 +10994,9 @@ impl Editor {
if range.start.row != range.end.row {
let mut found = false;
for row in range.start.row..=range.end.row {
- if let Some((foldable_range, fold_text)) =
- { display_map.foldable_range(MultiBufferRow(row)) }
- {
+ if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) {
found = true;
- fold_ranges.push((foldable_range, fold_text));
+ to_fold.push(crease);
}
}
if found {
@@ -11005,11 +11005,9 @@ impl Editor {
}
for row in (0..=range.start.row).rev() {
- if let Some((foldable_range, fold_text)) =
- display_map.foldable_range(MultiBufferRow(row))
- {
- if foldable_range.end.row >= buffer_start_row {
- fold_ranges.push((foldable_range, fold_text));
+ if let Some(crease) = display_map.crease_for_buffer_row(MultiBufferRow(row)) {
+ if crease.range().end.row >= buffer_start_row {
+ to_fold.push(crease);
} else {
break;
}
@@ -11017,21 +11015,21 @@ impl Editor {
}
}
- self.fold_ranges(fold_ranges, true, cx);
+ self.fold_creases(to_fold, true, cx);
}
pub fn fold_at(&mut self, fold_at: &FoldAt, cx: &mut ViewContext<Self>) {
let buffer_row = fold_at.buffer_row;
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
- if let Some((fold_range, placeholder)) = display_map.foldable_range(buffer_row) {
+ if let Some(crease) = display_map.crease_for_buffer_row(buffer_row) {
let autoscroll = self
.selections
.all::<Point>(cx)
.iter()
- .any(|selection| fold_range.overlaps(&selection.range()));
+ .any(|selection| crease.range().overlaps(&selection.range()));
- self.fold_ranges([(fold_range, placeholder)], autoscroll, cx);
+ self.fold_creases(vec![crease], autoscroll, cx);
}
}
@@ -11092,81 +11090,78 @@ impl Editor {
pub fn unfold_all(&mut self, _: &actions::UnfoldAll, cx: &mut ViewContext<Self>) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
- self.unfold_ranges(
- &[Point::zero()..display_map.max_point().to_point(&display_map)],
- true,
- true,
- cx,
- );
+ self.unfold_ranges(&[0..display_map.buffer_snapshot.len()], true, true, cx);
}
pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
let selections = self.selections.all::<Point>(cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let line_mode = self.selections.line_mode;
- let ranges = selections.into_iter().map(|s| {
- if line_mode {
- let start = Point::new(s.start.row, 0);
- let end = Point::new(
- s.end.row,
- display_map
- .buffer_snapshot
- .line_len(MultiBufferRow(s.end.row)),
- );
- (start..end, display_map.fold_placeholder.clone())
- } else {
- (s.start..s.end, display_map.fold_placeholder.clone())
- }
- });
- self.fold_ranges(ranges, true, cx);
+ let ranges = selections
+ .into_iter()
+ .map(|s| {
+ if line_mode {
+ let start = Point::new(s.start.row, 0);
+ let end = Point::new(
+ s.end.row,
+ display_map
+ .buffer_snapshot
+ .line_len(MultiBufferRow(s.end.row)),
+ );
+ Crease::simple(start..end, display_map.fold_placeholder.clone())
+ } else {
+ Crease::simple(s.start..s.end, display_map.fold_placeholder.clone())
+ }
+ })
+ .collect::<Vec<_>>();
+ self.fold_creases(ranges, true, cx);
}
- pub fn fold_ranges<T: ToOffset + Clone>(
+ pub fn fold_creases<T: ToOffset + Clone>(
&mut self,
- ranges: impl IntoIterator<Item = (Range<T>, FoldPlaceholder)>,
+ creases: Vec<Crease<T>>,
auto_scroll: bool,
cx: &mut ViewContext<Self>,
) {
- let mut fold_ranges = Vec::new();
+ if creases.is_empty() {
+ return;
+ }
+
let mut buffers_affected = HashMap::default();
let multi_buffer = self.buffer().read(cx);
- for (fold_range, fold_text) in ranges {
+ for crease in &creases {
if let Some((_, buffer, _)) =
- multi_buffer.excerpt_containing(fold_range.start.clone(), cx)
+ multi_buffer.excerpt_containing(crease.range().start.clone(), cx)
{
buffers_affected.insert(buffer.read(cx).remote_id(), buffer);
};
- fold_ranges.push((fold_range, fold_text));
}
- let mut ranges = fold_ranges.into_iter().peekable();
- if ranges.peek().is_some() {
- self.display_map.update(cx, |map, cx| map.fold(ranges, cx));
+ self.display_map.update(cx, |map, cx| map.fold(creases, cx));
- if auto_scroll {
- self.request_autoscroll(Autoscroll::fit(), cx);
- }
+ if auto_scroll {
+ self.request_autoscroll(Autoscroll::fit(), cx);
+ }
- for buffer in buffers_affected.into_values() {
- self.sync_expanded_diff_hunks(buffer, cx);
- }
+ for buffer in buffers_affected.into_values() {
+ self.sync_expanded_diff_hunks(buffer, cx);
+ }
- cx.notify();
+ cx.notify();
- if let Some(active_diagnostics) = self.active_diagnostics.take() {
- // Clear diagnostics block when folding a range that contains it.
- let snapshot = self.snapshot(cx);
- if snapshot.intersects_fold(active_diagnostics.primary_range.start) {
- drop(snapshot);
- self.active_diagnostics = Some(active_diagnostics);
- self.dismiss_diagnostics(cx);
- } else {
- self.active_diagnostics = Some(active_diagnostics);
- }
+ if let Some(active_diagnostics) = self.active_diagnostics.take() {
+ // Clear diagnostics block when folding a range that contains it.
+ let snapshot = self.snapshot(cx);
+ if snapshot.intersects_fold(active_diagnostics.primary_range.start) {
+ drop(snapshot);
+ self.active_diagnostics = Some(active_diagnostics);
+ self.dismiss_diagnostics(cx);
+ } else {
+ self.active_diagnostics = Some(active_diagnostics);
}
-
- self.scrollbar_marker_state.dirty = true;
}
+
+ self.scrollbar_marker_state.dirty = true;
}
/// Removes any folds whose ranges intersect any of the given ranges.
@@ -11215,6 +11210,7 @@ impl Editor {
}
self.display_map.update(cx, update);
+
if auto_scroll {
self.request_autoscroll(Autoscroll::fit(), cx);
}
@@ -11317,7 +11313,7 @@ impl Editor {
pub fn insert_creases(
&mut self,
- creases: impl IntoIterator<Item = Crease>,
+ creases: impl IntoIterator<Item = Crease<Anchor>>,
cx: &mut ViewContext<Self>,
) -> Vec<CreaseId> {
self.display_map
@@ -14056,7 +14052,7 @@ impl EditorSnapshot {
}
}
- pub fn render_fold_toggle(
+ pub fn render_crease_toggle(
&self,
buffer_row: MultiBufferRow,
row_contains_cursor: bool,
@@ -14064,34 +14060,38 @@ impl EditorSnapshot {
cx: &mut WindowContext,
) -> Option<AnyElement> {
let folded = self.is_line_folded(buffer_row);
+ let mut is_foldable = false;
if let Some(crease) = self
.crease_snapshot
.query_row(buffer_row, &self.buffer_snapshot)
{
- let toggle_callback = Arc::new(move |folded, cx: &mut WindowContext| {
- if folded {
- editor.update(cx, |editor, cx| {
- editor.fold_at(&crate::FoldAt { buffer_row }, cx)
- });
- } else {
- editor.update(cx, |editor, cx| {
- editor.unfold_at(&crate::UnfoldAt { buffer_row }, cx)
- });
+ is_foldable = true;
+ match crease {
+ Crease::Inline { render_toggle, .. } | Crease::Block { render_toggle, .. } => {
+ if let Some(render_toggle) = render_toggle {
+ let toggle_callback = Arc::new(move |folded, cx: &mut WindowContext| {
+ if folded {
+ editor.update(cx, |editor, cx| {
+ editor.fold_at(&crate::FoldAt { buffer_row }, cx)
+ });
+ } else {
+ editor.update(cx, |editor, cx| {
+ editor.unfold_at(&crate::UnfoldAt { buffer_row }, cx)
+ });
+ }
+ });
+ return Some((render_toggle)(buffer_row, folded, toggle_callback, cx));
+ }
}
- });
+ }
+ }
- Some((crease.render_toggle)(
- buffer_row,
- folded,
- toggle_callback,
- cx,
- ))
- } else if folded
- || (self.starts_indent(buffer_row) && (row_contains_cursor || self.gutter_hovered))
- {
+ is_foldable |= self.starts_indent(buffer_row);
+
+ if folded || (is_foldable && (row_contains_cursor || self.gutter_hovered)) {
Some(
- Disclosure::new(("indent-fold-indicator", buffer_row.0), !folded)
+ Disclosure::new(("gutter_crease", buffer_row.0), !folded)
.selected(folded)
.on_click(cx.listener_for(&editor, move |this, _e, cx| {
if folded {
@@ -14113,10 +14113,15 @@ impl EditorSnapshot {
cx: &mut WindowContext,
) -> Option<AnyElement> {
let folded = self.is_line_folded(buffer_row);
- let crease = self
+ if let Crease::Inline { render_trailer, .. } = self
.crease_snapshot
- .query_row(buffer_row, &self.buffer_snapshot)?;
- Some((crease.render_trailer)(buffer_row, folded, cx))
+ .query_row(buffer_row, &self.buffer_snapshot)?
+ {
+ let render_trailer = render_trailer.as_ref()?;
+ Some(render_trailer(buffer_row, folded, cx))
+ } else {
+ None
+ }
}
}
@@ -14621,7 +14626,7 @@ pub fn diagnostic_block_renderer(
let (text_without_backticks, code_ranges) =
highlight_diagnostic_message(&diagnostic, max_message_rows);
- Box::new(move |cx: &mut BlockContext| {
+ Arc::new(move |cx: &mut BlockContext| {
let group_id: SharedString = cx.block_id.to_string().into();
let mut text_style = cx.text_style().clone();
@@ -14676,6 +14681,7 @@ pub fn diagnostic_block_renderer(
.group(group_id.clone())
.relative()
.size_full()
+ .occlude()
.pl(cx.gutter_dimensions.width)
.w(cx.max_width - cx.gutter_dimensions.full_width())
.child(
@@ -596,10 +596,10 @@ fn test_clone(cx: &mut TestAppContext) {
_ = editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| s.select_ranges(selection_ranges.clone()));
- editor.fold_ranges(
- [
- (Point::new(1, 0)..Point::new(2, 0), FoldPlaceholder::test()),
- (Point::new(3, 0)..Point::new(4, 0), FoldPlaceholder::test()),
+ editor.fold_creases(
+ vec![
+ Crease::simple(Point::new(1, 0)..Point::new(2, 0), FoldPlaceholder::test()),
+ Crease::simple(Point::new(3, 0)..Point::new(4, 0), FoldPlaceholder::test()),
],
true,
cx,
@@ -1283,11 +1283,11 @@ fn test_move_cursor_multibyte(cx: &mut TestAppContext) {
assert_eq!('α'.len_utf8(), 2);
_ = view.update(cx, |view, cx| {
- view.fold_ranges(
+ view.fold_creases(
vec![
- (Point::new(0, 6)..Point::new(0, 12), FoldPlaceholder::test()),
- (Point::new(1, 2)..Point::new(1, 4), FoldPlaceholder::test()),
- (Point::new(2, 4)..Point::new(2, 8), FoldPlaceholder::test()),
+ Crease::simple(Point::new(0, 6)..Point::new(0, 12), FoldPlaceholder::test()),
+ Crease::simple(Point::new(1, 2)..Point::new(1, 4), FoldPlaceholder::test()),
+ Crease::simple(Point::new(2, 4)..Point::new(2, 8), FoldPlaceholder::test()),
],
true,
cx,
@@ -3875,11 +3875,11 @@ fn test_move_line_up_down(cx: &mut TestAppContext) {
build_editor(buffer, cx)
});
_ = view.update(cx, |view, cx| {
- view.fold_ranges(
+ view.fold_creases(
vec![
- (Point::new(0, 2)..Point::new(1, 2), FoldPlaceholder::test()),
- (Point::new(2, 3)..Point::new(4, 1), FoldPlaceholder::test()),
- (Point::new(7, 0)..Point::new(8, 4), FoldPlaceholder::test()),
+ Crease::simple(Point::new(0, 2)..Point::new(1, 2), FoldPlaceholder::test()),
+ Crease::simple(Point::new(2, 3)..Point::new(4, 1), FoldPlaceholder::test()),
+ Crease::simple(Point::new(7, 0)..Point::new(8, 4), FoldPlaceholder::test()),
],
true,
cx,
@@ -3980,7 +3980,7 @@ fn test_move_line_up_down_with_blocks(cx: &mut TestAppContext) {
style: BlockStyle::Fixed,
placement: BlockPlacement::Below(snapshot.anchor_after(Point::new(2, 0))),
height: 1,
- render: Box::new(|_| div().into_any()),
+ render: Arc::new(|_| div().into_any()),
priority: 0,
}],
Some(Autoscroll::fit()),
@@ -4022,7 +4022,7 @@ async fn test_selections_and_replace_blocks(cx: &mut TestAppContext) {
placement,
height: 4,
style: BlockStyle::Sticky,
- render: Box::new(|_| gpui::div().into_any_element()),
+ render: Arc::new(|_| gpui::div().into_any_element()),
priority: 0,
}],
None,
@@ -4717,11 +4717,11 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) {
build_editor(buffer, cx)
});
_ = view.update(cx, |view, cx| {
- view.fold_ranges(
+ view.fold_creases(
vec![
- (Point::new(0, 2)..Point::new(1, 2), FoldPlaceholder::test()),
- (Point::new(2, 3)..Point::new(4, 1), FoldPlaceholder::test()),
- (Point::new(7, 0)..Point::new(8, 4), FoldPlaceholder::test()),
+ Crease::simple(Point::new(0, 2)..Point::new(1, 2), FoldPlaceholder::test()),
+ Crease::simple(Point::new(2, 3)..Point::new(4, 1), FoldPlaceholder::test()),
+ Crease::simple(Point::new(7, 0)..Point::new(8, 4), FoldPlaceholder::test()),
],
true,
cx,
@@ -5398,13 +5398,13 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
// Ensure that we keep expanding the selection if the larger selection starts or ends within
// a fold.
editor.update(cx, |view, cx| {
- view.fold_ranges(
+ view.fold_creases(
vec![
- (
+ Crease::simple(
Point::new(0, 21)..Point::new(0, 24),
FoldPlaceholder::test(),
),
- (
+ Crease::simple(
Point::new(3, 20)..Point::new(3, 22),
FoldPlaceholder::test(),
),
@@ -13139,7 +13139,7 @@ fn test_crease_insertion_and_rendering(cx: &mut TestAppContext) {
callback: Arc<dyn Fn(bool, &mut WindowContext) + Send + Sync>,
}
- let crease = Crease::new(
+ let crease = Crease::inline(
range,
FoldPlaceholder::test(),
{
@@ -13158,7 +13158,8 @@ fn test_crease_insertion_and_rendering(cx: &mut TestAppContext) {
editor.insert_creases(Some(crease), cx);
let snapshot = editor.snapshot(cx);
- let _div = snapshot.render_fold_toggle(MultiBufferRow(1), false, cx.view().clone(), cx);
+ let _div =
+ snapshot.render_crease_toggle(MultiBufferRow(1), false, cx.view().clone(), cx);
snapshot
})
.unwrap();
@@ -1227,9 +1227,9 @@ impl EditorElement {
}
#[allow(clippy::too_many_arguments)]
- fn prepaint_gutter_fold_toggles(
+ fn prepaint_crease_toggles(
&self,
- toggles: &mut [Option<AnyElement>],
+ crease_toggles: &mut [Option<AnyElement>],
line_height: Pixels,
gutter_dimensions: &GutterDimensions,
gutter_settings: crate::editor_settings::Gutter,
@@ -1237,25 +1237,25 @@ impl EditorElement {
gutter_hitbox: &Hitbox,
cx: &mut WindowContext,
) {
- for (ix, fold_indicator) in toggles.iter_mut().enumerate() {
- if let Some(fold_indicator) = fold_indicator {
+ for (ix, crease_toggle) in crease_toggles.iter_mut().enumerate() {
+ if let Some(crease_toggle) = crease_toggle {
debug_assert!(gutter_settings.folds);
let available_space = size(
AvailableSpace::MinContent,
AvailableSpace::Definite(line_height * 0.55),
);
- let fold_indicator_size = fold_indicator.layout_as_root(available_space, cx);
+ let crease_toggle_size = crease_toggle.layout_as_root(available_space, cx);
let position = point(
gutter_dimensions.width - gutter_dimensions.right_padding,
ix as f32 * line_height - (scroll_pixel_position.y % line_height),
);
let centering_offset = point(
- (gutter_dimensions.fold_area_width() - fold_indicator_size.width) / 2.,
- (line_height - fold_indicator_size.height) / 2.,
+ (gutter_dimensions.fold_area_width() - crease_toggle_size.width) / 2.,
+ (line_height - crease_toggle_size.height) / 2.,
);
let origin = gutter_hitbox.origin + position + centering_offset;
- fold_indicator.prepaint_as_root(origin, available_space, cx);
+ crease_toggle.prepaint_as_root(origin, available_space, cx);
}
}
}
@@ -1915,7 +1915,7 @@ impl EditorElement {
.collect()
}
- fn layout_gutter_fold_toggles(
+ fn layout_crease_toggles(
&self,
rows: Range<DisplayRow>,
buffer_rows: impl IntoIterator<Item = Option<MultiBufferRow>>,
@@ -1934,7 +1934,7 @@ impl EditorElement {
if let Some(multibuffer_row) = row {
let display_row = DisplayRow(rows.start.0 + ix as u32);
let active = active_rows.contains_key(&display_row);
- snapshot.render_fold_toggle(
+ snapshot.render_crease_toggle(
multibuffer_row,
active,
self.editor.clone(),
@@ -2122,9 +2122,7 @@ impl EditorElement {
max_width: text_hitbox.size.width.max(*scroll_width),
editor_style: &self.style,
}))
- .cursor(CursorStyle::Arrow)
- .on_mouse_down(MouseButton::Left, |_, cx| cx.stop_propagation())
- .into_any_element()
+ .into_any()
}
Block::ExcerptBoundary {
@@ -3354,9 +3352,9 @@ impl EditorElement {
fn paint_gutter_indicators(&self, layout: &mut EditorLayout, cx: &mut WindowContext) {
cx.paint_layer(layout.gutter_hitbox.bounds, |cx| {
- cx.with_element_namespace("gutter_fold_toggles", |cx| {
- for fold_indicator in layout.gutter_fold_toggles.iter_mut().flatten() {
- fold_indicator.paint(cx);
+ cx.with_element_namespace("crease_toggles", |cx| {
+ for crease_toggle in layout.crease_toggles.iter_mut().flatten() {
+ crease_toggle.paint(cx);
}
});
@@ -5167,16 +5165,15 @@ impl Element for EditorElement {
cx,
);
- let mut gutter_fold_toggles =
- cx.with_element_namespace("gutter_fold_toggles", |cx| {
- self.layout_gutter_fold_toggles(
- start_row..end_row,
- buffer_rows.iter().copied(),
- &active_rows,
- &snapshot,
- cx,
- )
- });
+ let mut crease_toggles = cx.with_element_namespace("crease_toggles", |cx| {
+ self.layout_crease_toggles(
+ start_row..end_row,
+ buffer_rows.iter().copied(),
+ &active_rows,
+ &snapshot,
+ cx,
+ )
+ });
let crease_trailers = cx.with_element_namespace("crease_trailers", |cx| {
self.layout_crease_trailers(buffer_rows.iter().copied(), &snapshot, cx)
});
@@ -5556,9 +5553,9 @@ impl Element for EditorElement {
let mouse_context_menu =
self.layout_mouse_context_menu(&snapshot, start_row..end_row, cx);
- cx.with_element_namespace("gutter_fold_toggles", |cx| {
- self.prepaint_gutter_fold_toggles(
- &mut gutter_fold_toggles,
+ cx.with_element_namespace("crease_toggles", |cx| {
+ self.prepaint_crease_toggles(
+ &mut crease_toggles,
line_height,
&gutter_dimensions,
gutter_settings,
@@ -5638,7 +5635,7 @@ impl Element for EditorElement {
mouse_context_menu,
test_indicators,
code_actions_indicator,
- gutter_fold_toggles,
+ crease_toggles,
crease_trailers,
tab_invisible,
space_invisible,
@@ -5671,7 +5668,6 @@ impl Element for EditorElement {
line_height: Some(self.style.text.line_height),
..Default::default()
};
- let mouse_position = cx.mouse_position();
let hovered_hunk = layout
.display_hunks
.iter()
@@ -5685,7 +5681,7 @@ impl Element for EditorElement {
} => {
if hunk_hitbox
.as_ref()
- .map(|hitbox| hitbox.contains(&mouse_position))
+ .map(|hitbox| hitbox.is_hovered(cx))
.unwrap_or(false)
{
Some(HoveredHunk {
@@ -5778,7 +5774,7 @@ pub struct EditorLayout {
selections: Vec<(PlayerColor, Vec<SelectionLayout>)>,
code_actions_indicator: Option<AnyElement>,
test_indicators: Vec<AnyElement>,
- gutter_fold_toggles: Vec<Option<AnyElement>>,
+ crease_toggles: Vec<Option<AnyElement>>,
crease_trailers: Vec<Option<CreaseTrailerLayout>>,
mouse_context_menu: Option<AnyElement>,
tab_invisible: ShapedLine,
@@ -6623,7 +6619,7 @@ mod tests {
style: BlockStyle::Fixed,
placement: BlockPlacement::Above(Anchor::min()),
height: 3,
- render: Box::new(|cx| div().h(3. * cx.line_height()).into_any()),
+ render: Arc::new(|cx| div().h(3. * cx.line_height()).into_any()),
priority: 0,
}],
None,
@@ -425,7 +425,7 @@ impl Editor {
height: 1,
style: BlockStyle::Sticky,
priority: 0,
- render: Box::new({
+ render: Arc::new({
let editor = cx.view().clone();
let hunk = hunk.clone();
@@ -435,6 +435,7 @@ impl Editor {
h_flex()
.id(cx.block_id)
+ .occlude()
.h(cx.line_height())
.w_full()
.border_t_1()
@@ -707,12 +708,13 @@ impl Editor {
height,
style: BlockStyle::Flex,
priority: 0,
- render: Box::new(move |cx| {
+ render: Arc::new(move |cx| {
let width = EditorElement::diff_hunk_strip_width(cx.line_height());
let gutter_dimensions = editor.read(cx.context).gutter_dimensions;
h_flex()
.id(cx.block_id)
+ .occlude()
.bg(deleted_hunk_color)
.h(height as f32 * cx.line_height())
.w_full()
@@ -125,7 +125,7 @@ pub struct MultiBufferDiffHunk {
pub type MultiBufferPoint = Point;
-#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq, serde::Deserialize)]
+#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq, Hash, serde::Deserialize)]
#[serde(transparent)]
pub struct MultiBufferRow(pub u32);
@@ -121,7 +121,7 @@ impl EditorBlock {
execution_view: View<ExecutionView>,
on_close: CloseBlockFn,
) -> RenderBlock {
- let render = move |cx: &mut BlockContext| {
+ Arc::new(move |cx: &mut BlockContext| {
let execution_view = execution_view.clone();
let text_style = crate::outputs::plain::text_style(cx);
@@ -163,6 +163,7 @@ impl EditorBlock {
div()
.id(cx.block_id)
+ .occlude()
.flex()
.items_start()
.min_h(text_line_height)
@@ -186,9 +187,7 @@ impl EditorBlock {
.child(execution_view),
)
.into_any_element()
- };
-
- Box::new(render)
+ })
}
}