diff --git a/Cargo.lock b/Cargo.lock index 55ba70e06d..0b5fcea1d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", @@ -13475,7 +13436,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -13580,7 +13541,7 @@ dependencies = [ "collections", "ctor", "editor", - "env_logger 0.11.7", + "env_logger 0.11.6", "gpui", "language", "menu", @@ -13811,7 +13772,7 @@ dependencies = [ "clock", "collections", "ctor", - "env_logger 0.11.7", + "env_logger 0.11.6", "gpui", "http_client", "log", @@ -13929,7 +13890,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -13940,7 +13901,7 @@ checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -14176,7 +14137,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -14423,7 +14384,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -14486,7 +14447,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -15184,6 +15145,7 @@ dependencies = [ "collections", "command_palette", "command_palette_hooks", + "db", "editor", "futures 0.3.31", "git_ui", @@ -15209,6 +15171,7 @@ dependencies = [ "serde_json", "settings", "task", + "text", "theme", "tokio", "ui", @@ -15377,7 +15340,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -15412,7 +15375,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -15611,7 +15574,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "wasmtime-component-util", "wasmtime-wit-bindgen", "wit-parser 0.221.3", @@ -15725,7 +15688,7 @@ checksum = "86ff86db216dc0240462de40c8290887a613dddf9685508eb39479037ba97b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -16049,7 +16012,7 @@ dependencies = [ "proc-macro2", "quote", "shellexpand 2.1.2", - "syn 2.0.100", + "syn 2.0.90", "witx", ] @@ -16061,7 +16024,7 @@ checksum = "08c5c473d4198e6c2d377f3809f713ff0c110cab88a0805ae099a82119ee250c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "wiggle-generate", ] @@ -16241,7 +16204,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -16252,7 +16215,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -16263,7 +16226,7 @@ checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -16274,7 +16237,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -16285,7 +16248,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -16296,7 +16259,7 @@ checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -16718,7 +16681,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -16824,7 +16787,7 @@ dependencies = [ "component", "db", "derive_more", - "env_logger 0.11.7", + "env_logger 0.11.6", "fs", "futures 0.3.31", "gpui", @@ -16862,7 +16825,7 @@ dependencies = [ "anyhow", "clock", "collections", - "env_logger 0.11.7", + "env_logger 0.11.6", "fs", "futures 0.3.31", "fuzzy", @@ -17099,7 +17062,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "synstructure", ] @@ -17148,7 +17111,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "zbus_names", "zvariant", "zvariant_utils", @@ -17200,7 +17163,7 @@ dependencies = [ "db", "diagnostics", "editor", - "env_logger 0.11.7", + "env_logger 0.11.6", "extension", "extension_host", "extensions_ui", @@ -17425,7 +17388,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -17436,7 +17399,7 @@ checksum = "76331675d372f91bf8d17e13afbd5fe639200b73d01f0fc748bb059f9cca2db7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -17456,7 +17419,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "synstructure", ] @@ -17477,7 +17440,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -17523,7 +17486,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", ] [[package]] @@ -17541,7 +17504,7 @@ dependencies = [ "ctor", "db", "editor", - "env_logger 0.11.7", + "env_logger 0.11.6", "feature_flags", "fs", "futures 0.3.31", @@ -17678,7 +17641,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.90", "zvariant_utils", ] @@ -17692,6 +17655,6 @@ dependencies = [ "quote", "serde", "static_assertions", - "syn 2.0.100", + "syn 2.0.90", "winnow 0.7.1", ] diff --git a/crates/sqlez/src/bindable.rs b/crates/sqlez/src/bindable.rs index cddc2c486d..3e1acc0797 100644 --- a/crates/sqlez/src/bindable.rs +++ b/crates/sqlez/src/bindable.rs @@ -326,6 +326,13 @@ impl Bind for Arc { self.as_ref().bind(statement, start_index) } } +impl Column for Arc { + 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 { diff --git a/crates/vim/Cargo.toml b/crates/vim/Cargo.toml index 9732e51f47..72af39f2b9 100644 --- a/crates/vim/Cargo.toml +++ b/crates/vim/Cargo.toml @@ -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 diff --git a/crates/vim/src/change_list.rs b/crates/vim/src/change_list.rs index 206eb61f80..25bcfc20be 100644 --- a/crates/vim/src/change_list.rs +++ b/crates/vim/src/change_list.rs @@ -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) { - 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 = 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) } } diff --git a/crates/vim/src/command.rs b/crates/vim/src/command.rs index 88adcb1855..d9253fe78d 100644 --- a/crates/vim/src/command.rs +++ b/crates/vim/src/command.rs @@ -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) { 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) diff --git a/crates/vim/src/helix.rs b/crates/vim/src/helix.rs index 3ff203fcc7..334c48cd83 100644 --- a/crates/vim/src/helix.rs +++ b/crates/vim/src/helix.rs @@ -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); }); } diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index 9f4f9e9944..22c2d52475 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -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| { diff --git a/crates/vim/src/motion.rs b/crates/vim/src/motion.rs index a0ab12b2bb..486474c6e7 100644 --- a/crates/vim/src/motion.rs +++ b/crates/vim/src/motion.rs @@ -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(); diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 42f4a8403b..693785005b 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -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)) + }); }); } diff --git a/crates/vim/src/normal/change.rs b/crates/vim/src/normal/change.rs index 1f7806055a..fa648c173e 100644 --- a/crates/vim/src/normal/change.rs +++ b/crates/vim/src/normal/change.rs @@ -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); } diff --git a/crates/vim/src/normal/delete.rs b/crates/vim/src/normal/delete.rs index 914fce539c..07d63d47cd 100644 --- a/crates/vim/src/normal/delete.rs +++ b/crates/vim/src/normal/delete.rs @@ -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 diff --git a/crates/vim/src/normal/mark.rs b/crates/vim/src/normal/mark.rs index 72194b728c..0dbbeab913 100644 --- a/crates/vim/src/normal/mark.rs +++ b/crates/vim/src/normal/mark.rs @@ -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, - tail: bool, - window: &mut Window, - cx: &mut Context, - ) { - let Some(anchors) = self.update_editor(window, cx, |_, editor, _, _| { - editor + pub fn create_mark(&mut self, text: Arc, window: &mut Window, cx: &mut Context) { + 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::>() - }) else { - return; - }; - self.marks.insert(text.to_string(), anchors); + .map(|s| s.head()) + .collect::>(); + 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, + window: &mut Window, + cx: &mut Context, + ) { + let Some(workspace) = self.workspace(window) else { + return; + }; + workspace.update(cx, |workspace, cx| { + let item = workspace.items(cx).find(|item| { + item.act_as::(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::(cx).unwrap().update(cx, |editor, cx| { + let map = editor.snapshot(window, cx); + let mut ranges: Vec> = 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, + points: Vec, + window: &mut Window, + cx: &mut Context, + ) { + 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::(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, @@ -84,25 +187,22 @@ impl Vim { cx: &mut Context, ) { 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::>() - }), - "." => 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, + buffer_entity: &Entity, + 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 { + 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::>(); + 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( diff --git a/crates/vim/src/normal/paste.rs b/crates/vim/src/normal/paste.rs index 7dd5c93de3..9bd35c7af5 100644 --- a/crates/vim/src/normal/paste.rs +++ b/crates/vim/src/normal/paste.rs @@ -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); diff --git a/crates/vim/src/normal/substitute.rs b/crates/vim/src/normal/substitute.rs index fad183a51c..b6ccab6415 100644 --- a/crates/vim/src/normal/substitute.rs +++ b/crates/vim/src/normal/substitute.rs @@ -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::(cx).into_iter(); let edits = selections.map(|selection| (selection.start..selection.end, "")); editor.edit(edits, cx); diff --git a/crates/vim/src/normal/yank.rs b/crates/vim/src/normal/yank.rs index e00fb8f8f4..0367f43dae 100644 --- a/crates/vim/src/normal/yank.rs +++ b/crates/vim/src/normal/yank.rs @@ -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, ) { 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, ) { 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>, + window: &mut Window, cx: &mut Context, ) { 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() { diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index f51e479c6e..7d372ee412 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -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 for Register { } } -#[derive(Default, Clone)] +#[derive(Default)] pub struct VimGlobals { pub last_find: Option, @@ -208,7 +215,399 @@ pub struct VimGlobals { pub recordings: HashMap>, pub focused_vim: Option>, + + pub marks: HashMap>, } + +pub struct MarksState { + workspace: WeakEntity, + + multibuffer_marks: HashMap>>, + buffer_marks: HashMap>>, + watched_buffers: HashMap, + + serialized_marks: HashMap, HashMap>>, + global_marks: HashMap, + + _subscription: Subscription, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum MarkLocation { + Buffer(EntityId), + Path(Arc), +} + +pub enum Mark { + Local(Vec), + Buffer(EntityId, Vec), + Path(Arc, Vec), +} + +impl MarksState { + pub fn new(workspace: &Workspace, cx: &mut App) -> Entity { + 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 { + self.workspace + .read_with(cx, |workspace, _| workspace.database_id()) + .ok() + .flatten() + } + + fn project(&self, cx: &App) -> Option> { + self.workspace + .read_with(cx, |workspace, _| workspace.project().clone()) + .ok() + } + + fn load(&mut self, cx: &mut Context) { + 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, + global_mark_paths: Vec<(String, Arc)>, + cx: &mut Context, + ) { + 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, cx: &mut Context) { + 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 = 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, + buffer: &Entity, + cx: &mut Context, + ) { + let new_points: HashMap> = + 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::(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, + buffer: &Entity, + cx: &mut Context, + ) { + 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, cx: &App) -> Option> { + 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, + 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, + cx: &mut Context, + ) { + 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, + anchors: Vec, + cx: &mut Context, + ) { + 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, + cx: &App, + ) -> Option { + 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::(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 + .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) { + 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 = &[ + 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, + name: String, + points: Vec, +} + +impl VimDb { + pub(crate) async fn set_marks( + &self, + workspace_id: WorkspaceId, + path: Arc, + marks: HashMap>, + ) -> 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> { + let result: Vec<(Arc, 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, + ) -> 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)>> { + self.select_bound(sql!( + SELECT mark_name, path FROM vim_global_marks_paths + WHERE workspace_id = ? + ))?(workspace_id) + } +} diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index be4acca290..79900e1a36 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -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, pub(crate) replacements: Vec<(Range, String)>, - pub(crate) marks: HashMap>, pub(crate) stored_visual_mode: Option<(Mode, Vec)>, pub(crate) change_list: Vec>, pub(crate) change_list_position: Option, @@ -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) } diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index a9e4dd9767..5385d8a76a 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -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) { 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::>(); 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 {