diff --git a/Cargo.lock b/Cargo.lock index 0448538c35..c5bbeac616 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.1.0" dependencies = [ "auto_update", "editor", - "futures", + "futures 0.3.24", "gpui", "language", "project", @@ -183,6 +183,19 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-compat" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b48b4ff0c2026db683dea961cd8ea874737f56cffca86fa84415eaddc51c00d" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite 0.2.9", + "tokio", +] + [[package]] name = "async-compression" version = "0.3.14" @@ -265,7 +278,7 @@ name = "async-pipe" version = "0.1.3" source = "git+https://github.com/zed-industries/async-pipe-rs?rev=82d00a04211cf4e1236029aa03e6b6ce2a74c553#82d00a04211cf4e1236029aa03e6b6ce2a74c553" dependencies = [ - "futures", + "futures 0.3.24", "log", ] @@ -338,9 +351,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" dependencies = [ "proc-macro2", "quote", @@ -443,7 +456,7 @@ dependencies = [ "axum-core", "base64", "bitflags", - "bytes", + "bytes 1.2.1", "futures-util", "headers", "http", @@ -475,7 +488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4d047478b986f14a13edad31a009e2e05cb241f9805d0d75e4cba4e129ad4d" dependencies = [ "async-trait", - "bytes", + "bytes 1.2.1", "futures-util", "http", "http-body", @@ -489,7 +502,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "277c75e6c814b061ae4947d02335d9659db9771b9950cca670002ae986372f44" dependencies = [ "axum", - "bytes", + "bytes 1.2.1", "futures-util", "http", "mime", @@ -661,6 +674,16 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +dependencies = [ + "byteorder", + "iovec", +] + [[package]] name = "bytes" version = "1.2.1" @@ -691,7 +714,7 @@ dependencies = [ "anyhow", "client", "collections", - "futures", + "futures 0.3.24", "gpui", "postage", "project", @@ -772,12 +795,12 @@ dependencies = [ "bindgen", "block", "byteorder", - "bytes", + "bytes 1.2.1", "cocoa", "core-foundation", "core-graphics", "foreign-types", - "futures", + "futures 0.3.24", "gpui", "hmac 0.12.1", "jwt", @@ -960,7 +983,7 @@ dependencies = [ "async-tungstenite", "collections", "db", - "futures", + "futures 0.3.24", "gpui", "image", "isahc", @@ -1045,7 +1068,7 @@ dependencies = [ "editor", "env_logger", "envy", - "futures", + "futures 0.3.24", "git", "gpui", "hyper", @@ -1092,7 +1115,7 @@ dependencies = [ "clock", "collections", "editor", - "futures", + "futures 0.3.24", "fuzzy", "gpui", "log", @@ -1689,7 +1712,7 @@ dependencies = [ "context_menu", "ctor", "env_logger", - "futures", + "futures 0.3.24", "fuzzy", "git", "gpui", @@ -2038,9 +2061,15 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" -version = "0.3.21" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "futures" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" dependencies = [ "futures-channel", "futures-core", @@ -2053,9 +2082,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", "futures-sink", @@ -2063,15 +2092,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" dependencies = [ "futures-core", "futures-task", @@ -2091,9 +2120,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-lite" @@ -2112,9 +2141,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" dependencies = [ "proc-macro2", "quote", @@ -2123,22 +2152,23 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ + "futures 0.1.31", "futures-channel", "futures-core", "futures-io", @@ -2149,6 +2179,7 @@ dependencies = [ "pin-project-lite 0.2.9", "pin-utils", "slab", + "tokio-io", ] [[package]] @@ -2229,7 +2260,7 @@ dependencies = [ "async-trait", "clock", "collections", - "futures", + "futures 0.3.24", "git2", "lazy_static", "log", @@ -2307,9 +2338,10 @@ dependencies = [ "etagere", "font-kit", "foreign-types", - "futures", + "futures 0.3.24", "gpui_macros", "image", + "itertools", "lazy_static", "log", "media", @@ -2355,7 +2387,7 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" dependencies = [ - "bytes", + "bytes 1.2.1", "fnv", "futures-core", "futures-sink", @@ -2364,7 +2396,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.3", + "tokio-util 0.7.4", "tracing", ] @@ -2403,7 +2435,7 @@ checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" dependencies = [ "base64", "bitflags", - "bytes", + "bytes 1.2.1", "headers-core", "http", "httpdate", @@ -2496,7 +2528,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ - "bytes", + "bytes 1.2.1", "fnv", "itoa", ] @@ -2507,7 +2539,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes", + "bytes 1.2.1", "http", "pin-project-lite 0.2.9", ] @@ -2542,7 +2574,7 @@ version = "0.14.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" dependencies = [ - "bytes", + "bytes 1.2.1", "futures-channel", "futures-core", "futures-util", @@ -2578,7 +2610,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes", + "bytes 1.2.1", "hyper", "native-tls", "tokio", @@ -2868,7 +2900,7 @@ dependencies = [ "collections", "ctor", "env_logger", - "futures", + "futures 0.3.24", "fuzzy", "git", "gpui", @@ -3029,7 +3061,7 @@ dependencies = [ "anyhow", "core-foundation", "core-graphics", - "futures", + "futures 0.3.24", "media", "parking_lot 0.11.2", "serde", @@ -3066,7 +3098,7 @@ dependencies = [ "collections", "ctor", "env_logger", - "futures", + "futures 0.3.24", "gpui", "log", "lsp-types", @@ -3159,7 +3191,7 @@ dependencies = [ "anyhow", "bindgen", "block", - "bytes", + "bytes 1.2.1", "core-foundation", "foreign-types", "metal", @@ -3519,6 +3551,21 @@ dependencies = [ "libc", ] +[[package]] +name = "nvim-rs" +version = "0.5.0" +source = "git+https://github.com/KillTheMule/nvim-rs?branch=master#d701c2790dcb2579f8f4d7003ba30e2100a7d25b" +dependencies = [ + "async-trait", + "futures 0.3.24", + "log", + "parity-tokio-ipc", + "rmp", + "rmpv", + "tokio", + "tokio-util 0.7.4", +] + [[package]] name = "objc" version = "0.2.7" @@ -3639,6 +3686,20 @@ dependencies = [ "workspace", ] +[[package]] +name = "parity-tokio-ipc" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" +dependencies = [ + "futures 0.3.24", + "libc", + "log", + "rand 0.7.3", + "tokio", + "winapi 0.3.9", +] + [[package]] name = "parking" version = "2.0.0" @@ -3943,7 +4004,7 @@ checksum = "a63d25391d04a097954b76aba742b6b5b74f213dfe3dbaeeb36e8ddc1c657f0b" dependencies = [ "atomic", "crossbeam-queue", - "futures", + "futures 0.3.24", "log", "pin-project", "pollster", @@ -4013,7 +4074,7 @@ dependencies = [ "collections", "db", "fsevent", - "futures", + "futures 0.3.24", "fuzzy", "git", "gpui", @@ -4051,7 +4112,7 @@ version = "0.1.0" dependencies = [ "context_menu", "editor", - "futures", + "futures 0.3.24", "gpui", "menu", "postage", @@ -4070,7 +4131,7 @@ version = "0.1.0" dependencies = [ "anyhow", "editor", - "futures", + "futures 0.3.24", "fuzzy", "gpui", "language", @@ -4107,7 +4168,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020" dependencies = [ - "bytes", + "bytes 1.2.1", "prost-derive 0.8.0", ] @@ -4117,7 +4178,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" dependencies = [ - "bytes", + "bytes 1.2.1", "prost-derive 0.9.0", ] @@ -4127,7 +4188,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" dependencies = [ - "bytes", + "bytes 1.2.1", "heck 0.3.3", "itertools", "lazy_static", @@ -4173,7 +4234,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" dependencies = [ - "bytes", + "bytes 1.2.1", "prost 0.9.0", ] @@ -4436,7 +4497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" dependencies = [ "base64", - "bytes", + "bytes 1.2.1", "encoding_rs", "futures-core", "futures-util", @@ -4506,6 +4567,27 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "rmp" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmpv" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de8813b3a2f95c5138fe5925bfb8784175d88d6bff059ba8ce090aa891319754" +dependencies = [ + "num-traits", + "rmp", +] + [[package]] name = "rocksdb" version = "0.18.0" @@ -4536,7 +4618,7 @@ dependencies = [ "collections", "ctor", "env_logger", - "futures", + "futures 0.3.24", "gpui", "parking_lot 0.11.2", "prost 0.8.0", @@ -5290,7 +5372,7 @@ dependencies = [ "base64", "bitflags", "byteorder", - "bytes", + "bytes 1.2.1", "crc", "crossbeam-queue", "dirs 4.0.0", @@ -5543,7 +5625,7 @@ dependencies = [ "context_menu", "dirs 4.0.0", "editor", - "futures", + "futures 0.3.24", "gpui", "itertools", "lazy_static", @@ -5754,16 +5836,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.19.2" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ - "bytes", + "autocfg 1.1.0", + "bytes 1.2.1", "libc", "memchr", "mio 0.8.4", "num_cpus", - "once_cell", "parking_lot 0.12.1", "pin-project-lite 0.2.9", "signal-hook-registry", @@ -5772,6 +5854,17 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "tokio-io" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", + "log", +] + [[package]] name = "tokio-io-timeout" version = "1.2.0" @@ -5843,7 +5936,7 @@ version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" dependencies = [ - "bytes", + "bytes 1.2.1", "futures-core", "futures-sink", "log", @@ -5853,12 +5946,13 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ - "bytes", + "bytes 1.2.1", "futures-core", + "futures-io", "futures-sink", "pin-project-lite 0.2.9", "tokio", @@ -5883,7 +5977,7 @@ dependencies = [ "async-stream", "async-trait", "base64", - "bytes", + "bytes 1.2.1", "futures-core", "futures-util", "h2", @@ -5919,7 +6013,7 @@ dependencies = [ "rand 0.8.5", "slab", "tokio", - "tokio-util 0.7.3", + "tokio-util 0.7.4", "tower-layer", "tower-service", "tracing", @@ -5932,7 +6026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" dependencies = [ "bitflags", - "bytes", + "bytes 1.2.1", "futures-core", "futures-util", "http", @@ -6211,7 +6305,7 @@ checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" dependencies = [ "base64", "byteorder", - "bytes", + "bytes 1.2.1", "http", "httparse", "log", @@ -6230,7 +6324,7 @@ checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5" dependencies = [ "base64", "byteorder", - "bytes", + "bytes 1.2.1", "http", "httparse", "log", @@ -6406,7 +6500,7 @@ name = "util" version = "0.1.0" dependencies = [ "anyhow", - "futures", + "futures 0.3.24", "git2", "lazy_static", "log", @@ -6476,6 +6570,8 @@ name = "vim" version = "0.1.0" dependencies = [ "assets", + "async-compat", + "async-trait", "collections", "command_palette", "editor", @@ -6483,11 +6579,16 @@ dependencies = [ "indoc", "itertools", "language", + "lazy_static", "log", + "nvim-rs", + "parking_lot 0.11.2", "project", "search", "serde", + "serde_json", "settings", + "tokio", "util", "workspace", ] @@ -7173,7 +7274,7 @@ dependencies = [ "collections", "context_menu", "drag_and_drop", - "futures", + "futures 0.3.24", "gpui", "language", "log", @@ -7257,7 +7358,7 @@ dependencies = [ "env_logger", "file_finder", "fsevent", - "futures", + "futures 0.3.24", "fuzzy", "go_to_line", "gpui", diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index cd6b2dca4b..bdb83ddc55 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -618,7 +618,6 @@ pub struct MutableAppContext { HashMap>, Box)>, foreground: Rc, pending_effects: VecDeque, - pending_focus_index: Option, pending_notifications: HashSet, pending_global_notifications: HashSet, pending_flushes: usize, @@ -673,7 +672,6 @@ impl MutableAppContext { presenters_and_platform_windows: Default::default(), foreground, pending_effects: VecDeque::new(), - pending_focus_index: None, pending_notifications: Default::default(), pending_global_notifications: Default::default(), pending_flushes: 0, @@ -1876,9 +1874,6 @@ impl MutableAppContext { let mut refreshing = false; loop { if let Some(effect) = self.pending_effects.pop_front() { - if let Some(pending_focus_index) = self.pending_focus_index.as_mut() { - *pending_focus_index = pending_focus_index.saturating_sub(1); - } match effect { Effect::Subscription { entity_id, @@ -2259,8 +2254,6 @@ impl MutableAppContext { } fn handle_focus_effect(&mut self, window_id: usize, focused_id: Option) { - self.pending_focus_index.take(); - if self .cx .windows @@ -2383,10 +2376,6 @@ impl MutableAppContext { } pub fn focus(&mut self, window_id: usize, view_id: Option) { - if let Some(pending_focus_index) = self.pending_focus_index { - self.pending_effects.remove(pending_focus_index); - } - self.pending_focus_index = Some(self.pending_effects.len()); self.pending_effects .push_back(Effect::Focus { window_id, view_id }); } @@ -3465,6 +3454,15 @@ impl<'a, T: View> ViewContext<'a, T> { self.app.focused_view_id(self.window_id) == Some(self.view_id) } + pub fn is_child(&self, view: impl Into) -> bool { + let view = view.into(); + if self.window_id != view.window_id { + return false; + } + self.parents(view.window_id, view.view_id) + .any(|parent| parent == self.view_id) + } + pub fn blur(&mut self) { self.app.focus(self.window_id, None); } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 4992d03737..d3c0743325 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -200,6 +200,10 @@ impl View for ProjectSearchView { .0 .insert(self.model.read(cx).project.downgrade(), handle) }); + + if cx.is_self_focused() { + self.focus_query_editor(cx); + } } } diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 7e626c60a9..dcfcc9e983 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -170,7 +170,11 @@ impl Dock { } else { cx.focus(pane); } - } else if let Some(last_active_center_pane) = workspace.last_active_center_pane.clone() { + } else if let Some(last_active_center_pane) = workspace + .last_active_center_pane + .as_ref() + .and_then(|pane| pane.upgrade(cx)) + { cx.focus(last_active_center_pane); } cx.emit(crate::Event::DockAnchorChanged); @@ -583,10 +587,11 @@ mod tests { } pub fn center_pane_handle(&self) -> ViewHandle { - self.workspace(|workspace, _| { + self.workspace(|workspace, cx| { workspace .last_active_center_pane .clone() + .and_then(|pane| pane.upgrade(cx)) .unwrap_or_else(|| workspace.center.panes()[0].clone()) }) } @@ -597,6 +602,7 @@ mod tests { let pane = workspace .last_active_center_pane .clone() + .and_then(|pane| pane.upgrade(cx)) .unwrap_or_else(|| workspace.center.panes()[0].clone()); Pane::add_item( workspace, diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 46ce9eb97f..7e2cc0d599 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -112,10 +112,10 @@ pub fn init(cx: &mut MutableAppContext) { pane.activate_item(pane.items.len() - 1, true, true, cx); }); cx.add_action(|pane: &mut Pane, _: &ActivatePrevItem, cx| { - pane.activate_prev_item(cx); + pane.activate_prev_item(true, cx); }); cx.add_action(|pane: &mut Pane, _: &ActivateNextItem, cx| { - pane.activate_next_item(cx); + pane.activate_next_item(true, cx); }); cx.add_async_action(Pane::close_active_item); cx.add_async_action(Pane::close_inactive_items); @@ -189,7 +189,6 @@ pub fn init(cx: &mut MutableAppContext) { #[derive(Debug)] pub enum Event { - Focused, ActivateItem { local: bool }, Remove, RemoveItem { item_id: usize }, @@ -201,7 +200,7 @@ pub struct Pane { items: Vec>, is_active: bool, active_item_index: usize, - last_focused_view: Option, + last_focused_view_by_item: HashMap, autoscroll: bool, nav_history: Rc>, toolbar: ViewHandle, @@ -263,7 +262,7 @@ impl Pane { items: Vec::new(), is_active: true, active_item_index: 0, - last_focused_view: None, + last_focused_view_by_item: Default::default(), autoscroll: false, nav_history: Rc::new(RefCell::new(NavHistory { mode: NavigationMode::Normal, @@ -632,32 +631,29 @@ impl Pane { if focus_item { self.focus_active_item(cx); } - if activate_pane { - cx.emit(Event::Focused); - } self.autoscroll = true; cx.notify(); } } - pub fn activate_prev_item(&mut self, cx: &mut ViewContext) { + pub fn activate_prev_item(&mut self, activate_pane: bool, cx: &mut ViewContext) { let mut index = self.active_item_index; if index > 0 { index -= 1; } else if !self.items.is_empty() { index = self.items.len() - 1; } - self.activate_item(index, true, true, cx); + self.activate_item(index, activate_pane, activate_pane, cx); } - pub fn activate_next_item(&mut self, cx: &mut ViewContext) { + pub fn activate_next_item(&mut self, activate_pane: bool, cx: &mut ViewContext) { let mut index = self.active_item_index; if index + 1 < self.items.len() { index += 1; } else { index = 0; } - self.activate_item(index, true, true, cx); + self.activate_item(index, activate_pane, activate_pane, cx); } pub fn close_active_item( @@ -784,7 +780,7 @@ impl Pane { // Remove the item from the pane. pane.update(&mut cx, |pane, cx| { if let Some(item_ix) = pane.items.iter().position(|i| i.id() == item.id()) { - pane.remove_item(item_ix, cx); + pane.remove_item(item_ix, false, cx); } }); } @@ -794,15 +790,15 @@ impl Pane { }) } - fn remove_item(&mut self, item_ix: usize, cx: &mut ViewContext) { + fn remove_item(&mut self, item_ix: usize, activate_pane: bool, cx: &mut ViewContext) { if item_ix == self.active_item_index { // Activate the previous item if possible. // This returns the user to the previously opened tab if they closed // a new item they just navigated to. if item_ix > 0 { - self.activate_prev_item(cx); + self.activate_prev_item(activate_pane, cx); } else if item_ix + 1 < self.items.len() { - self.activate_next_item(cx); + self.activate_next_item(activate_pane, cx); } } @@ -965,26 +961,27 @@ impl Pane { log::warn!("Tried to move item handle which was not in `from` pane. Maybe tab was closed during drop"); return; } - let (item_ix, item_handle) = item_to_move.unwrap(); + let item_handle = item_handle.clone(); + + if from != to { + // Close item from previous pane + from.update(cx, |from, cx| { + from.remove_item(item_ix, false, cx); + }); + } + // This automatically removes duplicate items in the pane Pane::add_item( workspace, &to, - item_handle.clone(), + item_handle, true, true, Some(destination_index), cx, ); - if from != to { - // Close item from previous pane - from.update(cx, |from, cx| { - from.remove_item(item_ix, cx); - }); - } - cx.focus(to); } @@ -1488,21 +1485,27 @@ impl View for Pane { } fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext) { - if cx.is_self_focused() { - if let Some(last_focused_view) = self - .last_focused_view - .as_ref() - .and_then(|handle| handle.upgrade(cx)) - .filter(|handle| handle.id() != self.tab_bar_context_menu.id()) - { - cx.focus(last_focused_view); + if let Some(active_item) = self.active_item() { + if cx.is_self_focused() { + // Pane was focused directly. We need to either focus a view inside the active item, + // or focus the active item itself + if let Some(weak_last_focused_view) = + self.last_focused_view_by_item.get(&active_item.id()) + { + if let Some(last_focused_view) = weak_last_focused_view.upgrade(cx) { + cx.focus(last_focused_view); + return; + } else { + self.last_focused_view_by_item.remove(&active_item.id()); + } + } + + cx.focus(active_item); } else { - self.focus_active_item(cx); + self.last_focused_view_by_item + .insert(active_item.id(), focused.downgrade()); } - } else { - self.last_focused_view = Some(focused.downgrade()); } - cx.emit(Event::Focused); } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 705823003f..b07eca465e 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1,5 +1,4 @@ -/// NOTE: Focus only 'takes' after an update has flushed_effects. Pane sends an event in on_focus_in -/// which the workspace uses to change the activated pane. +/// NOTE: Focus only 'takes' after an update has flushed_effects. /// /// This may cause issues when you're trying to write tests that use workspace focus to add items at /// specific locations. @@ -970,7 +969,7 @@ pub struct Workspace { panes: Vec>, panes_by_item: HashMap>, active_pane: ViewHandle, - last_active_center_pane: Option>, + last_active_center_pane: Option>, status_bar: ViewHandle, titlebar_item: Option, dock: Dock, @@ -1110,7 +1109,7 @@ impl Workspace { panes: vec![dock_pane, center_pane.clone()], panes_by_item: Default::default(), active_pane: center_pane.clone(), - last_active_center_pane: Some(center_pane.clone()), + last_active_center_pane: Some(center_pane.downgrade()), status_bar, titlebar_item: None, notifications: Default::default(), @@ -1845,7 +1844,7 @@ impl Workspace { if &pane == self.dock_pane() { Dock::show(self, cx); } else { - self.last_active_center_pane = Some(pane.clone()); + self.last_active_center_pane = Some(pane.downgrade()); if self.dock.is_anchored_at(DockAnchor::Expanded) { Dock::hide(self, cx); } @@ -1876,7 +1875,6 @@ impl Workspace { } pane::Event::Remove if !is_dock => self.remove_pane(pane, cx), pane::Event::Remove if is_dock => Dock::hide(self, cx), - pane::Event::Focused => self.handle_pane_focused(pane, cx), pane::Event::ActivateItem { local } => { if *local { self.unfollow(&pane, cx); @@ -1937,7 +1935,7 @@ impl Workspace { for removed_item in pane.read(cx).items() { self.panes_by_item.remove(&removed_item.id()); } - if self.last_active_center_pane == Some(pane) { + if self.last_active_center_pane == Some(pane.downgrade()) { self.last_active_center_pane = None; } @@ -2647,9 +2645,17 @@ impl View for Workspace { .named("workspace") } - fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { + fn on_focus_in(&mut self, view: AnyViewHandle, cx: &mut ViewContext) { if cx.is_self_focused() { cx.focus(&self.active_pane); + } else { + for pane in self.panes() { + let view = view.clone(); + if pane.update(cx, |_, cx| cx.is_child(view)) { + self.handle_pane_focused(pane.clone(), cx); + break; + } + } } }