Detailed changes
@@ -257,9 +257,9 @@ checksum = "34cd60c5e3152cef0a592f1b296f1cc93715d89d2551d85315828c3a09575ff4"
[[package]]
name = "anyhow"
-version = "1.0.97"
+version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4"
[[package]]
name = "approx"
@@ -284,7 +284,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -398,7 +398,7 @@ dependencies = [
"ctor",
"db",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"feature_flags",
"fs",
"futures 0.3.31",
@@ -578,7 +578,7 @@ dependencies = [
"client",
"collections",
"context_server",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"fs",
"futures 0.3.31",
"gpui",
@@ -655,7 +655,7 @@ dependencies = [
"collections",
"context_server",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"feature_flags",
"fs",
"futures 0.3.31",
@@ -950,7 +950,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -1018,7 +1018,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -1075,13 +1075,13 @@ dependencies = [
[[package]]
name = "async-trait"
-version = "0.1.87"
+version = "0.1.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97"
+checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -1285,25 +1285,27 @@ dependencies = [
[[package]]
name = "aws-lc-rs"
-version = "1.12.6"
+version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01"
+checksum = "4c2b7ddaa2c56a367ad27a094ad8ef4faacf8a617c2575acb2ba88949df999ca"
dependencies = [
"aws-lc-sys",
+ "paste",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
-version = "0.27.0"
+version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bbe221bbf523b625a4dd8585c7f38166e31167ec2ca98051dbcb4c3b6e825d2"
+checksum = "71b2ddd3ada61a305e1d8bb6c005d1eaa7d14d903681edfc400406d523a9b491"
dependencies = [
"bindgen 0.69.5",
"cc",
"cmake",
"dunce",
"fs_extra",
+ "paste",
]
[[package]]
@@ -1883,7 +1885,7 @@ dependencies = [
"regex",
"rustc-hash 1.1.0",
"shlex",
- "syn 2.0.100",
+ "syn 2.0.90",
"which 4.4.2",
]
@@ -1904,7 +1906,7 @@ dependencies = [
"regex",
"rustc-hash 1.1.0",
"shlex",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -2015,7 +2017,7 @@ source = "git+https://github.com/kvark/blade?rev=b16f5c7bd873c7126f48c82c39e7ae6
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -2108,7 +2110,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -2142,7 +2144,7 @@ dependencies = [
"anyhow",
"clock",
"ctor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures 0.3.31",
"git2",
"gpui",
@@ -2218,7 +2220,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -2480,7 +2482,7 @@ dependencies = [
"quote",
"serde",
"serde_json",
- "syn 2.0.100",
+ "syn 2.0.90",
"tempfile",
"toml 0.8.20",
]
@@ -2498,7 +2500,7 @@ dependencies = [
"quote",
"serde",
"serde_json",
- "syn 2.0.100",
+ "syn 2.0.90",
"tempfile",
"toml 0.8.20",
]
@@ -2652,9 +2654,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.32"
+version = "4.5.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83"
+checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767"
dependencies = [
"clap_builder",
"clap_derive",
@@ -2662,9 +2664,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.32"
+version = "4.5.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8"
+checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863"
dependencies = [
"anstream",
"anstyle",
@@ -2684,14 +2686,14 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.5.32"
+version = "4.5.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
+checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -2892,7 +2894,7 @@ dependencies = [
"dashmap 6.1.0",
"derive_more",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"envy",
"extension",
"file_finder",
@@ -3051,7 +3053,7 @@ dependencies = [
"command_palette_hooks",
"ctor",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"fuzzy",
"go_to_line",
"gpui",
@@ -3235,7 +3237,7 @@ dependencies = [
"command_palette_hooks",
"ctor",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"fs",
"futures 0.3.31",
"gpui",
@@ -3744,9 +3746,9 @@ dependencies = [
[[package]]
name = "ctor"
-version = "0.4.1"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07e9666f4a9a948d4f1dff0c08a4512b0f7c86414b23960104c243c10d79f4c3"
+checksum = "a7747ac3a66a06f4ee6718686c8ea976d2d05fb30ada93ebd76b3f9aef97257c"
dependencies = [
"ctor-proc-macro",
"dtor",
@@ -3799,7 +3801,7 @@ dependencies = [
"proc-macro2",
"quote",
"scratch",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -3812,7 +3814,7 @@ dependencies = [
"codespan-reporting",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -3830,7 +3832,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -3965,7 +3967,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -3986,7 +3988,7 @@ dependencies = [
"collections",
"ctor",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"gpui",
"language",
"log",
@@ -4085,7 +4087,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -4134,9 +4136,9 @@ dependencies = [
[[package]]
name = "dtor"
-version = "0.0.5"
+version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "222ef136a1c687d4aa0395c175f2c4586e379924c352fd02f7870cf7de783c23"
+checksum = "8bf39a0bfd1f94d62ffdb2802a7e6244c0f34f6ebacf5d4c26547d08cd1d67a5"
dependencies = [
"dtor-proc-macro",
]
@@ -4205,7 +4207,7 @@ dependencies = [
"ctor",
"db",
"emojis",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"file_icons",
"fs",
"futures 0.3.31",
@@ -4374,7 +4376,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -4408,14 +4410,14 @@ dependencies = [
[[package]]
name = "env_logger"
-version = "0.11.7"
+version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697"
+checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0"
dependencies = [
"anstream",
"anstyle",
"env_filter",
- "jiff",
+ "humantime",
"log",
]
@@ -4514,7 +4516,7 @@ dependencies = [
"client",
"clock",
"collections",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"feature_flags",
"fs",
"gpui",
@@ -4619,7 +4621,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"clap",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"extension",
"fs",
"language",
@@ -4647,7 +4649,7 @@ dependencies = [
"collections",
"context_server_settings",
"ctor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"extension",
"fs",
"futures 0.3.31",
@@ -4842,7 +4844,7 @@ dependencies = [
"collections",
"ctor",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"file_icons",
"futures 0.3.31",
"fuzzy",
@@ -5052,7 +5054,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -5313,7 +5315,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -5525,7 +5527,7 @@ dependencies = [
"ctor",
"db",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures 0.3.31",
"fuzzy",
"git",
@@ -5702,7 +5704,7 @@ dependencies = [
"ctor",
"derive_more",
"embed-resource",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"etagere",
"filedescriptor",
"flume",
@@ -6093,7 +6095,7 @@ dependencies = [
"markup5ever",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -6480,7 +6482,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -6657,7 +6659,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -6767,7 +6769,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -6907,30 +6909,6 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
-[[package]]
-name = "jiff"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e"
-dependencies = [
- "jiff-static",
- "log",
- "portable-atomic",
- "portable-atomic-util",
- "serde",
-]
-
-[[package]]
-name = "jiff-static"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.100",
-]
-
[[package]]
name = "jni"
version = "0.21.1"
@@ -7102,7 +7080,7 @@ dependencies = [
"collections",
"ctor",
"ec4rs",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"fs",
"futures 0.3.31",
"fuzzy",
@@ -7282,7 +7260,7 @@ dependencies = [
"collections",
"copilot",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures 0.3.31",
"gpui",
"itertools 0.14.0",
@@ -7389,9 +7367,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
-version = "0.2.171"
+version = "0.2.170"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
[[package]]
name = "libdbus-sys"
@@ -7542,7 +7520,7 @@ checksum = "71a98813fa0073a317ed6a8055dcd4722a49d9b862af828ee68449adb799b6be"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -7769,7 +7747,7 @@ dependencies = [
"async-pipe",
"collections",
"ctor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures 0.3.31",
"gpui",
"log",
@@ -7914,7 +7892,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"assets",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"gpui",
"language",
"languages",
@@ -8018,9 +7996,9 @@ dependencies = [
[[package]]
name = "mdbook"
-version = "0.4.47"
+version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e1a8fe3a4a01f28dab245c474cb7b95ccb4d3d2f17a5419a3d949f474c45e84"
+checksum = "b07d36d96ffe1b5b16ddf2bc80b3b26bb7a498b2a6591061250bf0af8e8095ad"
dependencies = [
"ammonia",
"anyhow",
@@ -8028,10 +8006,9 @@ dependencies = [
"clap",
"clap_complete",
"elasticlunr-rs",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures-util",
"handlebars 6.2.0",
- "hex",
"ignore",
"log",
"memchr",
@@ -8044,7 +8021,6 @@ dependencies = [
"regex",
"serde",
"serde_json",
- "sha2",
"shlex",
"tempfile",
"tokio",
@@ -8276,7 +8252,7 @@ dependencies = [
"clock",
"collections",
"ctor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures 0.3.31",
"gpui",
"indoc",
@@ -8641,7 +8617,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -8738,7 +8714,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -9130,7 +9106,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -9217,7 +9193,7 @@ dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -9332,7 +9308,7 @@ dependencies = [
"by_address",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -9574,7 +9550,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -10021,7 +9997,7 @@ dependencies = [
"phf_shared 0.11.2",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -10049,7 +10025,7 @@ dependencies = [
"anyhow",
"ctor",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"gpui",
"menu",
"schemars",
@@ -10083,7 +10059,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -10221,21 +10197,6 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7"
-[[package]]
-name = "portable-atomic"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
-
-[[package]]
-name = "portable-atomic-util"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
-dependencies = [
- "portable-atomic",
-]
-
[[package]]
name = "postage"
version = "0.5.0"
@@ -10322,7 +10283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
dependencies = [
"proc-macro2",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -10353,14 +10314,14 @@ dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
@@ -10373,7 +10334,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
"version_check",
"yansi",
]
@@ -10394,7 +10355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30"
dependencies = [
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -10409,7 +10370,7 @@ dependencies = [
"client",
"clock",
"collections",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"extension",
"fancy-regex 0.14.0",
"fs",
@@ -10636,7 +10597,7 @@ dependencies = [
"prost 0.12.6",
"prost-types 0.12.6",
"regex",
- "syn 2.0.100",
+ "syn 2.0.90",
"tempfile",
]
@@ -10663,7 +10624,7 @@ dependencies = [
"itertools 0.12.1",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -10859,9 +10820,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.40"
+version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
@@ -11261,7 +11222,7 @@ dependencies = [
"clap",
"client",
"clock",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"extension",
"extension_host",
"fork",
@@ -11322,7 +11283,7 @@ dependencies = [
"collections",
"command_palette_hooks",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"feature_flags",
"file_icons",
"futures 0.3.31",
@@ -11598,7 +11559,7 @@ dependencies = [
"arrayvec",
"criterion",
"ctor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"gpui",
"log",
"rand 0.8.5",
@@ -11624,7 +11585,7 @@ dependencies = [
"base64 0.22.1",
"chrono",
"collections",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures 0.3.31",
"gpui",
"parking_lot",
@@ -11642,9 +11603,9 @@ dependencies = [
[[package]]
name = "rsa"
-version = "0.9.8"
+version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
+checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519"
dependencies = [
"const-oid",
"digest",
@@ -11706,7 +11667,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
- "syn 2.0.100",
+ "syn 2.0.90",
"walkdir",
]
@@ -11998,7 +11959,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"clap",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"schemars",
"serde",
"serde_json",
@@ -12007,9 +11968,9 @@ dependencies = [
[[package]]
name = "schemars"
-version = "0.8.22"
+version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
+checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92"
dependencies = [
"dyn-clone",
"indexmap",
@@ -12020,14 +11981,14 @@ dependencies = [
[[package]]
name = "schemars_derive"
-version = "0.8.22"
+version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d"
+checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e"
dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -12104,7 +12065,7 @@ dependencies = [
"proc-macro-error2",
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -12145,7 +12106,7 @@ dependencies = [
"proc-macro2",
"quote",
"sea-bae",
- "syn 2.0.100",
+ "syn 2.0.90",
"unicode-ident",
]
@@ -12281,7 +12242,7 @@ dependencies = [
"client",
"clock",
"collections",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"feature_flags",
"fs",
"futures 0.3.31",
@@ -12347,7 +12308,7 @@ checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -12358,7 +12319,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -12436,7 +12397,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -12971,7 +12932,7 @@ dependencies = [
"quote",
"sqlx-core",
"sqlx-macros-core",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -12994,7 +12955,7 @@ dependencies = [
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
- "syn 2.0.100",
+ "syn 2.0.90",
"tempfile",
"tokio",
"url",
@@ -13253,7 +13214,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn 2.0.100",
+ "syn 2.0.90",
]
[[package]]
@@ -13268,7 +13229,7 @@ version = "0.1.0"
dependencies = [
"arrayvec",
"ctor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"log",
"rand 0.8.5",
"rayon",
@@ -13282,7 +13243,7 @@ dependencies = [
"client",
"collections",
"editor",
- "env_logger 0.11.7",
+ "env_logger 0.11.6",
"futures 0.3.31",
"gpui",
"http_client",
@@ -13434,9 +13395,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.100"
+version = "2.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
dependencies = [
"proc-macro2",
"quote",
@@ -326,6 +326,13 @@ impl Bind for Arc<Path> {
self.as_ref().bind(statement, start_index)
}
}
+impl Column for Arc<Path> {
+ fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
+ let blob = statement.column_blob(start_index)?;
+
+ PathBuf::try_from_bytes(blob).map(|path| (Arc::from(path.as_path()), start_index + 1))
+ }
+}
impl StaticColumnCount for PathBuf {}
impl Bind for PathBuf {
@@ -22,6 +22,7 @@ async-trait = { workspace = true, "optional" = true }
collections.workspace = true
command_palette.workspace = true
command_palette_hooks.workspace = true
+db.workspace = true
editor.workspace = true
futures.workspace = true
gpui.workspace = true
@@ -32,6 +33,7 @@ log.workspace = true
multi_buffer.workspace = true
nvim-rs = { git = "https://github.com/KillTheMule/nvim-rs", branch = "master", features = ["use_tokio"], optional = true }
picker.workspace = true
+project.workspace = true
regex.workspace = true
schemars.workspace = true
search.workspace = true
@@ -40,6 +42,7 @@ serde_derive.workspace = true
serde_json.workspace = true
settings.workspace = true
task.workspace = true
+text.workspace = true
theme.workspace = true
tokio = { version = "1.15", features = ["full"], optional = true }
ui.workspace = true
@@ -1,4 +1,6 @@
-use editor::{display_map::ToDisplayPoint, movement, scroll::Autoscroll, Bias, Direction, Editor};
+use editor::{
+ display_map::ToDisplayPoint, movement, scroll::Autoscroll, Anchor, Bias, Direction, Editor,
+};
use gpui::{actions, Context, Window};
use crate::{state::Mode, Vim};
@@ -48,8 +50,10 @@ impl Vim {
}
pub(crate) fn push_to_change_list(&mut self, window: &mut Window, cx: &mut Context<Self>) {
- let Some((map, selections)) = self.update_editor(window, cx, |_, editor, _, cx| {
- editor.selections.all_adjusted_display(cx)
+ let Some((map, selections, buffer)) = self.update_editor(window, cx, |_, editor, _, cx| {
+ let (map, selections) = editor.selections.all_adjusted_display(cx);
+ let buffer = editor.buffer().clone();
+ (map, selections, buffer)
}) else {
return;
};
@@ -65,7 +69,7 @@ impl Vim {
})
.unwrap_or(false);
- let new_positions = selections
+ let new_positions: Vec<Anchor> = selections
.into_iter()
.map(|s| {
let point = if self.mode == Mode::Insert {
@@ -81,7 +85,8 @@ impl Vim {
if pop_state {
self.change_list.pop();
}
- self.change_list.push(new_positions);
+ self.change_list.push(new_positions.clone());
+ self.set_mark(".".to_string(), new_positions, &buffer, window, cx)
}
}
@@ -37,7 +37,7 @@ use crate::{
JoinLines,
},
object::Object,
- state::Mode,
+ state::{Mark, Mode},
visual::VisualDeleteLine,
ToggleRegistersView, Vim,
};
@@ -284,6 +284,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
true,
true,
vec![Point::new(range.start.0, 0)..end],
+ window,
cx,
)
}
@@ -594,9 +595,14 @@ impl Position {
}
}
Position::Mark { name, offset } => {
- let Some(mark) = vim.marks.get(&name.to_string()).and_then(|vec| vec.last()) else {
+ let Some(Mark::Local(anchors)) =
+ vim.get_mark(&name.to_string(), editor, window, cx)
+ else {
return Err(anyhow!("mark {} not set", name));
};
+ let Some(mark) = anchors.last() else {
+ return Err(anyhow!("mark {} contains empty anchors", name));
+ };
mark.to_point(&snapshot.buffer_snapshot)
.row
.saturating_add_signed(*offset)
@@ -254,7 +254,7 @@ impl Vim {
});
});
- vim.copy_selections_content(editor, false, cx);
+ vim.copy_selections_content(editor, false, window, cx);
editor.insert("", window, cx);
});
}
@@ -25,7 +25,7 @@ impl Vim {
let count = Vim::take_count(cx).unwrap_or(1);
self.stop_recording_immediately(action.boxed_clone(), cx);
if count <= 1 || Vim::globals(cx).dot_replaying {
- self.create_mark("^".into(), false, window, cx);
+ self.create_mark("^".into(), window, cx);
self.update_editor(window, cx, |_, editor, window, cx| {
editor.dismiss_menus_and_popups(false, window, cx);
editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
@@ -1889,7 +1889,7 @@ pub(crate) fn end_of_line(
}
}
-fn sentence_backwards(
+pub(crate) fn sentence_backwards(
map: &DisplaySnapshot,
point: DisplayPoint,
mut times: usize,
@@ -1935,7 +1935,11 @@ fn sentence_backwards(
DisplayPoint::zero()
}
-fn sentence_forwards(map: &DisplaySnapshot, point: DisplayPoint, mut times: usize) -> DisplayPoint {
+pub(crate) fn sentence_forwards(
+ map: &DisplaySnapshot,
+ point: DisplayPoint,
+ mut times: usize,
+) -> DisplayPoint {
let start = point.to_point(map).to_offset(&map.buffer_snapshot);
let mut chars = map.buffer_chars_at(start).peekable();
@@ -18,7 +18,7 @@ use crate::{
indent::IndentDirection,
motion::{self, first_non_whitespace, next_line_end, right, Motion},
object::Object,
- state::{Mode, Operator},
+ state::{Mark, Mode, Operator},
surrounds::SurroundsType,
Vim,
};
@@ -355,11 +355,13 @@ impl Vim {
self.start_recording(cx);
self.switch_mode(Mode::Insert, false, window, cx);
self.update_editor(window, cx, |vim, editor, window, cx| {
- if let Some(marks) = vim.marks.get("^") {
- editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
- s.select_anchor_ranges(marks.iter().map(|mark| *mark..*mark))
- });
- }
+ let Some(Mark::Local(marks)) = vim.get_mark("^", editor, window, cx) else {
+ return;
+ };
+
+ editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
+ s.select_anchor_ranges(marks.iter().map(|mark| *mark..*mark))
+ });
});
}
@@ -76,7 +76,7 @@ impl Vim {
}
});
});
- vim.copy_selections_content(editor, motion.linewise(), cx);
+ vim.copy_selections_content(editor, motion.linewise(), window, cx);
editor.insert("", window, cx);
editor.refresh_inline_completion(true, false, window, cx);
});
@@ -107,7 +107,7 @@ impl Vim {
});
});
if objects_found {
- vim.copy_selections_content(editor, false, cx);
+ vim.copy_selections_content(editor, false, window, cx);
editor.insert("", window, cx);
editor.refresh_inline_completion(true, false, window, cx);
}
@@ -60,7 +60,7 @@ impl Vim {
}
});
});
- vim.copy_selections_content(editor, motion.linewise(), cx);
+ vim.copy_selections_content(editor, motion.linewise(), window, cx);
editor.insert("", window, cx);
// Fixup cursor position after the deletion
@@ -148,7 +148,7 @@ impl Vim {
}
});
});
- vim.copy_selections_content(editor, false, cx);
+ vim.copy_selections_content(editor, false, window, cx);
editor.insert("", window, cx);
// Fixup cursor position after the deletion
@@ -1,39 +1,34 @@
-use std::{ops::Range, sync::Arc};
+use std::{ops::Range, path::Path, sync::Arc};
use editor::{
display_map::{DisplaySnapshot, ToDisplayPoint},
movement,
scroll::Autoscroll,
- Anchor, Bias, DisplayPoint,
+ Anchor, Bias, DisplayPoint, Editor, MultiBuffer,
};
-use gpui::{Context, Window};
+use gpui::{Context, Entity, EntityId, UpdateGlobal, Window};
use language::SelectionGoal;
+use text::Point;
+use ui::App;
+use workspace::OpenOptions;
use crate::{
motion::{self, Motion},
- state::Mode,
+ state::{Mark, Mode, VimGlobals},
Vim,
};
impl Vim {
- pub fn create_mark(
- &mut self,
- text: Arc<str>,
- tail: bool,
- window: &mut Window,
- cx: &mut Context<Self>,
- ) {
- let Some(anchors) = self.update_editor(window, cx, |_, editor, _, _| {
- editor
+ pub fn create_mark(&mut self, text: Arc<str>, window: &mut Window, cx: &mut Context<Self>) {
+ self.update_editor(window, cx, |vim, editor, window, cx| {
+ let anchors = editor
.selections
.disjoint_anchors()
.iter()
- .map(|s| if tail { s.tail() } else { s.head() })
- .collect::<Vec<_>>()
- }) else {
- return;
- };
- self.marks.insert(text.to_string(), anchors);
+ .map(|s| s.head())
+ .collect::<Vec<_>>();
+ vim.set_mark(text.to_string(), anchors, editor.buffer(), window, cx);
+ });
self.clear_operator(window, cx);
}
@@ -55,7 +50,7 @@ impl Vim {
let mut ends = vec![];
let mut reversed = vec![];
- self.update_editor(window, cx, |_, editor, _, cx| {
+ self.update_editor(window, cx, |vim, editor, window, cx| {
let (map, selections) = editor.selections.all_display(cx);
for selection in selections {
let end = movement::saturating_left(&map, selection.end);
@@ -69,13 +64,121 @@ impl Vim {
);
reversed.push(selection.reversed)
}
+ vim.set_mark("<".to_string(), starts, editor.buffer(), window, cx);
+ vim.set_mark(">".to_string(), ends, editor.buffer(), window, cx);
});
- self.marks.insert("<".to_string(), starts);
- self.marks.insert(">".to_string(), ends);
self.stored_visual_mode.replace((mode, reversed));
}
+ fn open_buffer_mark(
+ &mut self,
+ line: bool,
+ entity_id: EntityId,
+ anchors: Vec<Anchor>,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ let Some(workspace) = self.workspace(window) else {
+ return;
+ };
+ workspace.update(cx, |workspace, cx| {
+ let item = workspace.items(cx).find(|item| {
+ item.act_as::<Editor>(cx)
+ .is_some_and(|editor| editor.read(cx).buffer().entity_id() == entity_id)
+ });
+ let Some(item) = item.cloned() else {
+ return;
+ };
+ if let Some(pane) = workspace.pane_for(item.as_ref()) {
+ pane.update(cx, |pane, cx| {
+ if let Some(index) = pane.index_for_item(item.as_ref()) {
+ pane.activate_item(index, true, true, window, cx);
+ }
+ });
+ };
+
+ item.act_as::<Editor>(cx).unwrap().update(cx, |editor, cx| {
+ let map = editor.snapshot(window, cx);
+ let mut ranges: Vec<Range<Anchor>> = Vec::new();
+ for mut anchor in anchors {
+ if line {
+ let mut point = anchor.to_display_point(&map.display_snapshot);
+ point = motion::first_non_whitespace(&map.display_snapshot, false, point);
+ anchor = map
+ .display_snapshot
+ .buffer_snapshot
+ .anchor_before(point.to_point(&map.display_snapshot));
+ }
+
+ if ranges.last() != Some(&(anchor..anchor)) {
+ ranges.push(anchor..anchor);
+ }
+ }
+
+ editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
+ s.select_anchor_ranges(ranges)
+ });
+ })
+ });
+ return;
+ }
+
+ fn open_path_mark(
+ &mut self,
+ line: bool,
+ path: Arc<Path>,
+ points: Vec<Point>,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ let Some(workspace) = self.workspace(window) else {
+ return;
+ };
+ let task = workspace.update(cx, |workspace, cx| {
+ workspace.open_abs_path(
+ path.to_path_buf(),
+ OpenOptions {
+ visible: Some(workspace::OpenVisible::All),
+ focus: Some(true),
+ ..Default::default()
+ },
+ window,
+ cx,
+ )
+ });
+ cx.spawn_in(window, |this, mut cx| async move {
+ let editor = task.await?;
+ this.update_in(&mut cx, |_, window, cx| {
+ if let Some(editor) = editor.act_as::<Editor>(cx) {
+ editor.update(cx, |editor, cx| {
+ let map = editor.snapshot(window, cx);
+ let points: Vec<_> = points
+ .into_iter()
+ .map(|p| {
+ if line {
+ let point = p.to_display_point(&map.display_snapshot);
+ motion::first_non_whitespace(
+ &map.display_snapshot,
+ false,
+ point,
+ )
+ .to_point(&map.display_snapshot)
+ } else {
+ p
+ }
+ })
+ .collect();
+ editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
+ s.select_ranges(points.into_iter().map(|p| p..p))
+ })
+ })
+ }
+ })
+ })
+ .detach_and_log_err(cx);
+ }
+
pub fn jump(
&mut self,
text: Arc<str>,
@@ -84,25 +187,22 @@ impl Vim {
cx: &mut Context<Self>,
) {
self.pop_operator(window, cx);
-
- let anchors = match &*text {
- "{" | "}" => self.update_editor(window, cx, |_, editor, _, cx| {
- let (map, selections) = editor.selections.all_display(cx);
- selections
- .into_iter()
- .map(|selection| {
- let point = if &*text == "{" {
- movement::start_of_paragraph(&map, selection.head(), 1)
- } else {
- movement::end_of_paragraph(&map, selection.head(), 1)
- };
- map.buffer_snapshot
- .anchor_before(point.to_offset(&map, Bias::Left))
- })
- .collect::<Vec<Anchor>>()
- }),
- "." => self.change_list.last().cloned(),
- _ => self.marks.get(&*text).cloned(),
+ let mark = self
+ .update_editor(window, cx, |vim, editor, window, cx| {
+ vim.get_mark(&text, editor, window, cx)
+ })
+ .flatten();
+ let anchors = match mark {
+ None => None,
+ Some(Mark::Local(anchors)) => Some(anchors),
+ Some(Mark::Buffer(entity_id, anchors)) => {
+ self.open_buffer_mark(line, entity_id, anchors, window, cx);
+ return;
+ }
+ Some(Mark::Path(path, points)) => {
+ self.open_path_mark(line, path, points, window, cx);
+ return;
+ }
};
let Some(mut anchors) = anchors else { return };
@@ -144,7 +244,7 @@ impl Vim {
}
}
- if !should_jump {
+ if !should_jump && !ranges.is_empty() {
editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
s.select_anchor_ranges(ranges)
});
@@ -158,6 +258,62 @@ impl Vim {
}
}
}
+
+ pub fn set_mark(
+ &mut self,
+ name: String,
+ anchors: Vec<Anchor>,
+ buffer_entity: &Entity<MultiBuffer>,
+ window: &mut Window,
+ cx: &mut App,
+ ) {
+ let Some(workspace) = self.workspace(window) else {
+ return;
+ };
+ let entity_id = workspace.entity_id();
+ Vim::update_globals(cx, |vim_globals, cx| {
+ let Some(marks_state) = vim_globals.marks.get(&entity_id) else {
+ return;
+ };
+ marks_state.update(cx, |ms, cx| {
+ ms.set_mark(name.clone(), buffer_entity, anchors, cx);
+ });
+ });
+ }
+
+ pub fn get_mark(
+ &self,
+ name: &str,
+ editor: &mut Editor,
+ window: &mut Window,
+ cx: &mut App,
+ ) -> Option<Mark> {
+ if matches!(name, "{" | "}" | "(" | ")") {
+ let (map, selections) = editor.selections.all_display(cx);
+ let anchors = selections
+ .into_iter()
+ .map(|selection| {
+ let point = match name {
+ "{" => movement::start_of_paragraph(&map, selection.head(), 1),
+ "}" => movement::end_of_paragraph(&map, selection.head(), 1),
+ "(" => motion::sentence_backwards(&map, selection.head(), 1),
+ ")" => motion::sentence_forwards(&map, selection.head(), 1),
+ _ => unreachable!(),
+ };
+ map.buffer_snapshot
+ .anchor_before(point.to_offset(&map, Bias::Left))
+ })
+ .collect::<Vec<Anchor>>();
+ return Some(Mark::Local(anchors));
+ }
+ VimGlobals::update_global(cx, |globals, cx| {
+ let workspace_id = self.workspace(window)?.entity_id();
+ globals
+ .marks
+ .get_mut(&workspace_id)?
+ .update(cx, |ms, cx| ms.get_mark(name, editor.buffer(), cx))
+ })
+ }
}
pub fn jump_motion(
@@ -50,7 +50,7 @@ impl Vim {
.filter(|sel| sel.len() > 1 && vim.mode != Mode::VisualLine);
if !action.preserve_clipboard && vim.mode.is_visual() {
- vim.copy_selections_content(editor, vim.mode == Mode::VisualLine, cx);
+ vim.copy_selections_content(editor, vim.mode == Mode::VisualLine, window, cx);
}
let (display_map, current_selections) = editor.selections.all_adjusted_display(cx);
@@ -75,7 +75,7 @@ impl Vim {
}
})
});
- vim.copy_selections_content(editor, line_mode, cx);
+ vim.copy_selections_content(editor, line_mode, window, cx);
let selections = editor.selections.all::<Point>(cx).into_iter();
let edits = selections.map(|selection| (selection.start..selection.end, ""));
editor.edit(edits, cx);
@@ -36,7 +36,7 @@ impl Vim {
motion.expand_selection(map, selection, times, true, &text_layout_details);
});
});
- vim.yank_selections_content(editor, motion.linewise(), cx);
+ vim.yank_selections_content(editor, motion.linewise(), window, cx);
editor.change_selections(None, window, cx, |s| {
s.move_with(|_, selection| {
let (head, goal) = original_positions.remove(&selection.id).unwrap();
@@ -66,7 +66,7 @@ impl Vim {
start_positions.insert(selection.id, start_position);
});
});
- vim.yank_selections_content(editor, false, cx);
+ vim.yank_selections_content(editor, false, window, cx);
editor.change_selections(None, window, cx, |s| {
s.move_with(|_, selection| {
let (head, goal) = start_positions.remove(&selection.id).unwrap();
@@ -82,6 +82,7 @@ impl Vim {
&mut self,
editor: &mut Editor,
linewise: bool,
+ window: &mut Window,
cx: &mut Context<Editor>,
) {
self.copy_ranges(
@@ -94,6 +95,7 @@ impl Vim {
.iter()
.map(|s| s.range())
.collect(),
+ window,
cx,
)
}
@@ -102,6 +104,7 @@ impl Vim {
&mut self,
editor: &mut Editor,
linewise: bool,
+ window: &mut Window,
cx: &mut Context<Editor>,
) {
self.copy_ranges(
@@ -114,6 +117,7 @@ impl Vim {
.iter()
.map(|s| s.range())
.collect(),
+ window,
cx,
)
}
@@ -124,28 +128,35 @@ impl Vim {
linewise: bool,
is_yank: bool,
selections: Vec<Range<Point>>,
+ window: &mut Window,
cx: &mut Context<Editor>,
) {
let buffer = editor.buffer().read(cx).snapshot(cx);
- let mut text = String::new();
- let mut clipboard_selections = Vec::with_capacity(selections.len());
- let mut ranges_to_highlight = Vec::new();
-
- self.marks.insert(
+ self.set_mark(
"[".to_string(),
selections
.iter()
.map(|s| buffer.anchor_before(s.start))
.collect(),
+ editor.buffer(),
+ window,
+ cx,
);
- self.marks.insert(
+ self.set_mark(
"]".to_string(),
selections
.iter()
.map(|s| buffer.anchor_after(s.end))
.collect(),
+ editor.buffer(),
+ window,
+ cx,
);
+ let mut text = String::new();
+ let mut clipboard_selections = Vec::with_capacity(selections.len());
+ let mut ranges_to_highlight = Vec::new();
+
{
let mut is_first = true;
for selection in selections.iter() {
@@ -3,27 +3,34 @@ use crate::normal::repeat::Replayer;
use crate::surrounds::SurroundsType;
use crate::{motion::Motion, object::Object};
use crate::{ToggleRegistersView, UseSystemClipboard, Vim, VimSettings};
+use anyhow::Result;
use collections::HashMap;
use command_palette_hooks::{CommandPaletteFilter, CommandPaletteInterceptor};
+use db::define_connection;
+use db::sqlez_macros::sql;
use editor::display_map::{is_invisible, replacement};
-use editor::{Anchor, ClipboardSelection, Editor};
+use editor::{Anchor, ClipboardSelection, Editor, MultiBuffer};
use gpui::{
- Action, App, BorrowAppContext, ClipboardEntry, ClipboardItem, Entity, Global, HighlightStyle,
- StyledText, Task, TextStyle, WeakEntity,
+ Action, App, AppContext, BorrowAppContext, ClipboardEntry, ClipboardItem, Entity, EntityId,
+ Global, HighlightStyle, StyledText, Subscription, Task, TextStyle, WeakEntity,
};
-use language::Point;
+use language::{Buffer, BufferEvent, BufferId, Point};
use picker::{Picker, PickerDelegate};
+use project::{Project, ProjectItem, ProjectPath};
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use std::borrow::BorrowMut;
+use std::path::Path;
use std::{fmt::Display, ops::Range, sync::Arc};
+use text::Bias;
use theme::ThemeSettings;
use ui::{
h_flex, rems, ActiveTheme, Context, Div, FluentBuilder, KeyBinding, ParentElement,
SharedString, Styled, StyledTypography, Window,
};
+use util::ResultExt;
use workspace::searchable::Direction;
-use workspace::Workspace;
+use workspace::{Workspace, WorkspaceDb, WorkspaceId};
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub enum Mode {
@@ -179,7 +186,7 @@ impl From<String> for Register {
}
}
-#[derive(Default, Clone)]
+#[derive(Default)]
pub struct VimGlobals {
pub last_find: Option<Motion>,
@@ -208,7 +215,399 @@ pub struct VimGlobals {
pub recordings: HashMap<char, Vec<ReplayableAction>>,
pub focused_vim: Option<WeakEntity<Vim>>,
+
+ pub marks: HashMap<EntityId, Entity<MarksState>>,
+}
+
+pub struct MarksState {
+ workspace: WeakEntity<Workspace>,
+
+ multibuffer_marks: HashMap<EntityId, HashMap<String, Vec<Anchor>>>,
+ buffer_marks: HashMap<BufferId, HashMap<String, Vec<text::Anchor>>>,
+ watched_buffers: HashMap<BufferId, (MarkLocation, Subscription, Subscription)>,
+
+ serialized_marks: HashMap<Arc<Path>, HashMap<String, Vec<Point>>>,
+ global_marks: HashMap<String, MarkLocation>,
+
+ _subscription: Subscription,
}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum MarkLocation {
+ Buffer(EntityId),
+ Path(Arc<Path>),
+}
+
+pub enum Mark {
+ Local(Vec<Anchor>),
+ Buffer(EntityId, Vec<Anchor>),
+ Path(Arc<Path>, Vec<Point>),
+}
+
+impl MarksState {
+ pub fn new(workspace: &Workspace, cx: &mut App) -> Entity<MarksState> {
+ cx.new(|cx| {
+ let buffer_store = workspace.project().read(cx).buffer_store().clone();
+ let subscription =
+ cx.subscribe(
+ &buffer_store,
+ move |this: &mut Self, _, event, cx| match event {
+ project::buffer_store::BufferStoreEvent::BufferAdded(buffer) => {
+ this.on_buffer_loaded(buffer, cx);
+ }
+ _ => {}
+ },
+ );
+
+ let mut this = Self {
+ workspace: workspace.weak_handle(),
+ multibuffer_marks: HashMap::default(),
+ buffer_marks: HashMap::default(),
+ watched_buffers: HashMap::default(),
+ serialized_marks: HashMap::default(),
+ global_marks: HashMap::default(),
+ _subscription: subscription,
+ };
+
+ this.load(cx);
+ this
+ })
+ }
+
+ fn workspace_id(&self, cx: &App) -> Option<WorkspaceId> {
+ self.workspace
+ .read_with(cx, |workspace, _| workspace.database_id())
+ .ok()
+ .flatten()
+ }
+
+ fn project(&self, cx: &App) -> Option<Entity<Project>> {
+ self.workspace
+ .read_with(cx, |workspace, _| workspace.project().clone())
+ .ok()
+ }
+
+ fn load(&mut self, cx: &mut Context<Self>) {
+ cx.spawn(|this, mut cx| async move {
+ let Some(workspace_id) = this.update(&mut cx, |this, cx| this.workspace_id(cx))? else {
+ return Ok(());
+ };
+ let (marks, paths) = cx
+ .background_spawn(async move {
+ let marks = DB.get_marks(workspace_id)?;
+ let paths = DB.get_global_marks_paths(workspace_id)?;
+ anyhow::Ok((marks, paths))
+ })
+ .await?;
+ this.update(&mut cx, |this, cx| this.loaded(marks, paths, cx))
+ })
+ .detach_and_log_err(cx);
+ }
+
+ fn loaded(
+ &mut self,
+ marks: Vec<SerializedMark>,
+ global_mark_paths: Vec<(String, Arc<Path>)>,
+ cx: &mut Context<Self>,
+ ) {
+ let Some(project) = self.project(cx) else {
+ return;
+ };
+
+ for mark in marks {
+ self.serialized_marks
+ .entry(mark.path)
+ .or_default()
+ .insert(mark.name, mark.points);
+ }
+
+ for (name, path) in global_mark_paths {
+ self.global_marks
+ .insert(name, MarkLocation::Path(path.clone()));
+
+ let project_path = project
+ .read(cx)
+ .worktrees(cx)
+ .filter_map(|worktree| {
+ let relative = path.strip_prefix(worktree.read(cx).abs_path()).ok()?;
+ Some(ProjectPath {
+ worktree_id: worktree.read(cx).id(),
+ path: relative.into(),
+ })
+ })
+ .next();
+ if let Some(buffer) = project_path
+ .and_then(|project_path| project.read(cx).get_open_buffer(&project_path, cx))
+ {
+ self.on_buffer_loaded(&buffer, cx)
+ }
+ }
+ }
+
+ pub fn on_buffer_loaded(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) {
+ let Some(project) = self.project(cx) else {
+ return;
+ };
+ let Some(project_path) = buffer_handle.read(cx).project_path(cx) else {
+ return;
+ };
+ let Some(abs_path) = project.read(cx).absolute_path(&project_path, cx) else {
+ return;
+ };
+ let abs_path: Arc<Path> = abs_path.into();
+
+ let Some(serialized_marks) = self.serialized_marks.get(&abs_path) else {
+ return;
+ };
+
+ let mut loaded_marks = HashMap::default();
+ let buffer = buffer_handle.read(cx);
+ for (name, points) in serialized_marks.iter() {
+ loaded_marks.insert(
+ name.clone(),
+ points
+ .iter()
+ .map(|point| buffer.anchor_before(buffer.clip_point(*point, Bias::Left)))
+ .collect(),
+ );
+ }
+ self.buffer_marks.insert(buffer.remote_id(), loaded_marks);
+ self.watch_buffer(MarkLocation::Path(abs_path), buffer_handle, cx)
+ }
+
+ fn serialize_buffer_marks(
+ &mut self,
+ path: Arc<Path>,
+ buffer: &Entity<Buffer>,
+ cx: &mut Context<Self>,
+ ) {
+ let new_points: HashMap<String, Vec<Point>> =
+ if let Some(anchors) = self.buffer_marks.get(&buffer.read(cx).remote_id()) {
+ anchors
+ .iter()
+ .map(|(name, anchors)| {
+ (
+ name.clone(),
+ buffer
+ .read(cx)
+ .summaries_for_anchors::<Point, _>(anchors)
+ .collect(),
+ )
+ })
+ .collect()
+ } else {
+ HashMap::default()
+ };
+ let old_points = self.serialized_marks.get(&path.clone());
+ if old_points == Some(&new_points) {
+ return;
+ }
+ let mut to_write = HashMap::default();
+
+ for (key, value) in &new_points {
+ if self.is_global_mark(key) {
+ if self.global_marks.get(key) != Some(&MarkLocation::Path(path.clone())) {
+ if let Some(workspace_id) = self.workspace_id(cx) {
+ let path = path.clone();
+ let key = key.clone();
+ cx.background_spawn(async move {
+ DB.set_global_mark_path(workspace_id, key, path).await
+ })
+ .detach_and_log_err(cx);
+ }
+
+ self.global_marks
+ .insert(key.clone(), MarkLocation::Path(path.clone()));
+ }
+ }
+ if old_points.and_then(|o| o.get(key)) != Some(value) {
+ to_write.insert(key.clone(), value.clone());
+ }
+ }
+
+ self.serialized_marks.insert(path.clone(), new_points);
+
+ if let Some(workspace_id) = self.workspace_id(cx) {
+ cx.background_spawn(async move {
+ DB.set_marks(workspace_id, path.clone(), to_write).await?;
+ anyhow::Ok(())
+ })
+ .detach_and_log_err(cx);
+ }
+ }
+
+ fn is_global_mark(&self, key: &str) -> bool {
+ key.chars()
+ .next()
+ .is_some_and(|c| c.is_uppercase() || c.is_digit(10))
+ }
+
+ fn rename_buffer(
+ &mut self,
+ old_path: MarkLocation,
+ new_path: Arc<Path>,
+ buffer: &Entity<Buffer>,
+ cx: &mut Context<Self>,
+ ) {
+ if let MarkLocation::Buffer(entity_id) = old_path {
+ if let Some(old_marks) = self.multibuffer_marks.remove(&entity_id) {
+ let buffer_marks = old_marks
+ .into_iter()
+ .map(|(k, v)| (k, v.into_iter().map(|anchor| anchor.text_anchor).collect()))
+ .collect();
+ self.buffer_marks
+ .insert(buffer.read(cx).remote_id(), buffer_marks);
+ }
+ }
+ self.watch_buffer(MarkLocation::Path(new_path.clone()), buffer, cx);
+ self.serialize_buffer_marks(new_path, buffer, cx);
+ }
+
+ fn path_for_buffer(&self, buffer: &Entity<Buffer>, cx: &App) -> Option<Arc<Path>> {
+ let project_path = buffer.read(cx).project_path(cx)?;
+ let project = self.project(cx)?;
+ let abs_path = project.read(cx).absolute_path(&project_path, cx)?;
+ Some(abs_path.into())
+ }
+
+ fn points_at(
+ &self,
+ location: &MarkLocation,
+ multi_buffer: &Entity<MultiBuffer>,
+ cx: &App,
+ ) -> bool {
+ match location {
+ MarkLocation::Buffer(entity_id) => entity_id == &multi_buffer.entity_id(),
+ MarkLocation::Path(path) => {
+ let Some(singleton) = multi_buffer.read(cx).as_singleton() else {
+ return false;
+ };
+ self.path_for_buffer(&singleton, cx).as_ref() == Some(path)
+ }
+ }
+ }
+
+ pub fn watch_buffer(
+ &mut self,
+ mark_location: MarkLocation,
+ buffer_handle: &Entity<Buffer>,
+ cx: &mut Context<Self>,
+ ) {
+ let on_change = cx.subscribe(buffer_handle, move |this, buffer, event, cx| match event {
+ BufferEvent::Edited => {
+ if let Some(path) = this.path_for_buffer(&buffer, cx) {
+ this.serialize_buffer_marks(path, &buffer, cx);
+ }
+ }
+ BufferEvent::FileHandleChanged => {
+ let buffer_id = buffer.read(cx).remote_id();
+ if let Some(old_path) = this
+ .watched_buffers
+ .get(&buffer_id.clone())
+ .map(|(path, _, _)| path.clone())
+ {
+ if let Some(new_path) = this.path_for_buffer(&buffer, cx) {
+ this.rename_buffer(old_path, new_path, &buffer, cx)
+ }
+ }
+ }
+ _ => {}
+ });
+
+ let on_release = cx.observe_release(buffer_handle, |this, buffer, _| {
+ this.watched_buffers.remove(&buffer.remote_id());
+ this.buffer_marks.remove(&buffer.remote_id());
+ });
+
+ self.watched_buffers.insert(
+ buffer_handle.read(cx).remote_id(),
+ (mark_location, on_change, on_release),
+ );
+ }
+
+ pub fn set_mark(
+ &mut self,
+ name: String,
+ multibuffer: &Entity<MultiBuffer>,
+ anchors: Vec<Anchor>,
+ cx: &mut Context<Self>,
+ ) {
+ let buffer = multibuffer.read(cx).as_singleton();
+ let abs_path = buffer.as_ref().and_then(|b| self.path_for_buffer(&b, cx));
+
+ let Some(abs_path) = abs_path else {
+ self.multibuffer_marks
+ .entry(multibuffer.entity_id())
+ .or_default()
+ .insert(name.clone(), anchors);
+ if self.is_global_mark(&name) {
+ self.global_marks
+ .insert(name.clone(), MarkLocation::Buffer(multibuffer.entity_id()));
+ }
+ if let Some(buffer) = buffer {
+ let buffer_id = buffer.read(cx).remote_id();
+ if !self.watched_buffers.contains_key(&buffer_id) {
+ self.watch_buffer(MarkLocation::Buffer(multibuffer.entity_id()), &buffer, cx)
+ }
+ }
+ return;
+ };
+ let buffer = buffer.unwrap();
+
+ let buffer_id = buffer.read(cx).remote_id();
+ self.buffer_marks.entry(buffer_id).or_default().insert(
+ name.clone(),
+ anchors
+ .into_iter()
+ .map(|anchor| anchor.text_anchor)
+ .collect(),
+ );
+ if !self.watched_buffers.contains_key(&buffer_id) {
+ self.watch_buffer(MarkLocation::Path(abs_path.clone()), &buffer, cx)
+ }
+ self.serialize_buffer_marks(abs_path, &buffer, cx)
+ }
+
+ pub fn get_mark(
+ &self,
+ name: &str,
+ multi_buffer: &Entity<MultiBuffer>,
+ cx: &App,
+ ) -> Option<Mark> {
+ let target = self.global_marks.get(name);
+
+ if !self.is_global_mark(name) || target.is_some_and(|t| self.points_at(t, multi_buffer, cx))
+ {
+ if let Some(anchors) = self.multibuffer_marks.get(&multi_buffer.entity_id()) {
+ return Some(Mark::Local(anchors.get(name)?.clone()));
+ }
+
+ let singleton = multi_buffer.read(cx).as_singleton()?;
+ let excerpt_id = *multi_buffer.read(cx).excerpt_ids().first().unwrap();
+ let buffer_id = singleton.read(cx).remote_id();
+ if let Some(anchors) = self.buffer_marks.get(&buffer_id) {
+ let text_anchors = anchors.get(name)?;
+ let anchors = text_anchors
+ .into_iter()
+ .map(|anchor| Anchor::in_buffer(excerpt_id, buffer_id, *anchor))
+ .collect();
+ return Some(Mark::Local(anchors));
+ }
+ }
+
+ match target? {
+ MarkLocation::Buffer(entity_id) => {
+ let anchors = self.multibuffer_marks.get(&entity_id)?;
+ return Some(Mark::Buffer(*entity_id, anchors.get(name)?.clone()));
+ }
+ MarkLocation::Path(path) => {
+ let points = self.serialized_marks.get(path)?;
+ return Some(Mark::Path(path.clone(), points.get(name)?.clone()));
+ }
+ }
+ }
+}
+
impl Global for VimGlobals {}
impl VimGlobals {
@@ -228,8 +627,15 @@ impl VimGlobals {
})
.detach();
+ let mut was_enabled = None;
+
cx.observe_global::<SettingsStore>(move |cx| {
- if Vim::enabled(cx) {
+ let is_enabled = Vim::enabled(cx);
+ if was_enabled == Some(is_enabled) {
+ return;
+ }
+ was_enabled = Some(is_enabled);
+ if is_enabled {
KeyBinding::set_vim_mode(cx, true);
CommandPaletteFilter::update_global(cx, |filter, _| {
filter.show_namespace(Vim::NAMESPACE);
@@ -237,6 +643,17 @@ impl VimGlobals {
CommandPaletteInterceptor::update_global(cx, |interceptor, _| {
interceptor.set(Box::new(command_interceptor));
});
+ for window in cx.windows() {
+ if let Some(workspace) = window.downcast::<Workspace>() {
+ workspace
+ .update(cx, |workspace, _, cx| {
+ Vim::update_globals(cx, |globals, cx| {
+ globals.register_workspace(workspace, cx)
+ });
+ })
+ .ok();
+ }
+ }
} else {
KeyBinding::set_vim_mode(cx, false);
*Vim::globals(cx) = VimGlobals::default();
@@ -249,6 +666,21 @@ impl VimGlobals {
}
})
.detach();
+ cx.observe_new(|workspace: &mut Workspace, _, cx| {
+ Vim::update_globals(cx, |globals, cx| globals.register_workspace(workspace, cx));
+ })
+ .detach()
+ }
+
+ fn register_workspace(&mut self, workspace: &Workspace, cx: &mut Context<Workspace>) {
+ let entity_id = cx.entity_id();
+ self.marks.insert(entity_id, MarksState::new(workspace, cx));
+ cx.observe_release(&cx.entity(), move |_, _, cx| {
+ Vim::update_globals(cx, |globals, _| {
+ globals.marks.remove(&entity_id);
+ })
+ })
+ .detach();
}
pub(crate) fn write_registers(
@@ -799,3 +1231,111 @@ impl RegistersView {
.modal(true)
}
}
+
+define_connection! (
+ pub static ref DB: VimDb<WorkspaceDb> = &[
+ sql! (
+ CREATE TABLE vim_marks (
+ workspace_id INTEGER,
+ mark_name TEXT,
+ path BLOB,
+ value TEXT
+ );
+ CREATE UNIQUE INDEX idx_vim_marks ON vim_marks (workspace_id, mark_name, path);
+ ),
+ sql! (
+ CREATE TABLE vim_global_marks_paths(
+ workspace_id INTEGER,
+ mark_name TEXT,
+ path BLOB
+ );
+ CREATE UNIQUE INDEX idx_vim_global_marks_paths
+ ON vim_global_marks_paths(workspace_id, mark_name);
+ ),
+ ];
+);
+
+struct SerializedMark {
+ path: Arc<Path>,
+ name: String,
+ points: Vec<Point>,
+}
+
+impl VimDb {
+ pub(crate) async fn set_marks(
+ &self,
+ workspace_id: WorkspaceId,
+ path: Arc<Path>,
+ marks: HashMap<String, Vec<Point>>,
+ ) -> Result<()> {
+ let result = self
+ .write(move |conn| {
+ let mut query = conn.exec_bound(sql!(
+ INSERT OR REPLACE INTO vim_marks
+ (workspace_id, mark_name, path, value)
+ VALUES
+ (?, ?, ?, ?)
+ ))?;
+ for (mark_name, value) in marks {
+ let pairs: Vec<(u32, u32)> = value
+ .into_iter()
+ .map(|point| (point.row, point.column))
+ .collect();
+ let serialized = serde_json::to_string(&pairs)?;
+ query((workspace_id, mark_name, path.clone(), serialized))?;
+ }
+ Ok(())
+ })
+ .await;
+ result
+ }
+
+ fn get_marks(&self, workspace_id: WorkspaceId) -> Result<Vec<SerializedMark>> {
+ let result: Vec<(Arc<Path>, String, String)> = self.select_bound(sql!(
+ SELECT path, mark_name, value FROM vim_marks
+ WHERE workspace_id = ?
+ ))?(workspace_id)?;
+
+ Ok(result
+ .into_iter()
+ .filter_map(|(path, name, value)| {
+ let pairs: Vec<(u32, u32)> = serde_json::from_str(&value).log_err()?;
+ Some(SerializedMark {
+ path,
+ name,
+ points: pairs
+ .into_iter()
+ .map(|(row, column)| Point { row, column })
+ .collect(),
+ })
+ })
+ .collect())
+ }
+
+ pub(crate) async fn set_global_mark_path(
+ &self,
+ workspace_id: WorkspaceId,
+ mark_name: String,
+ path: Arc<Path>,
+ ) -> Result<()> {
+ self.write(move |conn| {
+ conn.exec_bound(sql!(
+ INSERT OR REPLACE INTO vim_global_marks_paths
+ (workspace_id, mark_name, path)
+ VALUES
+ (?, ?, ?)
+ ))?((workspace_id, mark_name, path))
+ })
+ .await
+ }
+
+ pub fn get_global_marks_paths(
+ &self,
+ workspace_id: WorkspaceId,
+ ) -> Result<Vec<(String, Arc<Path>)>> {
+ self.select_bound(sql!(
+ SELECT mark_name, path FROM vim_global_marks_paths
+ WHERE workspace_id = ?
+ ))?(workspace_id)
+ }
+}
@@ -26,7 +26,7 @@ use editor::{
Anchor, Bias, Editor, EditorEvent, EditorMode, EditorSettings, ToPoint,
};
use gpui::{
- actions, impl_actions, Action, App, AppContext as _, Axis, Context, Entity, EventEmitter,
+ actions, impl_actions, Action, App, AppContext, Axis, Context, Entity, EventEmitter,
KeyContext, KeystrokeEvent, Render, Subscription, Task, WeakEntity, Window,
};
use insert::{NormalBefore, TemporaryNormal};
@@ -314,7 +314,6 @@ pub(crate) struct Vim {
operator_stack: Vec<Operator>,
pub(crate) replacements: Vec<(Range<editor::Anchor>, String)>,
- pub(crate) marks: HashMap<String, Vec<Anchor>>,
pub(crate) stored_visual_mode: Option<(Mode, Vec<bool>)>,
pub(crate) change_list: Vec<Vec<Anchor>>,
pub(crate) change_list_position: Option<usize>,
@@ -362,7 +361,6 @@ impl Vim {
operator_stack: Vec::new(),
replacements: Vec::new(),
- marks: HashMap::default(),
stored_visual_mode: None,
change_list: Vec::new(),
change_list_position: None,
@@ -1573,7 +1571,7 @@ impl Vim {
}
_ => self.clear_operator(window, cx),
},
- Some(Operator::Mark) => self.create_mark(text, false, window, cx),
+ Some(Operator::Mark) => self.create_mark(text, window, cx),
Some(Operator::RecordRegister) => {
self.record_register(text.chars().next().unwrap(), window, cx)
}
@@ -17,7 +17,7 @@ use workspace::searchable::Direction;
use crate::{
motion::{first_non_whitespace, next_line_end, start_of_line, Motion},
object::Object,
- state::{Mode, Operator},
+ state::{Mark, Mode, Operator},
Vim,
};
@@ -107,14 +107,20 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
let Some((stored_mode, reversed)) = vim.stored_visual_mode.take() else {
return;
};
- let Some((start, end)) = vim.marks.get("<").zip(vim.marks.get(">")) else {
+ let marks = vim
+ .update_editor(window, cx, |vim, editor, window, cx| {
+ vim.get_mark("<", editor, window, cx)
+ .zip(vim.get_mark(">", editor, window, cx))
+ })
+ .flatten();
+ let Some((Mark::Local(start), Mark::Local(end))) = marks else {
return;
};
let ranges = start
.iter()
.zip(end)
.zip(reversed)
- .map(|((start, end), reversed)| (*start, *end, reversed))
+ .map(|((start, end), reversed)| (*start, end, reversed))
.collect::<Vec<_>>();
if vim.mode.is_visual() {
@@ -499,7 +505,7 @@ impl Vim {
selection.goal = SelectionGoal::None;
});
});
- vim.copy_selections_content(editor, line_mode, cx);
+ vim.copy_selections_content(editor, line_mode, window, cx);
editor.insert("", window, cx);
// Fixup cursor position after the deletion
@@ -528,7 +534,7 @@ impl Vim {
self.update_editor(window, cx, |vim, editor, window, cx| {
let line_mode = line_mode || editor.selections.line_mode;
editor.selections.line_mode = line_mode;
- vim.yank_selections_content(editor, line_mode, cx);
+ vim.yank_selections_content(editor, line_mode, window, cx);
editor.change_selections(None, window, cx, |s| {
s.move_with(|map, selection| {
if line_mode {